Added show_fragment_tree() to reassemble. This function will do the common
[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.269 2002/06/05 11:21:47 sahlberg 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 specification from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/English/Collaterals/Work_Group_Docs/NAS/CIFS/CIFS_Technical_Reference.pdf
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_files_moved = -1;
191 static int hf_smb_copy_flags_file = -1;
192 static int hf_smb_copy_flags_dir = -1;
193 static int hf_smb_copy_flags_dest_mode = -1;
194 static int hf_smb_copy_flags_source_mode = -1;
195 static int hf_smb_copy_flags_verify = -1;
196 static int hf_smb_copy_flags_tree_copy = -1;
197 static int hf_smb_copy_flags_ea_action = -1;
198 static int hf_smb_count = -1;
199 static int hf_smb_file_name = -1;
200 static int hf_smb_open_function_open = -1;
201 static int hf_smb_open_function_create = -1;
202 static int hf_smb_fid = -1;
203 static int hf_smb_file_attr_read_only_16bit = -1;
204 static int hf_smb_file_attr_read_only_8bit = -1;
205 static int hf_smb_file_attr_hidden_16bit = -1;
206 static int hf_smb_file_attr_hidden_8bit = -1;
207 static int hf_smb_file_attr_system_16bit = -1;
208 static int hf_smb_file_attr_system_8bit = -1;
209 static int hf_smb_file_attr_volume_16bit = -1;
210 static int hf_smb_file_attr_volume_8bit = -1;
211 static int hf_smb_file_attr_directory_16bit = -1;
212 static int hf_smb_file_attr_directory_8bit = -1;
213 static int hf_smb_file_attr_archive_16bit = -1;
214 static int hf_smb_file_attr_archive_8bit = -1;
215 static int hf_smb_file_attr_device = -1;
216 static int hf_smb_file_attr_normal = -1;
217 static int hf_smb_file_attr_temporary = -1;
218 static int hf_smb_file_attr_sparse = -1;
219 static int hf_smb_file_attr_reparse = -1;
220 static int hf_smb_file_attr_compressed = -1;
221 static int hf_smb_file_attr_offline = -1;
222 static int hf_smb_file_attr_not_content_indexed = -1;
223 static int hf_smb_file_attr_encrypted = -1;
224 static int hf_smb_file_size = -1;
225 static int hf_smb_search_attribute_read_only = -1;
226 static int hf_smb_search_attribute_hidden = -1;
227 static int hf_smb_search_attribute_system = -1;
228 static int hf_smb_search_attribute_volume = -1;
229 static int hf_smb_search_attribute_directory = -1;
230 static int hf_smb_search_attribute_archive = -1;
231 static int hf_smb_access_mode = -1;
232 static int hf_smb_access_sharing = -1;
233 static int hf_smb_access_locality = -1;
234 static int hf_smb_access_caching = -1;
235 static int hf_smb_access_writetru = -1;
236 static int hf_smb_create_time = -1;
237 static int hf_smb_create_dos_date = -1;
238 static int hf_smb_create_dos_time = -1;
239 static int hf_smb_last_write_time = -1;
240 static int hf_smb_last_write_dos_date = -1;
241 static int hf_smb_last_write_dos_time = -1;
242 static int hf_smb_access_time = -1;
243 static int hf_smb_access_dos_date = -1;
244 static int hf_smb_access_dos_time = -1;
245 static int hf_smb_old_file_name = -1;
246 static int hf_smb_offset = -1;
247 static int hf_smb_remaining = -1;
248 static int hf_smb_padding = -1;
249 static int hf_smb_file_data = -1;
250 static int hf_smb_total_data_len = -1;
251 static int hf_smb_data_len = -1;
252 static int hf_smb_seek_mode = -1;
253 static int hf_smb_data_size = -1;
254 static int hf_smb_alloc_size = -1;
255 static int hf_smb_alloc_size64 = -1;
256 static int hf_smb_max_count = -1;
257 static int hf_smb_min_count = -1;
258 static int hf_smb_timeout = -1;
259 static int hf_smb_high_offset = -1;
260 static int hf_smb_units = -1;
261 static int hf_smb_bpu = -1;
262 static int hf_smb_blocksize = -1;
263 static int hf_smb_freeunits = -1;
264 static int hf_smb_data_offset = -1;
265 static int hf_smb_dcm = -1;
266 static int hf_smb_request_mask = -1;
267 static int hf_smb_response_mask = -1;
268 static int hf_smb_sid = -1;
269 static int hf_smb_write_mode_write_through = -1;
270 static int hf_smb_write_mode_return_remaining = -1;
271 static int hf_smb_write_mode_raw = -1;
272 static int hf_smb_write_mode_message_start = -1;
273 static int hf_smb_write_mode_connectionless = -1;
274 static int hf_smb_resume_key_len = -1;
275 static int hf_smb_resume_find_id = -1;
276 static int hf_smb_resume_server_cookie = -1;
277 static int hf_smb_resume_client_cookie = -1;
278 static int hf_smb_andxoffset = -1;
279 static int hf_smb_lock_type_large = -1;
280 static int hf_smb_lock_type_cancel = -1;
281 static int hf_smb_lock_type_change = -1;
282 static int hf_smb_lock_type_oplock = -1;
283 static int hf_smb_lock_type_shared = -1;
284 static int hf_smb_locking_ol = -1;
285 static int hf_smb_number_of_locks = -1;
286 static int hf_smb_number_of_unlocks = -1;
287 static int hf_smb_lock_long_offset = -1;
288 static int hf_smb_lock_long_length = -1;
289 static int hf_smb_file_type = -1;
290 static int hf_smb_ipc_state_nonblocking = -1;
291 static int hf_smb_ipc_state_endpoint = -1;
292 static int hf_smb_ipc_state_pipe_type = -1;
293 static int hf_smb_ipc_state_read_mode = -1;
294 static int hf_smb_ipc_state_icount = -1;
295 static int hf_smb_server_fid = -1;
296 static int hf_smb_open_flags_add_info = -1;
297 static int hf_smb_open_flags_ex_oplock = -1;
298 static int hf_smb_open_flags_batch_oplock = -1;
299 static int hf_smb_open_flags_ealen = -1;
300 static int hf_smb_open_action_open = -1;
301 static int hf_smb_open_action_lock = -1;
302 static int hf_smb_vc_num = -1;
303 static int hf_smb_account = -1;
304 static int hf_smb_os = -1;
305 static int hf_smb_lanman = -1;
306 static int hf_smb_setup_action_guest = -1;
307 static int hf_smb_fs = -1;
308 static int hf_smb_connect_flags_dtid = -1;
309 static int hf_smb_connect_support_search = -1;
310 static int hf_smb_connect_support_in_dfs = -1;
311 static int hf_smb_max_setup_count = -1;
312 static int hf_smb_total_param_count = -1;
313 static int hf_smb_total_data_count = -1;
314 static int hf_smb_max_param_count = -1;
315 static int hf_smb_max_data_count = -1;
316 static int hf_smb_param_disp16 = -1;
317 static int hf_smb_param_count16 = -1;
318 static int hf_smb_param_offset16 = -1;
319 static int hf_smb_param_disp32 = -1;
320 static int hf_smb_param_count32 = -1;
321 static int hf_smb_param_offset32 = -1;
322 static int hf_smb_data_disp16 = -1;
323 static int hf_smb_data_count16 = -1;
324 static int hf_smb_data_offset16 = -1;
325 static int hf_smb_data_disp32 = -1;
326 static int hf_smb_data_count32 = -1;
327 static int hf_smb_data_offset32 = -1;
328 static int hf_smb_setup_count = -1;
329 static int hf_smb_nt_trans_subcmd = -1;
330 static int hf_smb_nt_ioctl_function_code = -1;
331 static int hf_smb_nt_ioctl_isfsctl = -1;
332 static int hf_smb_nt_ioctl_flags_root_handle = -1;
333 static int hf_smb_nt_ioctl_data = -1;
334 #ifdef SMB_UNUSED_HANDLES
335 static int hf_smb_nt_security_information = -1;
336 #endif
337 static int hf_smb_nt_notify_action = -1;
338 static int hf_smb_nt_notify_watch_tree = -1;
339 static int hf_smb_nt_notify_stream_write = -1;
340 static int hf_smb_nt_notify_stream_size = -1;
341 static int hf_smb_nt_notify_stream_name = -1;
342 static int hf_smb_nt_notify_security = -1;
343 static int hf_smb_nt_notify_ea = -1;
344 static int hf_smb_nt_notify_creation = -1;
345 static int hf_smb_nt_notify_last_access = -1;
346 static int hf_smb_nt_notify_last_write = -1;
347 static int hf_smb_nt_notify_size = -1;
348 static int hf_smb_nt_notify_attributes = -1;
349 static int hf_smb_nt_notify_dir_name = -1;
350 static int hf_smb_nt_notify_file_name = -1;
351 static int hf_smb_root_dir_fid = -1;
352 static int hf_smb_nt_create_disposition = -1;
353 static int hf_smb_sd_length = -1;
354 static int hf_smb_ea_length = -1;
355 static int hf_smb_file_name_len = -1;
356 static int hf_smb_nt_impersonation_level = -1;
357 static int hf_smb_nt_security_flags_context_tracking = -1;
358 static int hf_smb_nt_security_flags_effective_only = -1;
359 static int hf_smb_nt_access_mask_generic_read = -1;
360 static int hf_smb_nt_access_mask_generic_write = -1;
361 static int hf_smb_nt_access_mask_generic_execute = -1;
362 static int hf_smb_nt_access_mask_generic_all = -1;
363 static int hf_smb_nt_access_mask_maximum_allowed = -1;
364 static int hf_smb_nt_access_mask_system_security = -1;
365 static int hf_smb_nt_access_mask_synchronize = -1;
366 static int hf_smb_nt_access_mask_write_owner = -1;
367 static int hf_smb_nt_access_mask_write_dac = -1;
368 static int hf_smb_nt_access_mask_read_control = -1;
369 static int hf_smb_nt_access_mask_delete = -1;
370 static int hf_smb_nt_access_mask_write_attributes = -1;
371 static int hf_smb_nt_access_mask_read_attributes = -1;
372 static int hf_smb_nt_access_mask_delete_child = -1;
373 static int hf_smb_nt_access_mask_execute = -1;
374 static int hf_smb_nt_access_mask_write_ea = -1;
375 static int hf_smb_nt_access_mask_read_ea = -1;
376 static int hf_smb_nt_access_mask_append = -1;
377 static int hf_smb_nt_access_mask_write = -1;
378 static int hf_smb_nt_access_mask_read = -1;
379 static int hf_smb_nt_create_bits_oplock = -1;
380 static int hf_smb_nt_create_bits_boplock = -1;
381 static int hf_smb_nt_create_bits_dir = -1;
382 static int hf_smb_nt_create_options_directory_file = -1;
383 static int hf_smb_nt_create_options_write_through = -1;
384 static int hf_smb_nt_create_options_sequential_only = -1;
385 static int hf_smb_nt_create_options_sync_io_alert = -1;
386 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
387 static int hf_smb_nt_create_options_non_directory_file = -1;
388 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
389 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
390 static int hf_smb_nt_create_options_random_access = -1;
391 static int hf_smb_nt_create_options_delete_on_close = -1;
392 static int hf_smb_nt_share_access_read = -1;
393 static int hf_smb_nt_share_access_write = -1;
394 static int hf_smb_nt_share_access_delete = -1;
395 static int hf_smb_file_eattr_read_only = -1;
396 static int hf_smb_file_eattr_hidden = -1;
397 static int hf_smb_file_eattr_system = -1;
398 static int hf_smb_file_eattr_volume = -1;
399 static int hf_smb_file_eattr_directory = -1;
400 static int hf_smb_file_eattr_archive = -1;
401 static int hf_smb_file_eattr_device = -1;
402 static int hf_smb_file_eattr_normal = -1;
403 static int hf_smb_file_eattr_temporary = -1;
404 static int hf_smb_file_eattr_sparse = -1;
405 static int hf_smb_file_eattr_reparse = -1;
406 static int hf_smb_file_eattr_compressed = -1;
407 static int hf_smb_file_eattr_offline = -1;
408 static int hf_smb_file_eattr_not_content_indexed = -1;
409 static int hf_smb_file_eattr_encrypted = -1;
410 static int hf_smb_file_eattr_write_through = -1;
411 static int hf_smb_file_eattr_no_buffering = -1;
412 static int hf_smb_file_eattr_random_access = -1;
413 static int hf_smb_file_eattr_sequential_scan = -1;
414 static int hf_smb_file_eattr_delete_on_close = -1;
415 static int hf_smb_file_eattr_backup_semantics = -1;
416 static int hf_smb_file_eattr_posix_semantics = -1;
417 static int hf_smb_sec_desc_len = -1;
418 static int hf_smb_sec_desc_revision = -1;
419 static int hf_smb_sec_desc_type_owner_defaulted = -1;
420 static int hf_smb_sec_desc_type_group_defaulted = -1;
421 static int hf_smb_sec_desc_type_dacl_present = -1;
422 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
423 static int hf_smb_sec_desc_type_sacl_present = -1;
424 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
425 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
426 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
427 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
428 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
429 static int hf_smb_sec_desc_type_dacl_protected = -1;
430 static int hf_smb_sec_desc_type_sacl_protected = -1;
431 static int hf_smb_sec_desc_type_self_relative = -1;
432 static int hf_smb_sid_revision = -1;
433 static int hf_smb_sid_num_auth = -1;
434 static int hf_smb_acl_revision = -1;
435 static int hf_smb_acl_size = -1;
436 static int hf_smb_acl_num_aces = -1;
437 static int hf_smb_ace_type = -1;
438 static int hf_smb_ace_size = -1;
439 static int hf_smb_ace_flags_object_inherit = -1;
440 static int hf_smb_ace_flags_container_inherit = -1;
441 static int hf_smb_ace_flags_non_propagate_inherit = -1;
442 static int hf_smb_ace_flags_inherit_only = -1;
443 static int hf_smb_ace_flags_inherited_ace = -1;
444 static int hf_smb_ace_flags_successful_access = -1;
445 static int hf_smb_ace_flags_failed_access = -1;
446 static int hf_smb_nt_qsd_owner = -1;
447 static int hf_smb_nt_qsd_group = -1;
448 static int hf_smb_nt_qsd_dacl = -1;
449 static int hf_smb_nt_qsd_sacl = -1;
450 static int hf_smb_extended_attributes = -1;
451 static int hf_smb_oplock_level = -1;
452 static int hf_smb_create_action = -1;
453 static int hf_smb_file_id = -1;
454 static int hf_smb_ea_error_offset = -1;
455 static int hf_smb_end_of_file = -1;
456 static int hf_smb_device_type = -1;
457 static int hf_smb_is_directory = -1;
458 static int hf_smb_next_entry_offset = -1;
459 static int hf_smb_change_time = -1;
460 static int hf_smb_setup_len = -1;
461 static int hf_smb_print_mode = -1;
462 static int hf_smb_print_identifier = -1;
463 static int hf_smb_restart_index = -1;
464 static int hf_smb_print_queue_date = -1;
465 static int hf_smb_print_queue_dos_date = -1;
466 static int hf_smb_print_queue_dos_time = -1;
467 static int hf_smb_print_status = -1;
468 static int hf_smb_print_spool_file_number = -1;
469 static int hf_smb_print_spool_file_size = -1;
470 static int hf_smb_print_spool_file_name = -1;
471 static int hf_smb_start_index = -1;
472 static int hf_smb_originator_name = -1;
473 static int hf_smb_destination_name = -1;
474 static int hf_smb_message_len = -1;
475 static int hf_smb_message = -1;
476 static int hf_smb_mgid = -1;
477 static int hf_smb_forwarded_name = -1;
478 static int hf_smb_machine_name = -1;
479 static int hf_smb_cancel_to = -1;
480 static int hf_smb_trans2_subcmd = -1;
481 static int hf_smb_trans_name = -1;
482 static int hf_smb_transaction_flags_dtid = -1;
483 static int hf_smb_transaction_flags_owt = -1;
484 static int hf_smb_search_count = -1;
485 static int hf_smb_search_pattern = -1;
486 static int hf_smb_ff2_backup = -1;
487 static int hf_smb_ff2_continue = -1;
488 static int hf_smb_ff2_resume = -1;
489 static int hf_smb_ff2_close_eos = -1;
490 static int hf_smb_ff2_close = -1;
491 static int hf_smb_ff2_information_level = -1;
492 static int hf_smb_qpi_loi = -1;
493 #if 0
494 static int hf_smb_sfi_writetru = -1;
495 static int hf_smb_sfi_caching = -1;
496 #endif
497 static int hf_smb_storage_type = -1;
498 static int hf_smb_resume = -1;
499 static int hf_smb_max_referral_level = -1;
500 static int hf_smb_qfsi_information_level = -1;
501 static int hf_smb_ea_size = -1;
502 static int hf_smb_list_length = -1;
503 static int hf_smb_number_of_links = -1;
504 static int hf_smb_delete_pending = -1;
505 static int hf_smb_index_number = -1;
506 static int hf_smb_current_offset = -1;
507 static int hf_smb_t2_alignment = -1;
508 static int hf_smb_t2_stream_name_length = -1;
509 static int hf_smb_t2_stream_size = -1;
510 static int hf_smb_t2_stream_name = -1;
511 static int hf_smb_t2_compressed_file_size = -1;
512 static int hf_smb_t2_compressed_format = -1;
513 static int hf_smb_t2_compressed_unit_shift = -1;
514 static int hf_smb_t2_compressed_chunk_shift = -1;
515 static int hf_smb_t2_compressed_cluster_shift = -1;
516 static int hf_smb_dfs_path_consumed = -1;
517 static int hf_smb_dfs_num_referrals = -1;
518 static int hf_smb_get_dfs_server_hold_storage = -1;
519 static int hf_smb_get_dfs_fielding = -1;
520 static int hf_smb_dfs_referral_version = -1;
521 static int hf_smb_dfs_referral_size = -1;
522 static int hf_smb_dfs_referral_server_type = -1;
523 static int hf_smb_dfs_referral_flags_strip = -1;
524 static int hf_smb_dfs_referral_node_offset = -1;
525 static int hf_smb_dfs_referral_node = -1;
526 static int hf_smb_dfs_referral_proximity = -1;
527 static int hf_smb_dfs_referral_ttl = -1;
528 static int hf_smb_dfs_referral_path_offset = -1;
529 static int hf_smb_dfs_referral_path = -1;
530 static int hf_smb_dfs_referral_alt_path_offset = -1;
531 static int hf_smb_dfs_referral_alt_path = -1;
532 static int hf_smb_end_of_search = -1;
533 static int hf_smb_last_name_offset = -1;
534 static int hf_smb_fn_information_level = -1;
535 static int hf_smb_monitor_handle = -1;
536 static int hf_smb_change_count = -1;
537 static int hf_smb_file_index = -1;
538 static int hf_smb_short_file_name = -1;
539 static int hf_smb_short_file_name_len = -1;
540 static int hf_smb_fs_id = -1;
541 static int hf_smb_sector_unit = -1;
542 static int hf_smb_fs_units = -1;
543 static int hf_smb_fs_sector = -1;
544 static int hf_smb_avail_units = -1;
545 static int hf_smb_volume_serial_num = -1;
546 static int hf_smb_volume_label_len = -1;
547 static int hf_smb_volume_label = -1;
548 static int hf_smb_free_alloc_units64 = -1;
549 static int hf_smb_caller_free_alloc_units64 = -1;
550 static int hf_smb_actual_free_alloc_units64 = -1;
551 static int hf_smb_max_name_len = -1;
552 static int hf_smb_fs_name_len = -1;
553 static int hf_smb_fs_name = -1;
554 static int hf_smb_device_char_removable = -1;
555 static int hf_smb_device_char_read_only = -1;
556 static int hf_smb_device_char_floppy = -1;
557 static int hf_smb_device_char_write_once = -1;
558 static int hf_smb_device_char_remote = -1;
559 static int hf_smb_device_char_mounted = -1;
560 static int hf_smb_device_char_virtual = -1;
561 static int hf_smb_fs_attr_css = -1;
562 static int hf_smb_fs_attr_cpn = -1;
563 static int hf_smb_fs_attr_pacls = -1;
564 static int hf_smb_fs_attr_fc = -1;
565 static int hf_smb_fs_attr_vq = -1;
566 static int hf_smb_fs_attr_dim = -1;
567 static int hf_smb_fs_attr_vic = -1;
568 static int hf_smb_quota_flags_enabled = -1;
569 static int hf_smb_quota_flags_deny_disk = -1;
570 static int hf_smb_quota_flags_log_limit = -1;
571 static int hf_smb_quota_flags_log_warning = -1;
572 static int hf_smb_soft_quota_limit = -1;
573 static int hf_smb_hard_quota_limit = -1;
574 static int hf_smb_user_quota_used = -1;
575 static int hf_smb_user_quota_offset = -1;
576 static int hf_smb_nt_rename_level = -1;
577 static int hf_smb_cluster_count = -1;
578 static int hf_smb_segments = -1;
579 static int hf_smb_segment = -1;
580 static int hf_smb_segment_overlap = -1;
581 static int hf_smb_segment_overlap_conflict = -1;
582 static int hf_smb_segment_multiple_tails = -1;
583 static int hf_smb_segment_too_long_fragment = -1;
584 static int hf_smb_segment_error = -1;
585
586 static gint ett_smb = -1;
587 static gint ett_smb_hdr = -1;
588 static gint ett_smb_command = -1;
589 static gint ett_smb_fileattributes = -1;
590 static gint ett_smb_capabilities = -1;
591 static gint ett_smb_aflags = -1;
592 static gint ett_smb_dialect = -1;
593 static gint ett_smb_dialects = -1;
594 static gint ett_smb_mode = -1;
595 static gint ett_smb_rawmode = -1;
596 static gint ett_smb_flags = -1;
597 static gint ett_smb_flags2 = -1;
598 static gint ett_smb_desiredaccess = -1;
599 static gint ett_smb_search = -1;
600 static gint ett_smb_file = -1;
601 static gint ett_smb_openfunction = -1;
602 static gint ett_smb_filetype = -1;
603 static gint ett_smb_openaction = -1;
604 static gint ett_smb_writemode = -1;
605 static gint ett_smb_lock_type = -1;
606 static gint ett_smb_ssetupandxaction = -1;
607 static gint ett_smb_optionsup = -1;
608 static gint ett_smb_time_date = -1;
609 static gint ett_smb_move_copy_flags = -1;
610 static gint ett_smb_file_attributes = -1;
611 static gint ett_smb_search_resume_key = -1;
612 static gint ett_smb_search_dir_info = -1;
613 static gint ett_smb_unlocks = -1;
614 static gint ett_smb_unlock = -1;
615 static gint ett_smb_locks = -1;
616 static gint ett_smb_lock = -1;
617 static gint ett_smb_open_flags = -1;
618 static gint ett_smb_ipc_state = -1;
619 static gint ett_smb_open_action = -1;
620 static gint ett_smb_setup_action = -1;
621 static gint ett_smb_connect_flags = -1;
622 static gint ett_smb_connect_support_bits = -1;
623 static gint ett_smb_nt_access_mask = -1;
624 static gint ett_smb_nt_create_bits = -1;
625 static gint ett_smb_nt_create_options = -1;
626 static gint ett_smb_nt_share_access = -1;
627 static gint ett_smb_nt_security_flags = -1;
628 static gint ett_smb_nt_trans_setup = -1;
629 static gint ett_smb_nt_trans_data = -1;
630 static gint ett_smb_nt_trans_param = -1;
631 static gint ett_smb_nt_notify_completion_filter = -1;
632 static gint ett_smb_nt_ioctl_flags = -1;
633 static gint ett_smb_security_information_mask = -1;
634 static gint ett_smb_print_queue_entry = -1;
635 static gint ett_smb_transaction_flags = -1;
636 static gint ett_smb_transaction_params = -1;
637 static gint ett_smb_find_first2_flags = -1;
638 #if 0
639 static gint ett_smb_ioflag = -1;
640 #endif
641 static gint ett_smb_transaction_data = -1;
642 static gint ett_smb_stream_info = -1;
643 static gint ett_smb_dfs_referrals = -1;
644 static gint ett_smb_dfs_referral = -1;
645 static gint ett_smb_dfs_referral_flags = -1;
646 static gint ett_smb_get_dfs_flags = -1;
647 static gint ett_smb_ff2_data = -1;
648 static gint ett_smb_device_characteristics = -1;
649 static gint ett_smb_fs_attributes = -1;
650 static gint ett_smb_segments = -1;
651 static gint ett_smb_segment = -1;
652 static gint ett_smb_sec_desc = -1;
653 static gint ett_smb_sid = -1;
654 static gint ett_smb_acl = -1;
655 static gint ett_smb_ace = -1;
656 static gint ett_smb_ace_flags = -1;
657 static gint ett_smb_sec_desc_type = -1;
658 static gint ett_smb_quotaflags = -1;
659
660
661 fragment_items smb_frag_items = {
662         &ett_smb_segment,
663         &ett_smb_segments,
664
665         &hf_smb_segments,
666         &hf_smb_segment,
667         &hf_smb_segment_overlap,
668         &hf_smb_segment_overlap_conflict,
669         &hf_smb_segment_multiple_tails,
670         &hf_smb_segment_too_long_fragment,
671         &hf_smb_segment_error,
672 };
673
674 proto_tree *top_tree=NULL;     /* ugly */
675
676 static char *decode_smb_name(unsigned char);
677 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd);
678 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
679     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
680     gboolean exactlen, guint16 *bcp);
681
682 /*
683  * Macros for use in the main dissector routines for an SMB.
684  */
685
686 #define WORD_COUNT      \
687         /* Word Count */                                \
688         wc = tvb_get_guint8(tvb, offset);               \
689         proto_tree_add_uint(tree, hf_smb_word_count,    \
690                 tvb, offset, 1, wc);                    \
691         offset += 1;                                    \
692         if(wc==0) goto bytecount;
693
694 #define BYTE_COUNT      \
695         bytecount:                                      \
696         bc = tvb_get_letohs(tvb, offset);               \
697         proto_tree_add_uint(tree, hf_smb_byte_count,    \
698                         tvb, offset, 2, bc);            \
699         offset += 2;                                    \
700         if(bc==0) goto endofcommand;
701
702 #define CHECK_BYTE_COUNT(len)   \
703         if (bc < len) goto endofcommand;
704
705 #define COUNT_BYTES(len)   {\
706         int tmp;            \
707         tmp=len;            \
708         offset += tmp;      \
709         bc -= tmp;          \
710         }
711
712 #define END_OF_SMB      \
713         if (bc != 0) { \
714                 proto_tree_add_text(tree, tvb, offset, bc, \
715                     "Extra byte parameters");           \
716                 offset += bc;                           \
717         }                                               \
718         endofcommand:
719
720 /*
721  * Macros for use in routines called by them.
722  */
723 #define CHECK_BYTE_COUNT_SUBR(len)      \
724         if (*bcp < len) {               \
725                 *trunc = TRUE;          \
726                 return offset;          \
727         }
728
729 #define CHECK_STRING_SUBR(fn)   \
730         if (fn == NULL) {       \
731                 *trunc = TRUE;  \
732                 return offset;  \
733         }
734
735 #define COUNT_BYTES_SUBR(len)   \
736         offset += len;          \
737         *bcp -= len;
738
739 /*
740  * Macros for use when dissecting transaction parameters and data
741  */
742 #define CHECK_BYTE_COUNT_TRANS(len)     \
743         if (bc < len) return offset;
744
745 #define CHECK_STRING_TRANS(fn)  \
746         if (fn == NULL) return offset;
747
748 #define COUNT_BYTES_TRANS(len)  \
749         offset += len;          \
750         bc -= len;
751
752 /*
753  * Macros for use in subrroutines dissecting transaction parameters or data
754  */
755 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
756         if (*bcp < len) return offset;
757
758 #define CHECK_STRING_TRANS_SUBR(fn)     \
759         if (fn == NULL) return offset;
760
761 #define COUNT_BYTES_TRANS_SUBR(len)     \
762         offset += len;                  \
763         *bcp -= len;
764
765
766 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
767    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
768    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
769 static gboolean smb_trans_reassembly = FALSE;
770 gboolean smb_dcerpc_reassembly = FALSE;
771
772 static GHashTable *smb_trans_fragment_table = NULL;
773 GHashTable *dcerpc_fragment_table = NULL;
774
775 static void
776 smb_trans_reassembly_init(void)
777 {
778         fragment_table_init(&smb_trans_fragment_table);
779 }
780 static void
781 smb_dcerpc_reassembly_init(void)
782 {
783         fragment_table_init(&dcerpc_fragment_table);
784 }
785
786
787 static fragment_data *
788 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
789                      int offset, int count, int pos, int totlen)
790 {
791         fragment_data *fd_head=NULL;
792         smb_info_t *si;
793         int more_frags;
794
795         more_frags=totlen>(pos+count);
796
797         si = (smb_info_t *)pinfo->private_data;
798         if (si->sip == NULL) {
799                 /*
800                  * We don't have the frame number of the request.
801                  *
802                  * XXX - is there truly nothing we can do here?
803                  * Can we not separately keep track of the original
804                  * transaction and its continuations, as we did
805                  * at one time?
806                  *
807                  * It is probably not much point in even trying to do something here
808                  * if we have never seen the initial request. Without the initial 
809                  * request we probably miss all parameters and the begining of data
810                  * so we cant even call a subdissector since we can not determine
811                  * which type of transaction call this is.
812                  */
813                 return NULL;
814         }
815
816         if(!pinfo->fd->flags.visited){
817                 fd_head = fragment_add(tvb, offset, pinfo,
818                                        si->sip->frame_req, smb_trans_fragment_table,
819                                        pos, count, more_frags);
820         } else {
821                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
822         }
823
824         /* we only show the defragmented packet for the first fragment,
825            or else we might end up with dissecting one HUGE transaction PDU
826            a LOT of times. (first fragment is the only one containing the setup
827            bytes)
828            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
829            SMBs. Takes a LOT of time dissecting and is not fun.
830         */
831         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
832                 return fd_head;
833         } else {
834                 return NULL;
835         }
836 }
837                 
838
839
840
841
842 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
843    These variables and functions are used to match
844    responses with calls
845    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
846 /*
847  * The information we need to save about a request in order to show the
848  * frame number of the request in the dissection of the reply.
849  */
850 typedef struct  {
851         guint32 frame;
852         guint32 pid_mid;
853 } smb_saved_info_key_t;
854
855 static GMemChunk *smb_saved_info_key_chunk = NULL;
856 static GMemChunk *smb_saved_info_chunk = NULL;
857 static int smb_saved_info_init_count = 200;
858
859 /* unmatched smb_saved_info structures.
860    For unmatched smb_saved_info structures we store the smb_saved_info
861    structure using the MID and the PID as the key.
862
863    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
864    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
865    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
866 */
867 static gint
868 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
869 {
870         register guint32 key1 = (guint32)k1;
871         register guint32 key2 = (guint32)k2;
872         return key1==key2;
873 }
874 static guint
875 smb_saved_info_hash_unmatched(gconstpointer k)
876 {
877         register guint32 key = (guint32)k;
878         return key;
879 }
880
881 /* matched smb_saved_info structures.
882    For matched smb_saved_info structures we store the smb_saved_info
883    structure twice in the table using the frame number, and a combination
884    of the MID and the PID, as the key.
885    The frame number is guaranteed to be unique but if ever someone makes
886    some change that will renumber the frames in a capture we are in BIG trouble.
887    This is not likely though since that would break (among other things) all the
888    reassembly routines as well.
889
890    We also need the MID as there may be more than one SMB request or reply
891    in a single frame, and we also need the PID as there may be more than
892    one outstanding request with the same MID and different PIDs.
893 */
894 static gint
895 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
896 {
897         const smb_saved_info_key_t *key1 = k1;
898         const smb_saved_info_key_t *key2 = k2;
899         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
900 }
901 static guint
902 smb_saved_info_hash_matched(gconstpointer k)
903 {
904         const smb_saved_info_key_t *key = k;
905         return key->frame + key->pid_mid;
906 }
907
908 /*
909  * The information we need to save about an NT Transaction request in order
910  * to dissect the reply.
911  */
912 typedef struct {
913         int subcmd;
914 } smb_nt_transact_info_t;
915
916 static GMemChunk *smb_nt_transact_info_chunk = NULL;
917 static int smb_nt_transact_info_init_count = 200;
918
919 /*
920  * The information we need to save about a Transaction2 request in order
921  * to dissect the reply.
922  */
923 typedef struct {
924         int subcmd;
925         int info_level;
926         gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
927 } smb_transact2_info_t;
928
929 static GMemChunk *smb_transact2_info_chunk = NULL;
930 static int smb_transact2_info_init_count = 200;
931
932 /*
933  * The information we need to save about a Transaction request in order
934  * to dissect the reply; this includes information for use by the
935  * Remote API dissector.
936  */
937 static GMemChunk *smb_transact_info_chunk = NULL;
938 static int smb_transact_info_init_count = 200;
939
940 static GMemChunk *conv_tables_chunk = NULL;
941 static GSList *conv_tables = NULL;
942 static int conv_tables_count = 10;
943
944
945 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
946    End of request/response matching functions
947    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
948
949 static const value_string buffer_format_vals[] = {
950         {1,     "Data Block"},
951         {2,     "Dialect"},
952         {3,     "Pathname"},
953         {4,     "ASCII"},
954         {5,     "Variable Block"},
955         {0,     NULL}
956 };
957
958 /*
959  * UTIME - this is *almost* like a UNIX time stamp, except that it's
960  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
961  * January 1, 1970, 00:00:00 GMT.
962  *
963  * This means we have to do some extra work to convert it.  This code is
964  * based on the Samba code:
965  *
966  *      Unix SMB/Netbios implementation.
967  *      Version 1.9.
968  *      time handling functions
969  *      Copyright (C) Andrew Tridgell 1992-1998
970  */
971
972 /*
973  * Yield the difference between *A and *B, in seconds, ignoring leap
974  * seconds.
975  */
976 #define TM_YEAR_BASE 1900
977
978 static int
979 tm_diff(struct tm *a, struct tm *b)
980 {
981         int ay = a->tm_year + (TM_YEAR_BASE - 1);
982         int by = b->tm_year + (TM_YEAR_BASE - 1);
983         int intervening_leap_days =
984             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
985         int years = ay - by;
986         int days =
987             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
988         int hours = 24*days + (a->tm_hour - b->tm_hour);
989         int minutes = 60*hours + (a->tm_min - b->tm_min);
990         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
991
992         return seconds;
993 }
994
995 /*
996  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
997  * determined.
998  */
999 static int
1000 TimeZone(time_t t)
1001 {
1002         struct tm *tm = gmtime(&t);
1003         struct tm tm_utc;
1004
1005         if (tm == NULL)
1006                 return 0;
1007         tm_utc = *tm;
1008         tm = localtime(&t);
1009         if (tm == NULL)
1010                 return 0;
1011         return tm_diff(&tm_utc,tm);
1012 }
1013
1014 /*
1015  * Return the same value as TimeZone, but it should be more efficient.
1016  *
1017  * We keep a table of DST offsets to prevent calling localtime() on each 
1018  * call of this function. This saves a LOT of time on many unixes.
1019  *
1020  * Updated by Paul Eggert <eggert@twinsun.com>
1021  */
1022 #ifndef CHAR_BIT
1023 #define CHAR_BIT 8
1024 #endif
1025
1026 #ifndef TIME_T_MIN
1027 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1028                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1029 #endif
1030 #ifndef TIME_T_MAX
1031 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1032 #endif
1033
1034 static int
1035 TimeZoneFaster(time_t t)
1036 {
1037         static struct dst_table {time_t start,end; int zone;} *tdt;
1038         static struct dst_table *dst_table = NULL;
1039         static int table_size = 0;
1040         int i;
1041         int zone = 0;
1042
1043         if (t == 0)
1044                 t = time(NULL);
1045
1046         /* Tunis has a 8 day DST region, we need to be careful ... */
1047 #define MAX_DST_WIDTH (365*24*60*60)
1048 #define MAX_DST_SKIP (7*24*60*60)
1049
1050         for (i = 0; i < table_size; i++) {
1051                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1052                         break;
1053         }
1054
1055         if (i < table_size) {
1056                 zone = dst_table[i].zone;
1057         } else {
1058                 time_t low,high;
1059
1060                 zone = TimeZone(t);
1061                 if (dst_table == NULL)
1062                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1063                 else
1064                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1065                 if (tdt == NULL) {
1066                         if (dst_table)
1067                                 free(dst_table);
1068                         table_size = 0;
1069                 } else {
1070                         dst_table = tdt;
1071                         table_size++;
1072     
1073                         dst_table[i].zone = zone; 
1074                         dst_table[i].start = dst_table[i].end = t;
1075     
1076                         /* no entry will cover more than 6 months */
1077                         low = t - MAX_DST_WIDTH/2;
1078                         if (t < low)
1079                                 low = TIME_T_MIN;
1080       
1081                         high = t + MAX_DST_WIDTH/2;
1082                         if (high < t)
1083                                 high = TIME_T_MAX;
1084       
1085                         /*
1086                          * Widen the new entry using two bisection searches.
1087                          */
1088                         while (low+60*60 < dst_table[i].start) {
1089                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1090                                         t = dst_table[i].start - MAX_DST_SKIP;
1091                                 else
1092                                         t = low + (dst_table[i].start-low)/2;
1093                                 if (TimeZone(t) == zone)
1094                                         dst_table[i].start = t;
1095                                 else
1096                                         low = t;
1097                         }
1098
1099                         while (high-60*60 > dst_table[i].end) {
1100                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1101                                         t = dst_table[i].end + MAX_DST_SKIP;
1102                                 else
1103                                         t = high - (high-dst_table[i].end)/2;
1104                                 if (TimeZone(t) == zone)
1105                                         dst_table[i].end = t;
1106                                 else
1107                                         high = t;
1108                         }
1109                 }
1110         }
1111         return zone;
1112 }
1113
1114 /*
1115  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1116  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1117  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1118  * daylight savings transitions because some local times are ambiguous.
1119  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1120  */
1121 static int
1122 LocTimeDiff(time_t lt)
1123 {
1124         int d = TimeZoneFaster(lt);
1125         time_t t = lt + d;
1126
1127         /* if overflow occurred, ignore all the adjustments so far */
1128         if (((t < lt) ^ (d < 0)))
1129                 t = lt;
1130
1131         /*
1132          * Now t should be close enough to the true UTC to yield the
1133          * right answer.
1134          */
1135         return TimeZoneFaster(t);
1136 }
1137
1138 static int
1139 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1140 {
1141         guint32 timeval;
1142         nstime_t ts;
1143  
1144         timeval = tvb_get_letohl(tvb, offset);
1145         if (timeval == 0xffffffff) {
1146                 proto_tree_add_text(tree, tvb, offset, 4,
1147                     "%s: No time specified (0xffffffff)",
1148                     proto_registrar_get_name(hf_date));
1149                 offset += 4;
1150                 return offset;
1151         }
1152
1153         /*
1154          * We add the local time offset.
1155          */
1156         ts.secs = timeval + LocTimeDiff(timeval);
1157         ts.nsecs = 0;
1158
1159         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1160         offset += 4;
1161  
1162         return offset;
1163 }
1164
1165 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1166
1167 /*
1168  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1169  * to an "nstime_t".
1170  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1171  * midnight "UTC", in 100ns units.
1172  * Return TRUE if the conversion succeeds, FALSE otherwise.
1173  *
1174  * According to the Samba code, it appears to be kludge-GMT (at least for
1175  * file listings). This means it's the GMT you get by taking a local time
1176  * and adding the server time zone offset.  This is NOT the same as GMT in
1177  * some cases.   However, we don't know the server time zone, so we don't
1178  * do that adjustment.
1179  *
1180  * This code is based on the Samba code:
1181  *
1182  *      Unix SMB/Netbios implementation.
1183  *      Version 1.9.
1184  *      time handling functions
1185  *      Copyright (C) Andrew Tridgell 1992-1998
1186  */
1187 static gboolean
1188 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1189 {
1190         double d;
1191         /* The next two lines are a fix needed for the 
1192             broken SCO compiler. JRA. */
1193         time_t l_time_min = TIME_T_MIN;
1194         time_t l_time_max = TIME_T_MAX;
1195
1196         if (filetime_high == 0)
1197                 return FALSE;
1198
1199         /*
1200          * Get the time as a double, in seconds and fractional seconds.
1201          */
1202         d = ((double)filetime_high)*4.0*(double)(1<<30);
1203         d += filetime_low;
1204         d *= 1.0e-7;
1205  
1206         /* Now adjust by 369 years, to make the seconds since 1970. */
1207         d -= TIME_FIXUP_CONSTANT;
1208
1209         if (!(l_time_min <= d && d <= l_time_max))
1210                 return FALSE;
1211
1212         /*
1213          * Get the time as seconds and nanoseconds.
1214          */
1215         tv->secs = d;
1216         tv->nsecs = (d - tv->secs)*1000000000;
1217
1218         return TRUE;
1219 }
1220
1221 int
1222 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1223 {
1224         guint32 filetime_high, filetime_low;
1225         nstime_t ts;
1226
1227         /* XXX there seems also to be another special time value which is fairly common :
1228            0x40000000 00000000  
1229            the meaning of this one is yet unknown 
1230         */
1231         if (tree) {
1232                 filetime_low = tvb_get_letohl(tvb, offset);
1233                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1234                 if (filetime_low == 0 && filetime_high == 0) {
1235                         proto_tree_add_text(tree, tvb, offset, 8,
1236                             "%s: No time specified (0)",
1237                             proto_registrar_get_name(hf_date));
1238                 } else if(filetime_low==0 && filetime_high==0x80000000){
1239                         proto_tree_add_text(tree, tvb, offset, 8,
1240                             "%s: Infinity (relative time)",
1241                             proto_registrar_get_name(hf_date));
1242                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1243                         proto_tree_add_text(tree, tvb, offset, 8,
1244                             "%s: Infinity (absolute time)",
1245                             proto_registrar_get_name(hf_date));
1246                 } else {                        
1247                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1248                                 proto_tree_add_time(tree, hf_date, tvb,
1249                                     offset, 8, &ts);
1250                         } else {
1251                                 proto_tree_add_text(tree, tvb, offset, 8,
1252                                     "%s: Time can't be converted",
1253                                     proto_registrar_get_name(hf_date));
1254                         }
1255                 }
1256         }
1257
1258         offset += 8;
1259         return offset;
1260 }
1261
1262 static int
1263 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1264     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1265 {
1266         guint16 dos_time, dos_date;
1267         proto_item *item = NULL;
1268         proto_tree *tree = NULL;
1269         struct tm tm;
1270         time_t t;
1271         static const int mday_noleap[12] = {
1272                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1273         };
1274         static const int mday_leap[12] = {
1275                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1276         };
1277 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1278         nstime_t tv;
1279
1280         if (time_first) {
1281                 dos_time = tvb_get_letohs(tvb, offset);
1282                 dos_date = tvb_get_letohs(tvb, offset+2);
1283         } else {
1284                 dos_date = tvb_get_letohs(tvb, offset);
1285                 dos_time = tvb_get_letohs(tvb, offset+2);
1286         }
1287
1288         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1289             (dos_date == 0 && dos_time == 0)) {
1290                 /*
1291                  * No date/time specified.
1292                  */
1293                 if(parent_tree){
1294                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1295                             "%s: No time specified (0x%08x)",
1296                             proto_registrar_get_name(hf_date),
1297                             (dos_date << 16) | dos_time);
1298                 }
1299                 offset += 4;
1300                 return offset;
1301         }
1302
1303         tm.tm_sec = (dos_time&0x1f)*2;
1304         tm.tm_min = (dos_time>>5)&0x3f;
1305         tm.tm_hour = (dos_time>>11)&0x1f;
1306         tm.tm_mday = dos_date&0x1f;
1307         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1308         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1309         tm.tm_isdst = -1;
1310
1311         /*
1312          * Do some sanity checks before calling "mktime()";
1313          * "mktime()" doesn't do them, it "normalizes" out-of-range
1314          * values.
1315          */
1316         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1317            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1318            (ISLEAP(tm.tm_year + 1900) ?
1319              tm.tm_mday > mday_leap[tm.tm_mon] :
1320              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1321              (t = mktime(&tm)) == -1) {
1322                 /*
1323                  * Invalid date/time.
1324                  */
1325                 if (parent_tree) {
1326                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1327                             "%s: Invalid time",
1328                             proto_registrar_get_name(hf_date));
1329                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1330                         if (time_first) {
1331                                 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);
1332                                 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);
1333                         } else {
1334                                 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);
1335                                 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);
1336                         }
1337                 }
1338                 offset += 4;
1339                 return offset;
1340         }
1341
1342         tv.secs = t;
1343         tv.nsecs = 0;
1344
1345         if(parent_tree){
1346                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1347                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1348                 if (time_first) {
1349                         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);
1350                         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);
1351                 } else {
1352                         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);
1353                         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);
1354                 }
1355         }
1356
1357         offset += 4;
1358
1359         return offset;
1360 }
1361
1362
1363 static const value_string da_access_vals[] = {
1364         { 0,            "Open for reading"},
1365         { 1,            "Open for writing"},
1366         { 2,            "Open for reading and writing"},
1367         { 3,            "Open for execute"},
1368         {0, NULL}
1369 };
1370 static const value_string da_sharing_vals[] = {
1371         { 0,            "Compatibility mode"},
1372         { 1,            "Deny read/write/execute (exclusive)"},
1373         { 2,            "Deny write"},
1374         { 3,            "Deny read/execute"},
1375         { 4,            "Deny none"},
1376         {0, NULL}
1377 };
1378 static const value_string da_locality_vals[] = {
1379         { 0,            "Locality of reference unknown"},
1380         { 1,            "Mainly sequential access"},
1381         { 2,            "Mainly random access"},
1382         { 3,            "Random access with some locality"},
1383         {0, NULL}
1384 };
1385 static const true_false_string tfs_da_caching = {
1386         "Do not cache this file",
1387         "Caching permitted on this file"
1388 };
1389 static const true_false_string tfs_da_writetru = {
1390         "Write through enabled",
1391         "Write through disabled"
1392 };
1393 static int
1394 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1395 {
1396         guint16 mask;
1397         proto_item *item = NULL;
1398         proto_tree *tree = NULL;
1399
1400         mask = tvb_get_letohs(tvb, offset);
1401
1402         if(parent_tree){
1403                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1404                         "%s Access: 0x%04x", type, mask);
1405                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1406         }
1407
1408         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1409                 tvb, offset, 2, mask);
1410         proto_tree_add_boolean(tree, hf_smb_access_caching,
1411                 tvb, offset, 2, mask);
1412         proto_tree_add_uint(tree, hf_smb_access_locality,
1413                 tvb, offset, 2, mask);
1414         proto_tree_add_uint(tree, hf_smb_access_sharing,
1415                 tvb, offset, 2, mask);
1416         proto_tree_add_uint(tree, hf_smb_access_mode,
1417                 tvb, offset, 2, mask);
1418
1419         offset += 2;
1420
1421         return offset;
1422 }
1423
1424 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1425 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1426 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1427 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1428 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1429 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1430 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1431 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1432 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1433 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1434 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1435 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1436 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1437 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1438 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1439
1440 /*
1441  * These are flags to be used in NT Create operations.
1442  */
1443 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1444 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1445 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1446 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1447 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1448 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1449 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1450
1451 static const true_false_string tfs_file_attribute_write_through = {
1452         "This object requires WRITE THROUGH",
1453         "This object does NOT require write through",
1454 };
1455 static const true_false_string tfs_file_attribute_no_buffering = {
1456         "This object requires NO BUFFERING",
1457         "This object can be buffered",
1458 };
1459 static const true_false_string tfs_file_attribute_random_access = {
1460         "This object will be RANDOM ACCESSed",
1461         "Random access is NOT requested",
1462 };
1463 static const true_false_string tfs_file_attribute_sequential_scan = {
1464         "This object is optimized for SEQUENTIAL SCAN",
1465         "This object is NOT optimized for sequential scan",
1466 };
1467 static const true_false_string tfs_file_attribute_delete_on_close = {
1468         "This object will be DELETED ON CLOSE",
1469         "This object will not be deleted on close",
1470 };
1471 static const true_false_string tfs_file_attribute_backup_semantics = {
1472         "This object supports BACKUP SEMANTICS",
1473         "This object does NOT support backup semantics",
1474 };
1475 static const true_false_string tfs_file_attribute_posix_semantics = {
1476         "This object supports POSIX SEMANTICS",
1477         "This object does NOT support POSIX semantics",
1478 };
1479 static const true_false_string tfs_file_attribute_read_only = {
1480         "This file is READ ONLY",
1481         "This file is NOT read only",
1482 };
1483 static const true_false_string tfs_file_attribute_hidden = {
1484         "This is a HIDDEN file",
1485         "This is NOT a hidden file"
1486 };
1487 static const true_false_string tfs_file_attribute_system = {
1488         "This is a SYSTEM file",
1489         "This is NOT a system file"
1490 };
1491 static const true_false_string tfs_file_attribute_volume = {
1492         "This is a VOLUME ID",
1493         "This is NOT a volume ID"
1494 };
1495 static const true_false_string tfs_file_attribute_directory = {
1496         "This is a DIRECTORY",
1497         "This is NOT a directory"
1498 };
1499 static const true_false_string tfs_file_attribute_archive = {
1500         "This is an ARCHIVE file",
1501         "This is NOT an archive file"
1502 };
1503 static const true_false_string tfs_file_attribute_device = {
1504         "This is a DEVICE",
1505         "This is NOT a device"
1506 };
1507 static const true_false_string tfs_file_attribute_normal = {
1508         "This file is an ordinary file",
1509         "This file has some attribute set"
1510 };
1511 static const true_false_string tfs_file_attribute_temporary = {
1512         "This is a TEMPORARY file",
1513         "This is NOT a temporary file"
1514 };
1515 static const true_false_string tfs_file_attribute_sparse = {
1516         "This is a SPARSE file",
1517         "This is NOT a sparse file"
1518 };
1519 static const true_false_string tfs_file_attribute_reparse = {
1520         "This file has an associated REPARSE POINT",
1521         "This file does NOT have an associated reparse point"
1522 };
1523 static const true_false_string tfs_file_attribute_compressed = {
1524         "This is a COMPRESSED file",
1525         "This is NOT a compressed file"
1526 };
1527 static const true_false_string tfs_file_attribute_offline = {
1528         "This file is OFFLINE",
1529         "This file is NOT offline"
1530 };
1531 static const true_false_string tfs_file_attribute_not_content_indexed = {
1532         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1533         "This file MAY be indexed by the content indexing service"
1534 };
1535 static const true_false_string tfs_file_attribute_encrypted = {
1536         "This is an ENCRYPTED file",
1537         "This is NOT an encrypted file"
1538 };
1539
1540 static int
1541 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1542 {
1543         guint16 mask;
1544         proto_item *item = NULL;
1545         proto_tree *tree = NULL;
1546
1547         mask = tvb_get_letohs(tvb, offset);
1548
1549         if(parent_tree){
1550                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1551                         "File Attributes: 0x%04x", mask);
1552                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1553         }
1554         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1555                 tvb, offset, 2, mask);
1556         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1557                 tvb, offset, 2, mask);
1558         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1559                 tvb, offset, 2, mask);
1560         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1561                 tvb, offset, 2, mask);
1562         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1563                 tvb, offset, 2, mask);
1564         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1565                 tvb, offset, 2, mask);
1566
1567         offset += 2;
1568
1569         return offset;
1570 }
1571
1572 /* 3.11 */
1573 static int
1574 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1575 {
1576         guint32 mask;
1577         proto_item *item = NULL;
1578         proto_tree *tree = NULL;
1579
1580         mask = tvb_get_letohl(tvb, offset);
1581
1582         if(parent_tree){
1583                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1584                         "File Attributes: 0x%08x", mask);
1585                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1586         }
1587
1588         /*
1589          * XXX - Network Monitor disagrees on some of the
1590          * bits, e.g. the bits above temporary are "atomic write"
1591          * and "transaction write", and it says nothing about the
1592          * bits above that.
1593          *
1594          * Does the Win32 API documentation, or the NT Native API book,
1595          * suggest anything?
1596          */
1597         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1598                 tvb, offset, 4, mask);
1599         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1600                 tvb, offset, 4, mask);
1601         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1602                 tvb, offset, 4, mask);
1603         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1604                 tvb, offset, 4, mask);
1605         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1606                 tvb, offset, 4, mask);
1607         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1608                 tvb, offset, 4, mask);
1609         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1610                 tvb, offset, 4, mask);
1611         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1612                 tvb, offset, 4, mask);
1613         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1614                 tvb, offset, 4, mask);
1615         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1616                 tvb, offset, 4, mask);
1617         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1618                 tvb, offset, 4, mask);
1619         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1620                 tvb, offset, 4, mask);
1621         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1622                 tvb, offset, 4, mask);
1623         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1624                 tvb, offset, 4, mask);
1625         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1626                 tvb, offset, 4, mask);
1627         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1628                 tvb, offset, 4, mask);
1629         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1630                 tvb, offset, 4, mask);
1631         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1632                 tvb, offset, 4, mask);
1633         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1634                 tvb, offset, 4, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1636                 tvb, offset, 4, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1638                 tvb, offset, 4, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1640                 tvb, offset, 4, mask);
1641
1642         offset += 4;
1643
1644         return offset;
1645 }
1646
1647 static int
1648 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1649 {
1650         guint8 mask;
1651         proto_item *item = NULL;
1652         proto_tree *tree = NULL;
1653
1654         mask = tvb_get_guint8(tvb, offset);
1655
1656         if(parent_tree){
1657                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1658                         "File Attributes: 0x%02x", mask);
1659                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1660         }
1661         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1662                 tvb, offset, 1, mask);
1663         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1664                 tvb, offset, 1, mask);
1665         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1666                 tvb, offset, 1, mask);
1667         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1668                 tvb, offset, 1, mask);
1669         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1670                 tvb, offset, 1, mask);
1671         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1672                 tvb, offset, 1, mask);
1673
1674         offset += 1;
1675
1676         return offset;
1677 }
1678
1679 static const true_false_string tfs_search_attribute_read_only = {
1680         "Include READ ONLY files in search results",
1681         "Do NOT include read only files in search results",
1682 };
1683 static const true_false_string tfs_search_attribute_hidden = {
1684         "Include HIDDEN files in search results",
1685         "Do NOT include hidden files in search results"
1686 };
1687 static const true_false_string tfs_search_attribute_system = {
1688         "Include SYSTEM files in search results",
1689         "Do NOT include system files in search results"
1690 };
1691 static const true_false_string tfs_search_attribute_volume = {
1692         "Include VOLUME IDs in search results",
1693         "Do NOT include volume IDs in search results"
1694 };
1695 static const true_false_string tfs_search_attribute_directory = {
1696         "Include DIRECTORIES in search results",
1697         "Do NOT include directories in search results"
1698 };
1699 static const true_false_string tfs_search_attribute_archive = {
1700         "Include ARCHIVE files in search results",
1701         "Do NOT include archive files in search results"
1702 };
1703
1704 static int
1705 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1706 {
1707         guint16 mask;
1708         proto_item *item = NULL;
1709         proto_tree *tree = NULL;
1710
1711         mask = tvb_get_letohs(tvb, offset);
1712
1713         if(parent_tree){
1714                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1715                         "Search Attributes: 0x%04x", mask);
1716                 tree = proto_item_add_subtree(item, ett_smb_search);
1717         }
1718
1719         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1720                 tvb, offset, 2, mask);
1721         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1722                 tvb, offset, 2, mask);
1723         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1724                 tvb, offset, 2, mask);  
1725         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1726                 tvb, offset, 2, mask);
1727         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1728                 tvb, offset, 2, mask);
1729         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1730                 tvb, offset, 2, mask);
1731
1732         offset += 2;
1733         return offset;
1734 }
1735
1736 #if 0
1737 /*
1738  * XXX - this isn't used.
1739  * Is this used for anything?  NT Create AndX doesn't use it.
1740  * Is there some 16-bit attribute field with more bits than Read Only,
1741  * Hidden, System, Volume ID, Directory, and Archive?
1742  */
1743 static int
1744 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1745 {
1746         guint32 mask;
1747         proto_item *item = NULL;
1748         proto_tree *tree = NULL;
1749
1750         mask = tvb_get_letohl(tvb, offset);
1751
1752         if(parent_tree){
1753                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1754                         "File Attributes: 0x%08x", mask);
1755                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1756         }
1757         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1758                 tvb, offset, 2, mask);
1759         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1760                 tvb, offset, 2, mask);
1761         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1762                 tvb, offset, 2, mask);
1763         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1764                 tvb, offset, 2, mask);
1765         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1766                 tvb, offset, 2, mask);
1767         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1768                 tvb, offset, 2, mask);
1769         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1770                 tvb, offset, 2, mask);
1771         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1772                 tvb, offset, 2, mask);
1773         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1774                 tvb, offset, 2, mask);
1775         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1776                 tvb, offset, 2, mask);
1777         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1778                 tvb, offset, 2, mask);
1779         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1780                 tvb, offset, 2, mask);
1781         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1782                 tvb, offset, 2, mask);
1783         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1784                 tvb, offset, 2, mask);
1785         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1786                 tvb, offset, 2, mask);
1787
1788         offset += 2;
1789
1790         return offset;
1791 }
1792 #endif
1793
1794
1795 #define SERVER_CAP_RAW_MODE            0x00000001
1796 #define SERVER_CAP_MPX_MODE            0x00000002
1797 #define SERVER_CAP_UNICODE             0x00000004
1798 #define SERVER_CAP_LARGE_FILES         0x00000008
1799 #define SERVER_CAP_NT_SMBS             0x00000010
1800 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1801 #define SERVER_CAP_STATUS32            0x00000040
1802 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1803 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1804 #define SERVER_CAP_NT_FIND             0x00000200
1805 #define SERVER_CAP_DFS                 0x00001000
1806 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1807 #define SERVER_CAP_LARGE_READX         0x00004000
1808 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1809 #define SERVER_CAP_UNIX                0x00800000
1810 #define SERVER_CAP_RESERVED            0x02000000
1811 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1812 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1813 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1814 static const true_false_string tfs_server_cap_raw_mode = {
1815         "Read Raw and Write Raw are supported",
1816         "Read Raw and Write Raw are not supported"
1817 };
1818 static const true_false_string tfs_server_cap_mpx_mode = {
1819         "Read Mpx and Write Mpx are supported",
1820         "Read Mpx and Write Mpx are not supported"
1821 };
1822 static const true_false_string tfs_server_cap_unicode = {
1823         "Unicode strings are supported",
1824         "Unicode strings are not supported"
1825 };
1826 static const true_false_string tfs_server_cap_large_files = {
1827         "Large files are supported",
1828         "Large files are not supported",
1829 };
1830 static const true_false_string tfs_server_cap_nt_smbs = {
1831         "NT SMBs are supported",
1832         "NT SMBs are not supported"
1833 };
1834 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1835         "RPC remote APIs are supported",
1836         "RPC remote APIs are not supported"
1837 };
1838 static const true_false_string tfs_server_cap_nt_status = {
1839         "NT status codes are supported",
1840         "NT status codes are not supported"
1841 };
1842 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1843         "Level 2 oplocks are supported",
1844         "Level 2 oplocks are not supported"
1845 };
1846 static const true_false_string tfs_server_cap_lock_and_read = {
1847         "Lock and Read is supported",
1848         "Lock and Read is not supported"
1849 };
1850 static const true_false_string tfs_server_cap_nt_find = {
1851         "NT Find is supported",
1852         "NT Find is not supported"
1853 };
1854 static const true_false_string tfs_server_cap_dfs = {
1855         "Dfs is supported",
1856         "Dfs is not supported"
1857 };
1858 static const true_false_string tfs_server_cap_infolevel_passthru = {
1859         "NT information level request passthrough is supported",
1860         "NT information level request passthrough is not supported"
1861 };
1862 static const true_false_string tfs_server_cap_large_readx = {
1863         "Large Read andX is supported",
1864         "Large Read andX is not supported"
1865 };
1866 static const true_false_string tfs_server_cap_large_writex = {
1867         "Large Write andX is supported",
1868         "Large Write andX is not supported"
1869 };
1870 static const true_false_string tfs_server_cap_unix = {
1871         "UNIX extensions are supported",
1872         "UNIX extensions are not supported"
1873 };
1874 static const true_false_string tfs_server_cap_reserved = {
1875         "Reserved",
1876         "Reserved"
1877 };
1878 static const true_false_string tfs_server_cap_bulk_transfer = {
1879         "Bulk Read and Bulk Write are supported",
1880         "Bulk Read and Bulk Write are not supported"
1881 };
1882 static const true_false_string tfs_server_cap_compressed_data = {
1883         "Compressed data transfer is supported",
1884         "Compressed data transfer is not supported"
1885 };
1886 static const true_false_string tfs_server_cap_extended_security = {
1887         "Extended security exchanges are supported",
1888         "Extended security exchanges are not supported"
1889 };
1890 static int
1891 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1892 {
1893         guint32 mask;
1894         proto_item *item = NULL;
1895         proto_tree *tree = NULL;
1896
1897         mask = tvb_get_letohl(tvb, offset);
1898
1899         if(parent_tree){
1900                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1901                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1902         }
1903
1904         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1905                 tvb, offset, 4, mask);
1906         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1907                 tvb, offset, 4, mask);
1908         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1909                 tvb, offset, 4, mask);
1910         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1911                 tvb, offset, 4, mask);
1912         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1913                 tvb, offset, 4, mask);
1914         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1915                 tvb, offset, 4, mask);
1916         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1917                 tvb, offset, 4, mask);
1918         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1919                 tvb, offset, 4, mask);
1920         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1921                 tvb, offset, 4, mask);
1922         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1923                 tvb, offset, 4, mask);
1924         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1925                 tvb, offset, 4, mask);
1926         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1927                 tvb, offset, 4, mask);
1928         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1929                 tvb, offset, 4, mask);
1930         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1931                 tvb, offset, 4, mask);
1932         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1933                 tvb, offset, 4, mask);
1934         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1935                 tvb, offset, 4, mask);
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1941                 tvb, offset, 4, mask);
1942
1943         return mask;
1944 }
1945
1946 #define RAWMODE_READ   0x01
1947 #define RAWMODE_WRITE  0x02
1948 static const true_false_string tfs_rm_read = {
1949         "Read Raw is supported",
1950         "Read Raw is not supported"
1951 };
1952 static const true_false_string tfs_rm_write = {
1953         "Write Raw is supported",
1954         "Write Raw is not supported"
1955 };
1956
1957 static int
1958 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1959 {
1960         guint16 mask;
1961         proto_item *item = NULL;
1962         proto_tree *tree = NULL;
1963
1964         mask = tvb_get_letohs(tvb, offset);
1965
1966         if(parent_tree){
1967                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1968                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1969         }
1970
1971         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1972         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1973
1974         offset += 2;
1975
1976         return offset;
1977 }
1978
1979 #define SECURITY_MODE_MODE             0x01
1980 #define SECURITY_MODE_PASSWORD         0x02
1981 #define SECURITY_MODE_SIGNATURES       0x04
1982 #define SECURITY_MODE_SIG_REQUIRED     0x08
1983 static const true_false_string tfs_sm_mode = {
1984         "USER security mode",
1985         "SHARE security mode"
1986 };
1987 static const true_false_string tfs_sm_password = {
1988         "ENCRYPTED password. Use challenge/response",
1989         "PLAINTEXT password"
1990 };
1991 static const true_false_string tfs_sm_signatures = {
1992         "Security signatures ENABLED",
1993         "Security signatures NOT enabled"
1994 };
1995 static const true_false_string tfs_sm_sig_required = {
1996         "Security signatures REQUIRED",
1997         "Security signatures NOT required"
1998 };
1999
2000 static int
2001 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2002 {
2003         guint16 mask = 0;
2004         proto_item *item = NULL;
2005         proto_tree *tree = NULL;
2006
2007         switch(wc){
2008         case 13:
2009                 mask = tvb_get_letohs(tvb, offset);
2010                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2011                                 "Security Mode: 0x%04x", mask);
2012                 tree = proto_item_add_subtree(item, ett_smb_mode);
2013                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2014                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2015                 offset += 2;
2016                 break;
2017
2018         case 17:
2019                 mask = tvb_get_guint8(tvb, offset);
2020                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2021                                 "Security Mode: 0x%02x", mask);
2022                 tree = proto_item_add_subtree(item, ett_smb_mode);
2023                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2024                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2025                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2026                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2027                 offset += 1;
2028                 break;
2029         }
2030
2031         return offset;
2032 }
2033
2034 static int
2035 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2036 {
2037         proto_item *it = NULL;
2038         proto_tree *tr = NULL;
2039         guint16 bc;
2040         guint8 wc;
2041
2042         WORD_COUNT;
2043
2044         BYTE_COUNT;
2045
2046         if(tree){
2047                 it = proto_tree_add_text(tree, tvb, offset, bc,
2048                                 "Requested Dialects");
2049                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2050         }
2051
2052         while(bc){
2053                 int len;
2054                 const guint8 *str;
2055                 proto_item *dit = NULL;
2056                 proto_tree *dtr = NULL;
2057
2058                 /* XXX - what if this runs past bc? */
2059                 len = tvb_strsize(tvb, offset+1);
2060                 str = tvb_get_ptr(tvb, offset+1, len);
2061
2062                 if(tr){
2063                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2064                                         "Dialect: %s", str);
2065                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2066                 }
2067
2068                 /* Buffer Format */
2069                 CHECK_BYTE_COUNT(1);
2070                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2071                         TRUE);
2072                 COUNT_BYTES(1);
2073
2074                 /*Dialect Name */
2075                 CHECK_BYTE_COUNT(len);
2076                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2077                         len, str);
2078                 COUNT_BYTES(len);
2079         }
2080
2081         END_OF_SMB
2082
2083         return offset;
2084 }
2085
2086 static int
2087 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2088 {
2089         guint8 wc;
2090         guint16 dialect;
2091         const char *dn;
2092         int dn_len;
2093         guint16 bc;
2094         guint16 ekl=0;
2095         guint32 caps=0;
2096         gint16 tz;
2097
2098         WORD_COUNT;
2099
2100         /* Dialect Index */
2101         dialect = tvb_get_letohs(tvb, offset);
2102         switch(wc){
2103         case 1:
2104                 if(dialect==0xffff){
2105                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2106                                 tvb, offset, 2, dialect,
2107                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2108                 } else {
2109                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2110                                 tvb, offset, 2, dialect);
2111                 }
2112                 break;
2113         case 13:
2114                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2115                         tvb, offset, 2, dialect,
2116                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2117                 break;
2118         case 17:
2119                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2120                         tvb, offset, 2, dialect,
2121                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2122                 break;
2123         default:
2124                 proto_tree_add_text(tree, tvb, offset, wc*2,
2125                         "Words for unknown response format");
2126                 offset += wc*2;
2127                 goto bytecount;
2128         }
2129         offset += 2;
2130
2131         switch(wc){
2132         case 13:
2133                 /* Security Mode */
2134                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2135
2136                 /* Maximum Transmit Buffer Size */
2137                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2138                         tvb, offset, 2, TRUE);
2139                 offset += 2;
2140
2141                 /* Maximum Multiplex Count */
2142                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2143                         tvb, offset, 2, TRUE);
2144                 offset += 2;
2145
2146                 /* Maximum Vcs Number */
2147                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2148                         tvb, offset, 2, TRUE);
2149                 offset += 2;
2150
2151                 /* raw mode */
2152                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2153
2154                 /* session key */
2155                 proto_tree_add_item(tree, hf_smb_session_key,
2156                         tvb, offset, 4, TRUE);
2157                 offset += 4;
2158
2159                 /* current time and date at server */
2160                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2161                     TRUE);
2162
2163                 /* time zone */
2164                 tz = tvb_get_letohs(tvb, offset);
2165                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2166                 offset += 2;
2167
2168                 /* encryption key length */
2169                 ekl = tvb_get_letohs(tvb, offset);
2170                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2171                 offset += 2;
2172
2173                 /* 2 reserved bytes */
2174                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2175                 offset += 2;
2176
2177                 break;
2178
2179         case 17:
2180                 /* Security Mode */
2181                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2182
2183                 /* Maximum Multiplex Count */
2184                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2185                         tvb, offset, 2, TRUE);
2186                 offset += 2;
2187
2188                 /* Maximum Vcs Number */
2189                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2190                         tvb, offset, 2, TRUE);
2191                 offset += 2;
2192
2193                 /* Maximum Transmit Buffer Size */
2194                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2195                         tvb, offset, 4, TRUE);
2196                 offset += 4;
2197
2198                 /* maximum raw buffer size */
2199                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2200                         tvb, offset, 4, TRUE);
2201                 offset += 4;
2202
2203                 /* session key */
2204                 proto_tree_add_item(tree, hf_smb_session_key,
2205                         tvb, offset, 4, TRUE);
2206                 offset += 4;
2207
2208                 /* server capabilities */
2209                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2210                 offset += 4;
2211
2212                 /* system time */
2213                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2214                                 hf_smb_system_time);
2215
2216                 /* time zone */
2217                 tz = tvb_get_letohs(tvb, offset);
2218                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2219                         tvb, offset, 2, tz,
2220                         "Server Time Zone: %d min from UTC", tz);
2221                 offset += 2;
2222
2223                 /* encryption key length */
2224                 ekl = tvb_get_guint8(tvb, offset);
2225                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2226                         tvb, offset, 1, ekl);
2227                 offset += 1;
2228
2229                 break;
2230         }
2231
2232         BYTE_COUNT;
2233
2234         switch(wc){
2235         case 13:
2236                 /* challenge/response encryption key */
2237                 if(ekl){
2238                         CHECK_BYTE_COUNT(ekl);
2239                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2240                         COUNT_BYTES(ekl);
2241                 }
2242
2243                 /*
2244                  * Primary domain.
2245                  *
2246                  * XXX - not present if negotiated dialect isn't
2247                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2248                  * have to see the request, or assume what dialect strings
2249                  * were sent, to determine that.
2250                  *
2251                  * Is this something other than a primary domain if the
2252                  * negotiated dialect is Windows for Workgroups 3.1a?
2253                  * It appears to be 8 bytes of binary data in at least
2254                  * one capture - is that an encryption key or something
2255                  * such as that?
2256                  */
2257                 dn = get_unicode_or_ascii_string(tvb, &offset,
2258                         pinfo, &dn_len, FALSE, FALSE, &bc);
2259                 if (dn == NULL)
2260                         goto endofcommand;
2261                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2262                         offset, dn_len,dn);
2263                 COUNT_BYTES(dn_len);
2264                 break;
2265
2266         case 17:
2267                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2268                         smb_info_t *si;
2269
2270                         /* challenge/response encryption key */
2271                         /* XXX - is this aligned on an even boundary? */
2272                         if(ekl){
2273                                 CHECK_BYTE_COUNT(ekl);
2274                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2275                                         tvb, offset, ekl, TRUE);
2276                                 COUNT_BYTES(ekl);
2277                         }
2278
2279                         /* domain */
2280                         /* this string is special, unicode is flagged in caps */
2281                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2282                         si = pinfo->private_data;
2283                         si->unicode = (caps&SERVER_CAP_UNICODE);
2284                         dn = get_unicode_or_ascii_string(tvb,
2285                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2286                                 &bc);
2287                         if (dn == NULL)
2288                                 goto endofcommand;
2289                         proto_tree_add_string(tree, hf_smb_primary_domain,
2290                                 tvb, offset, dn_len, dn);
2291                         COUNT_BYTES(dn_len);
2292                 } else {
2293                         /* guid */
2294                         /* XXX - show it in the standard Microsoft format
2295                            for GUIDs? */
2296                         CHECK_BYTE_COUNT(16);
2297                         proto_tree_add_item(tree, hf_smb_server_guid,
2298                                 tvb, offset, 16, TRUE);
2299                         COUNT_BYTES(16);
2300
2301                         /* security blob */
2302                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2303                            data structure, at least in NT 5.0-and-later
2304                            server replies? */
2305                         if(bc){
2306                                 proto_tree_add_item(tree, hf_smb_security_blob,
2307                                         tvb, offset, bc, TRUE);
2308                                 COUNT_BYTES(bc);
2309                         }
2310                 }
2311                 break;
2312         }
2313
2314         END_OF_SMB
2315
2316         return offset;
2317 }
2318
2319
2320 static int
2321 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2322 {
2323         int dn_len;
2324         const char *dn;
2325         guint8 wc;
2326         guint16 bc;
2327
2328         WORD_COUNT;
2329  
2330         BYTE_COUNT;
2331
2332         /* buffer format */
2333         CHECK_BYTE_COUNT(1);
2334         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2335         COUNT_BYTES(1);
2336
2337         /* dir name */
2338         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2339                 FALSE, FALSE, &bc);
2340         if (dn == NULL)
2341                 goto endofcommand;
2342         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2343                 dn);
2344         COUNT_BYTES(dn_len);
2345
2346         if (check_col(pinfo->cinfo, COL_INFO)) {
2347                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2348         }
2349
2350         END_OF_SMB
2351
2352         return offset;
2353 }
2354
2355 static int
2356 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2357 {
2358         guint8 wc;
2359         guint16 bc;
2360  
2361         WORD_COUNT;
2362  
2363         BYTE_COUNT;
2364
2365         END_OF_SMB
2366
2367         return offset;
2368 }
2369
2370 static int
2371 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2372 {
2373         guint16 ec, bc;
2374         guint8 wc;
2375
2376         WORD_COUNT;
2377
2378         /* echo count */
2379         ec = tvb_get_letohs(tvb, offset);
2380         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2381         offset += 2;
2382
2383         BYTE_COUNT;
2384
2385         if (bc != 0) {
2386                 /* echo data */
2387                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2388                 COUNT_BYTES(bc);
2389         }
2390
2391         END_OF_SMB
2392
2393         return offset;
2394 }
2395
2396 static int
2397 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2398 {
2399         guint16 bc;
2400         guint8 wc;
2401
2402         WORD_COUNT;
2403
2404         /* echo sequence number */
2405         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2406         offset += 2;
2407
2408         BYTE_COUNT;
2409
2410         if (bc != 0) {
2411                 /* echo data */
2412                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2413                 COUNT_BYTES(bc);
2414         }
2415
2416         END_OF_SMB
2417
2418         return offset;
2419 }
2420
2421 static int
2422 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2423 {
2424         int an_len, pwlen;
2425         const char *an;
2426         guint8 wc;
2427         guint16 bc;
2428
2429         WORD_COUNT;
2430  
2431         BYTE_COUNT;
2432
2433         /* buffer format */
2434         CHECK_BYTE_COUNT(1);
2435         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2436         COUNT_BYTES(1);
2437
2438         /* Path */
2439         an = get_unicode_or_ascii_string(tvb, &offset,
2440                 pinfo, &an_len, FALSE, FALSE, &bc);
2441         if (an == NULL)
2442                 goto endofcommand;
2443         proto_tree_add_string(tree, hf_smb_path, tvb,
2444                 offset, an_len, an);
2445         COUNT_BYTES(an_len);
2446
2447         if (check_col(pinfo->cinfo, COL_INFO)) {
2448                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2449         }
2450
2451         /* buffer format */
2452         CHECK_BYTE_COUNT(1);
2453         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2454         COUNT_BYTES(1);
2455
2456         /* password, ANSI */
2457         /* XXX - what if this runs past bc? */
2458         pwlen = tvb_strsize(tvb, offset);
2459         CHECK_BYTE_COUNT(pwlen);
2460         proto_tree_add_item(tree, hf_smb_password,
2461                 tvb, offset, pwlen, TRUE);
2462         COUNT_BYTES(pwlen);
2463
2464         /* buffer format */
2465         CHECK_BYTE_COUNT(1);
2466         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2467         COUNT_BYTES(1);
2468
2469         /* Service */
2470         an = get_unicode_or_ascii_string(tvb, &offset,
2471                 pinfo, &an_len, FALSE, FALSE, &bc);
2472         if (an == NULL)
2473                 goto endofcommand;
2474         proto_tree_add_string(tree, hf_smb_service, tvb,
2475                 offset, an_len, an);
2476         COUNT_BYTES(an_len);
2477
2478         END_OF_SMB
2479
2480         return offset;
2481 }
2482
2483 static int
2484 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2485 {
2486         guint8 wc;
2487         guint16 bc;
2488
2489         WORD_COUNT;
2490  
2491         /* Maximum Buffer Size */
2492         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2493         offset += 2;
2494
2495         /* tid */
2496         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2497         offset += 2;
2498
2499         BYTE_COUNT;
2500
2501         END_OF_SMB
2502
2503         return offset;
2504 }
2505  
2506
2507 static const true_false_string tfs_of_create = {
2508         "Create file if it does not exist",
2509         "Fail if file does not exist"
2510 };
2511 static const value_string of_open[] = {
2512         { 0,            "Fail if file exists"},
2513         { 1,            "Open file if it exists"},
2514         { 2,            "Truncate file if it exists"},
2515         {0, NULL}
2516 };
2517 static int
2518 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2519 {
2520         guint16 mask;
2521         proto_item *item = NULL;
2522         proto_tree *tree = NULL;
2523
2524         mask = tvb_get_letohs(tvb, offset);
2525
2526         if(parent_tree){
2527                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2528                         "Open Function: 0x%04x", mask);
2529                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2530         }
2531
2532         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2533                 tvb, offset, 2, mask);
2534         proto_tree_add_uint(tree, hf_smb_open_function_open,
2535                 tvb, offset, 2, mask);
2536
2537         offset += 2;
2538
2539         return offset;
2540 }
2541
2542
2543 static const true_false_string tfs_mf_file = {
2544         "Target must be a file",
2545         "Target needn't be a file"
2546 };
2547 static const true_false_string tfs_mf_dir = {
2548         "Target must be a directory",
2549         "Target needn't be a directory"
2550 };
2551 static const true_false_string tfs_mf_verify = {
2552         "MUST verify all writes",
2553         "Don't have to verify writes"
2554 };
2555 static int
2556 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2557 {
2558         guint16 mask;
2559         proto_item *item = NULL;
2560         proto_tree *tree = NULL;
2561
2562         mask = tvb_get_letohs(tvb, offset);
2563
2564         if(parent_tree){
2565                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2566                         "Flags: 0x%04x", mask);
2567                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2568         }
2569  
2570         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2571                 tvb, offset, 2, mask);
2572         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2573                 tvb, offset, 2, mask);
2574         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2575                 tvb, offset, 2, mask);
2576
2577         offset += 2;
2578
2579         return offset;
2580 }
2581
2582 static const true_false_string tfs_cf_mode = {
2583         "ASCII",
2584         "Binary"
2585 };
2586 static const true_false_string tfs_cf_tree_copy = {
2587         "Copy is a tree copy",
2588         "Copy is a file copy"
2589 };
2590 static const true_false_string tfs_cf_ea_action = {
2591         "Fail copy",
2592         "Discard EAs"
2593 };
2594 static int
2595 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2596 {
2597         guint16 mask;
2598         proto_item *item = NULL;
2599         proto_tree *tree = NULL;
2600
2601         mask = tvb_get_letohs(tvb, offset);
2602
2603         if(parent_tree){
2604                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2605                         "Flags: 0x%04x", mask);
2606                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2607         }
2608  
2609         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2610                 tvb, offset, 2, mask);
2611         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2612                 tvb, offset, 2, mask);
2613         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2614                 tvb, offset, 2, mask);
2615         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2616                 tvb, offset, 2, mask);
2617         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2618                 tvb, offset, 2, mask);
2619         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2620                 tvb, offset, 2, mask);
2621         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2622                 tvb, offset, 2, mask);
2623
2624         offset += 2;
2625
2626         return offset;
2627 }
2628
2629 static int
2630 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2631 {
2632         int fn_len;
2633         guint16 tid;
2634         guint16 bc;
2635         guint8 wc;
2636         const char *fn;
2637
2638         WORD_COUNT;
2639
2640         /* tid */
2641         tid = tvb_get_letohs(tvb, offset);
2642         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2643                 "TID (target): 0x%04x", tid);
2644         offset += 2;
2645
2646         /* open function */
2647         offset = dissect_open_function(tvb, tree, offset);
2648
2649         /* move flags */
2650         offset = dissect_move_flags(tvb, tree, offset);
2651
2652         BYTE_COUNT;
2653
2654         /* buffer format */
2655         CHECK_BYTE_COUNT(1);
2656         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2657         COUNT_BYTES(1);
2658
2659         /* file name */
2660         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2661                 FALSE, FALSE, &bc);
2662         if (fn == NULL)
2663                 goto endofcommand;
2664         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2665                 fn_len, fn, "Old File Name: %s", fn);
2666         COUNT_BYTES(fn_len);
2667
2668         if (check_col(pinfo->cinfo, COL_INFO)) {
2669                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2670         }
2671
2672         /* buffer format */
2673         CHECK_BYTE_COUNT(1);
2674         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2675         COUNT_BYTES(1);
2676
2677         /* file name */
2678         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2679                 FALSE, FALSE, &bc);
2680         if (fn == NULL)
2681                 goto endofcommand;
2682         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2683                 fn_len, fn, "New File Name: %s", fn);
2684         COUNT_BYTES(fn_len);
2685
2686         if (check_col(pinfo->cinfo, COL_INFO)) {
2687                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2688         }
2689
2690         END_OF_SMB
2691
2692         return offset;
2693 }
2694
2695 static int
2696 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2697 {
2698         int fn_len;
2699         guint16 tid;
2700         guint16 bc;
2701         guint8 wc;
2702         const char *fn;
2703
2704         WORD_COUNT;
2705
2706         /* tid */
2707         tid = tvb_get_letohs(tvb, offset);
2708         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2709                 "TID (target): 0x%04x", tid);
2710         offset += 2;
2711
2712         /* open function */
2713         offset = dissect_open_function(tvb, tree, offset);
2714
2715         /* copy flags */
2716         offset = dissect_copy_flags(tvb, tree, offset);
2717
2718         BYTE_COUNT;
2719
2720         /* buffer format */
2721         CHECK_BYTE_COUNT(1);
2722         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2723         COUNT_BYTES(1);
2724
2725         /* file name */
2726         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2727                 FALSE, FALSE, &bc);
2728         if (fn == NULL)
2729                 goto endofcommand;
2730         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2731                 fn_len, fn, "Source File Name: %s", fn);
2732         COUNT_BYTES(fn_len);
2733
2734         if (check_col(pinfo->cinfo, COL_INFO)) {
2735                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2736         }
2737
2738         /* buffer format */
2739         CHECK_BYTE_COUNT(1);
2740         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2741         COUNT_BYTES(1);
2742
2743         /* file name */
2744         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2745                 FALSE, FALSE, &bc);
2746         if (fn == NULL)
2747                 goto endofcommand;
2748         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2749                 fn_len, fn, "Destination File Name: %s", fn);
2750         COUNT_BYTES(fn_len);
2751
2752         if (check_col(pinfo->cinfo, COL_INFO)) {
2753                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2754         }
2755
2756         END_OF_SMB
2757
2758         return offset;
2759 }
2760
2761 static int
2762 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2763 {
2764         int fn_len;
2765         const char *fn;
2766         guint8 wc;
2767         guint16 bc;
2768
2769         WORD_COUNT;
2770
2771         /* # of files moved */
2772         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2773         offset += 2;
2774
2775         BYTE_COUNT;
2776
2777         /* buffer format */
2778         CHECK_BYTE_COUNT(1);
2779         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2780         COUNT_BYTES(1);
2781
2782         /* file name */
2783         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2784                 FALSE, FALSE, &bc);
2785         if (fn == NULL)
2786                 goto endofcommand;
2787         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2788                 fn);
2789         COUNT_BYTES(fn_len);
2790
2791         END_OF_SMB
2792
2793         return offset;
2794 }
2795
2796 static int
2797 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2798 {
2799         int fn_len;
2800         const char *fn;
2801         guint8 wc;
2802         guint16 bc;
2803
2804         WORD_COUNT;
2805
2806         /* desired access */
2807         offset = dissect_access(tvb, tree, offset, "Desired");
2808
2809         /* Search Attributes */
2810         offset = dissect_search_attributes(tvb, tree, offset);
2811
2812         BYTE_COUNT;
2813
2814         /* buffer format */
2815         CHECK_BYTE_COUNT(1);
2816         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2817         COUNT_BYTES(1);
2818
2819         /* file name */
2820         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2821                 FALSE, FALSE, &bc);
2822         if (fn == NULL)
2823                 goto endofcommand;
2824         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2825                 fn);
2826         COUNT_BYTES(fn_len);
2827
2828         if (check_col(pinfo->cinfo, COL_INFO)) {
2829                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2830         }
2831
2832         END_OF_SMB
2833
2834         return offset;
2835 }
2836
2837 void
2838 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2839     int len, guint16 fid)
2840 {
2841         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2842         if (check_col(pinfo->cinfo, COL_INFO))
2843                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2844 }
2845
2846 static int
2847 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2848 {
2849         guint8 wc;
2850         guint16 bc;
2851         guint16 fid;
2852
2853         WORD_COUNT;
2854
2855         /* fid */
2856         fid = tvb_get_letohs(tvb, offset);
2857         add_fid(tvb, pinfo, tree, offset, 2, fid);
2858         offset += 2;
2859
2860         /* File Attributes */
2861         offset = dissect_file_attributes(tvb, tree, offset);
2862
2863         /* last write time */
2864         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2865         
2866         /* File Size */
2867         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2868         offset += 4;
2869
2870         /* granted access */
2871         offset = dissect_access(tvb, tree, offset, "Granted");
2872
2873         BYTE_COUNT;
2874
2875         END_OF_SMB
2876
2877         return offset;
2878 }
2879
2880 static int
2881 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2882 {
2883         guint8 wc;
2884         guint16 bc;
2885         guint16 fid;
2886
2887         WORD_COUNT;
2888
2889         /* fid */
2890         fid = tvb_get_letohs(tvb, offset);
2891         add_fid(tvb, pinfo, tree, offset, 2, fid);
2892         offset += 2;
2893
2894         BYTE_COUNT;
2895
2896         END_OF_SMB
2897
2898         return offset;
2899 }
2900
2901 static int
2902 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2903 {
2904         int fn_len;
2905         const char *fn;
2906         guint8 wc;
2907         guint16 bc;
2908
2909         WORD_COUNT;
2910
2911         /* file attributes */
2912         offset = dissect_file_attributes(tvb, tree, offset);
2913
2914         /* creation time */
2915         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2916
2917         BYTE_COUNT;
2918
2919         /* buffer format */
2920         CHECK_BYTE_COUNT(1);
2921         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2922         COUNT_BYTES(1);
2923
2924         /* File Name */
2925         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2926                 FALSE, FALSE, &bc);
2927         if (fn == NULL)
2928                 goto endofcommand;
2929         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2930                 fn);
2931         COUNT_BYTES(fn_len);
2932
2933         if (check_col(pinfo->cinfo, COL_INFO)) {
2934                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2935         }
2936
2937         END_OF_SMB
2938
2939         return offset;
2940 }
2941
2942 static int
2943 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2944 {
2945         guint8 wc;
2946         guint16 bc, fid;
2947
2948         WORD_COUNT;
2949
2950         /* fid */
2951         fid = tvb_get_letohs(tvb, offset);
2952         add_fid(tvb, pinfo, tree, offset, 2, fid);
2953         offset += 2;
2954
2955         /* last write time */
2956         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2957
2958         BYTE_COUNT;
2959
2960         END_OF_SMB
2961
2962         return offset;
2963 }
2964
2965 static int
2966 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2967 {
2968         int fn_len;
2969         const char *fn;
2970         guint8 wc;
2971         guint16 bc;
2972
2973         WORD_COUNT;
2974
2975         /* search attributes */
2976         offset = dissect_search_attributes(tvb, tree, offset);
2977
2978         BYTE_COUNT;
2979
2980         /* buffer format */
2981         CHECK_BYTE_COUNT(1);
2982         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2983         COUNT_BYTES(1);
2984
2985         /* file name */
2986         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2987                 FALSE, FALSE, &bc);
2988         if (fn == NULL)
2989                 goto endofcommand;
2990         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2991                 fn);
2992         COUNT_BYTES(fn_len);
2993
2994         if (check_col(pinfo->cinfo, COL_INFO)) {
2995                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2996         }
2997
2998         END_OF_SMB
2999
3000         return offset;
3001 }
3002
3003 static int
3004 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3005 {
3006         int fn_len;
3007         const char *fn;
3008         guint8 wc;
3009         guint16 bc;
3010
3011         WORD_COUNT;
3012
3013         /* search attributes */
3014         offset = dissect_search_attributes(tvb, tree, offset);
3015
3016         BYTE_COUNT;
3017
3018         /* buffer format */
3019         CHECK_BYTE_COUNT(1);
3020         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3021         COUNT_BYTES(1);
3022
3023         /* old file name */
3024         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3025                 FALSE, FALSE, &bc);
3026         if (fn == NULL)
3027                 goto endofcommand;
3028         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3029                 fn);
3030         COUNT_BYTES(fn_len);
3031
3032         if (check_col(pinfo->cinfo, COL_INFO)) {
3033                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3034         }
3035
3036         /* buffer format */
3037         CHECK_BYTE_COUNT(1);
3038         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3039         COUNT_BYTES(1);
3040
3041         /* file name */
3042         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3043                 FALSE, FALSE, &bc);
3044         if (fn == NULL)
3045                 goto endofcommand;
3046         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3047                 fn);
3048         COUNT_BYTES(fn_len);
3049
3050         if (check_col(pinfo->cinfo, COL_INFO)) {
3051                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3052         }
3053
3054         END_OF_SMB
3055
3056         return offset;
3057 }
3058
3059 static int
3060 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3061 {
3062         int fn_len;
3063         const char *fn;
3064         guint8 wc;
3065         guint16 bc;
3066
3067         WORD_COUNT;
3068
3069         /* search attributes */
3070         offset = dissect_search_attributes(tvb, tree, offset);
3071  
3072         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3073         offset += 2;
3074
3075         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3076         offset += 4;
3077
3078         BYTE_COUNT;
3079
3080         /* buffer format */
3081         CHECK_BYTE_COUNT(1);
3082         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3083         COUNT_BYTES(1);
3084
3085         /* old file name */
3086         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3087                 FALSE, FALSE, &bc);
3088         if (fn == NULL)
3089                 goto endofcommand;
3090         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3091                 fn);
3092         COUNT_BYTES(fn_len);
3093
3094         if (check_col(pinfo->cinfo, COL_INFO)) {
3095                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3096         }
3097
3098         /* buffer format */
3099         CHECK_BYTE_COUNT(1);
3100         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3101         COUNT_BYTES(1);
3102
3103         /* file name */
3104         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3105                 FALSE, FALSE, &bc);
3106         if (fn == NULL)
3107                 goto endofcommand;
3108         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3109                 fn);
3110         COUNT_BYTES(fn_len);
3111
3112         if (check_col(pinfo->cinfo, COL_INFO)) {
3113                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3114         }
3115
3116         END_OF_SMB
3117
3118         return offset;
3119 }
3120
3121
3122 static int
3123 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3124 {
3125         guint16 bc;
3126         guint8 wc;
3127         const char *fn;
3128         int fn_len;
3129
3130         WORD_COUNT;
3131
3132         BYTE_COUNT;
3133
3134         /* Buffer Format */
3135         CHECK_BYTE_COUNT(1);
3136         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3137         COUNT_BYTES(1);
3138
3139         /* File Name */
3140         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3141                 FALSE, FALSE, &bc);
3142         if (fn == NULL)
3143                 goto endofcommand;
3144         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3145                 fn);
3146         COUNT_BYTES(fn_len);
3147
3148         if (check_col(pinfo->cinfo, COL_INFO)) {
3149                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3150         }
3151
3152         END_OF_SMB
3153
3154         return offset;
3155 }
3156  
3157 static int
3158 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3159 {
3160         guint16 bc;
3161         guint8 wc;
3162
3163         WORD_COUNT;
3164
3165         /* File Attributes */
3166         offset = dissect_file_attributes(tvb, tree, offset);
3167
3168         /* Last Write Time */
3169         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3170
3171         /* File Size */
3172         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3173         offset += 4;
3174
3175         /* 10 reserved bytes */
3176         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3177         offset += 10;
3178
3179         BYTE_COUNT;
3180
3181         END_OF_SMB
3182
3183         return offset;
3184 }
3185
3186 static int
3187 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3188 {
3189         int fn_len;
3190         const char *fn;
3191         guint8 wc;
3192         guint16 bc;
3193
3194         WORD_COUNT;
3195
3196         /* file attributes */
3197         offset = dissect_file_attributes(tvb, tree, offset);
3198
3199         /* last write time */
3200         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3201
3202         /* 10 reserved bytes */
3203         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3204         offset += 10;
3205
3206         BYTE_COUNT;
3207
3208         /* buffer format */
3209         CHECK_BYTE_COUNT(1);
3210         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3211         COUNT_BYTES(1);
3212
3213         /* file name */
3214         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3215                 FALSE, FALSE, &bc);
3216         if (fn == NULL)
3217                 goto endofcommand;
3218         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3219                 fn);
3220         COUNT_BYTES(fn_len);
3221
3222         if (check_col(pinfo->cinfo, COL_INFO)) {
3223                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3224         }
3225
3226         END_OF_SMB
3227
3228         return offset;
3229 }
3230
3231 static int
3232 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3233 {
3234         guint8 wc;
3235         guint16 bc;
3236         smb_info_t *si;
3237         unsigned int fid;
3238
3239         WORD_COUNT;
3240
3241         /* fid */
3242         fid = tvb_get_letohs(tvb, offset);
3243         add_fid(tvb, pinfo, tree, offset, 2, fid);
3244         offset += 2;
3245         if (!pinfo->fd->flags.visited) {
3246                 /* remember the FID for the processing of the response */
3247                 si = (smb_info_t *)pinfo->private_data;
3248                 si->sip->extra_info=(void *)fid;
3249         }
3250
3251         /* read count */
3252         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3253         offset += 2;
3254
3255         /* offset */
3256         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3257         offset += 4;
3258
3259         /* remaining */
3260         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3261         offset += 2;
3262
3263         BYTE_COUNT;
3264
3265         END_OF_SMB
3266
3267         return offset;
3268 }
3269
3270 int
3271 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3272 {
3273         int tvblen;
3274
3275         if(bc>datalen){
3276                 /* We have some initial padding bytes. */
3277                 /* XXX - use the data offset here instead? */
3278                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3279                         TRUE);
3280                 offset += bc-datalen;
3281                 bc = datalen;
3282         }
3283         tvblen = tvb_length_remaining(tvb, offset);
3284         if(bc>tvblen){
3285                 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);
3286                 offset += tvblen;
3287         } else {
3288                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3289                 offset += bc;
3290         }
3291         return offset;
3292 }
3293
3294 static int
3295 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3296     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3297 {
3298         int tvblen;
3299         tvbuff_t *dcerpc_tvb;
3300
3301         if(bc>datalen){
3302                 /* We have some initial padding bytes. */
3303                 /* XXX - use the data offset here instead? */
3304                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3305                         TRUE);
3306                 offset += bc-datalen;
3307                 bc = datalen;
3308         }
3309         tvblen = tvb_length_remaining(tvb, offset);
3310         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3311         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3312         if(bc>tvblen)
3313                 offset += tvblen;
3314         else
3315                 offset += bc;
3316         return offset;
3317 }
3318
3319 static int
3320 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3321 {
3322         guint16 cnt=0, bc;
3323         guint8 wc;
3324         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3325         int fid=0;
3326
3327         WORD_COUNT;
3328
3329         /* read count */
3330         cnt = tvb_get_letohs(tvb, offset);
3331         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3332         offset += 2;
3333
3334         /* 8 reserved bytes */
3335         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3336         offset += 8;
3337
3338         /* If we have seen the request, then print which FID this refers to */
3339         /* first check if we have seen the request */
3340         if(si->sip != NULL && si->sip->frame_req>0){
3341                 fid=(int)si->sip->extra_info;
3342                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3343         }
3344
3345         BYTE_COUNT;
3346
3347         /* buffer format */
3348         CHECK_BYTE_COUNT(1);
3349         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3350         COUNT_BYTES(1);
3351
3352         /* data len */
3353         CHECK_BYTE_COUNT(2);
3354         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3355         COUNT_BYTES(2);
3356
3357         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3358            read write */
3359         if(bc){
3360                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3361                         /* dcerpc call */
3362                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3363                             top_tree, offset, bc, bc, fid);
3364                 } else {
3365                         /* ordinary file data, or we didn't see the request,
3366                            so we don't know whether this is a DCERPC call
3367                            or not */
3368                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3369                 }
3370                 bc = 0;
3371         }
3372
3373         END_OF_SMB
3374
3375         return offset;
3376 }
3377
3378 static int
3379 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3380 {
3381         guint16 cnt, bc;
3382         guint8 wc;
3383
3384         WORD_COUNT;
3385
3386         /* read count */
3387         cnt = tvb_get_letohs(tvb, offset);
3388         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3389         offset += 2;
3390
3391         /* 8 reserved bytes */
3392         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3393         offset += 8;
3394
3395         BYTE_COUNT;
3396
3397         /* buffer format */
3398         CHECK_BYTE_COUNT(1);
3399         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3400         COUNT_BYTES(1);
3401
3402         /* data len */
3403         CHECK_BYTE_COUNT(2);
3404         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3405         COUNT_BYTES(2);
3406
3407         END_OF_SMB
3408
3409         return offset;
3410 }
3411
3412
3413 static int
3414 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3415 {
3416         guint32 ofs=0;
3417         guint16 cnt=0, bc, fid=0;
3418         guint8 wc;
3419         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3420
3421         WORD_COUNT;
3422
3423         /* fid */
3424         fid = tvb_get_letohs(tvb, offset);
3425         add_fid(tvb, pinfo, tree, offset, 2, fid);
3426         offset += 2;
3427
3428         /* write count */
3429         cnt = tvb_get_letohs(tvb, offset);
3430         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3431         offset += 2;
3432
3433         /* offset */
3434         ofs = tvb_get_letohl(tvb, offset);
3435         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3436         offset += 4;
3437
3438         if (check_col(pinfo->cinfo, COL_INFO))
3439                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3440                                 ", %u byte%s at offset %u", cnt, 
3441                                 (cnt == 1) ? "" : "s", ofs);
3442
3443         /* remaining */
3444         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3445         offset += 2;
3446
3447         BYTE_COUNT;
3448
3449         /* buffer format */
3450         CHECK_BYTE_COUNT(1);
3451         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3452         COUNT_BYTES(1);
3453
3454         /* data len */
3455         CHECK_BYTE_COUNT(2);
3456         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3457         COUNT_BYTES(2);
3458
3459         if (bc != 0) {
3460                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3461                         /* dcerpc call */
3462                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3463                             top_tree, offset, bc, bc, fid);
3464                 } else {
3465                         /* ordinary file data */
3466                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3467                 }
3468                 bc = 0;
3469         }
3470
3471         END_OF_SMB
3472
3473         return offset;
3474 }
3475  
3476 static int
3477 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3478 {
3479         guint8 wc;
3480         guint16 bc, cnt;
3481
3482         WORD_COUNT;
3483
3484         /* write count */
3485         cnt = tvb_get_letohs(tvb, offset);
3486         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3487         offset += 2;
3488
3489         if (check_col(pinfo->cinfo, COL_INFO))
3490                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3491                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3492
3493         BYTE_COUNT;
3494
3495         END_OF_SMB
3496
3497         return offset;
3498 }
3499
3500 static int
3501 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3502 {
3503         guint8 wc;
3504         guint16 bc, fid;
3505
3506         WORD_COUNT;
3507
3508         /* fid */
3509         fid = tvb_get_letohs(tvb, offset);
3510         add_fid(tvb, pinfo, tree, offset, 2, fid);
3511         offset += 2;
3512
3513         /* lock count */
3514         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3515         offset += 4;
3516
3517         /* offset */
3518         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3519         offset += 4;
3520
3521         BYTE_COUNT;
3522
3523         END_OF_SMB
3524
3525         return offset;
3526 }
3527
3528 static int
3529 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3530 {
3531         int fn_len;
3532         const char *fn;
3533         guint8 wc;
3534         guint16 bc;
3535
3536         WORD_COUNT;
3537
3538         /* 2 reserved bytes */
3539         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3540         offset += 2;
3541
3542         /* Creation time */
3543         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3544
3545         BYTE_COUNT;
3546
3547         /* buffer format */
3548         CHECK_BYTE_COUNT(1);
3549         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3550         COUNT_BYTES(1);
3551
3552         /* directory name */
3553         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3554                 FALSE, FALSE, &bc);
3555         if (fn == NULL)
3556                 goto endofcommand;
3557         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3558                 fn);
3559         COUNT_BYTES(fn_len);
3560
3561         if (check_col(pinfo->cinfo, COL_INFO)) {
3562                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3563         }
3564
3565         END_OF_SMB
3566
3567         return offset;
3568 }
3569
3570 static int
3571 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3572 {
3573         int fn_len;
3574         const char *fn;
3575         guint8 wc;
3576         guint16 bc, fid;
3577
3578         WORD_COUNT;
3579
3580         /* fid */
3581         fid = tvb_get_letohs(tvb, offset);
3582         add_fid(tvb, pinfo, tree, offset, 2, fid);
3583         offset += 2;
3584
3585         BYTE_COUNT;
3586
3587         /* buffer format */
3588         CHECK_BYTE_COUNT(1);
3589         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3590         COUNT_BYTES(1);
3591
3592         /* file name */
3593         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3594                 FALSE, FALSE, &bc);
3595         if (fn == NULL)
3596                 goto endofcommand;
3597         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3598                 fn);
3599         COUNT_BYTES(fn_len);
3600
3601         END_OF_SMB
3602
3603         return offset;
3604 }
3605
3606 static const value_string seek_mode_vals[] = {
3607         {0,     "From Start Of File"},
3608         {1,     "From Current Position"},
3609         {2,     "From End Of File"},
3610         {0,     NULL}
3611 };
3612
3613 static int
3614 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3615 {
3616         guint8 wc;
3617         guint16 bc, fid;
3618
3619         WORD_COUNT;
3620
3621         /* fid */
3622         fid = tvb_get_letohs(tvb, offset);
3623         add_fid(tvb, pinfo, tree, offset, 2, fid);
3624         offset += 2;
3625
3626         /* Seek Mode */
3627         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3628         offset += 2;
3629
3630         /* offset */
3631         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3632         offset += 4;
3633
3634         BYTE_COUNT;
3635
3636         END_OF_SMB
3637
3638         return offset;
3639 }
3640
3641 static int
3642 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3643 {
3644         guint8 wc;
3645         guint16 bc;
3646
3647         WORD_COUNT;
3648
3649         /* offset */
3650         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3651         offset += 4;
3652
3653         BYTE_COUNT;
3654
3655         END_OF_SMB
3656
3657         return offset;
3658 }
3659  
3660 static int
3661 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3662 {
3663         guint8 wc;
3664         guint16 bc, fid;
3665
3666         WORD_COUNT;
3667
3668         /* fid */
3669         fid = tvb_get_letohs(tvb, offset);
3670         add_fid(tvb, pinfo, tree, offset, 2, fid);
3671         offset += 2;
3672
3673         /* create time */
3674         offset = dissect_smb_datetime(tvb, tree, offset,
3675                 hf_smb_create_time,
3676                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3677
3678         /* access time */
3679         offset = dissect_smb_datetime(tvb, tree, offset,
3680                 hf_smb_access_time,
3681                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3682
3683         /* last write time */
3684         offset = dissect_smb_datetime(tvb, tree, offset,
3685                 hf_smb_last_write_time,
3686                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3687
3688         BYTE_COUNT;
3689
3690         END_OF_SMB
3691
3692         return offset;
3693 }
3694
3695 static int
3696 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3697 {
3698         guint8 wc;
3699         guint16 bc;
3700
3701         WORD_COUNT;
3702
3703         /* create time */
3704         offset = dissect_smb_datetime(tvb, tree, offset,
3705                 hf_smb_create_time,
3706                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3707
3708         /* access time */
3709         offset = dissect_smb_datetime(tvb, tree, offset,
3710                 hf_smb_access_time,
3711                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3712
3713         /* last write time */
3714         offset = dissect_smb_datetime(tvb, tree, offset,
3715                 hf_smb_last_write_time,
3716                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3717
3718         /* data size */
3719         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3720         offset += 4;
3721
3722         /* allocation size */
3723         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3724         offset += 4;
3725
3726         /* File Attributes */
3727         offset = dissect_file_attributes(tvb, tree, offset);
3728
3729         BYTE_COUNT;
3730
3731         END_OF_SMB
3732
3733         return offset;
3734 }
3735
3736 static int
3737 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3738 {
3739         guint8 wc;
3740         guint16 cnt=0;
3741         guint16 bc, fid;
3742
3743         WORD_COUNT;
3744
3745         /* fid */
3746         fid = tvb_get_letohs(tvb, offset);
3747         add_fid(tvb, pinfo, tree, offset, 2, fid);
3748         offset += 2;
3749
3750         /* write count */
3751         cnt = tvb_get_letohs(tvb, offset);
3752         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3753         offset += 2;
3754
3755         /* offset */
3756         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3757         offset += 4;
3758
3759         /* last write time */
3760         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3761         
3762         if(wc==12){
3763                 /* 12 reserved bytes */
3764                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3765                 offset += 12;
3766         }
3767
3768         BYTE_COUNT;
3769
3770         /* 1 pad byte */
3771         CHECK_BYTE_COUNT(1);
3772         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3773         COUNT_BYTES(1);
3774         
3775         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3776         bc = 0; /* XXX */
3777
3778         END_OF_SMB
3779
3780         return offset;
3781 }
3782  
3783 static int
3784 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3785 {
3786         guint8 wc;
3787         guint16 bc;
3788
3789         WORD_COUNT;
3790
3791         /* write count */
3792         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3793         offset += 2;
3794
3795         BYTE_COUNT;
3796
3797         END_OF_SMB
3798
3799         return offset;
3800 }
3801
3802 static int
3803 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3804 {
3805         guint8 wc;
3806         guint16 bc, fid;
3807         guint32 to;
3808
3809         WORD_COUNT;
3810
3811         /* fid */
3812         fid = tvb_get_letohs(tvb, offset);
3813         add_fid(tvb, pinfo, tree, offset, 2, fid);
3814         offset += 2;
3815
3816         /* offset */
3817         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3818         offset += 4;
3819
3820         /* max count */
3821         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3822         offset += 2;
3823
3824         /* min count */
3825         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3826         offset += 2;
3827
3828         /* timeout */
3829         to = tvb_get_letohl(tvb, offset);
3830         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3831         offset += 4;
3832
3833         /* 2 reserved bytes */
3834         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3835         offset += 2;
3836
3837         if(wc==10){
3838                 /* high offset */
3839                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3840                 offset += 4;
3841         }
3842
3843         BYTE_COUNT;
3844
3845         END_OF_SMB
3846
3847         return offset;
3848 }
3849
3850 static int
3851 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3852 {
3853         guint8 wc;
3854         guint16 bc;
3855
3856         WORD_COUNT;
3857
3858         /* units */
3859         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3860         offset += 2;
3861
3862         /* bpu */
3863         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3864         offset += 2;
3865
3866         /* block size */
3867         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3868         offset += 2;
3869
3870         /* free units */
3871         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3872         offset += 2;
3873
3874         /* 2 reserved bytes */
3875         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3876         offset += 2;
3877
3878         BYTE_COUNT;
3879
3880         END_OF_SMB
3881
3882         return offset;
3883 }
3884
3885 static int
3886 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3887 {
3888         guint8 wc;
3889         guint16 bc, fid;
3890
3891         WORD_COUNT;
3892
3893         /* fid */
3894         fid = tvb_get_letohs(tvb, offset);
3895         add_fid(tvb, pinfo, tree, offset, 2, fid);
3896         offset += 2;
3897
3898         /* offset */
3899         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3900         offset += 4;
3901
3902         /* max count */
3903         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3904         offset += 2;
3905
3906         /* min count */
3907         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3908         offset += 2;
3909
3910         /* 6 reserved bytes */
3911         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3912         offset += 6;
3913
3914         BYTE_COUNT;
3915
3916         END_OF_SMB
3917
3918         return offset;
3919 }
3920
3921 static int
3922 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3923 {
3924         guint16 datalen=0, bc;
3925         guint8 wc;
3926
3927         WORD_COUNT;
3928
3929         /* offset */
3930         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3931         offset += 4;
3932
3933         /* count */
3934         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3935         offset += 2;
3936
3937         /* 2 reserved bytes */
3938         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3939         offset += 2;
3940
3941         /* data compaction mode */
3942         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3943         offset += 2;
3944
3945         /* 2 reserved bytes */
3946         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3947         offset += 2;
3948
3949         /* data len */
3950         datalen = tvb_get_letohs(tvb, offset);
3951         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3952         offset += 2;
3953
3954         /* data offset */
3955         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3956         offset += 2;
3957
3958         BYTE_COUNT;
3959
3960         /* file data */
3961         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
3962         bc = 0;
3963
3964         END_OF_SMB
3965
3966         return offset;
3967 }
3968
3969
3970 static const true_false_string tfs_write_mode_write_through = {
3971         "WRITE THROUGH requested",
3972         "Write through not requested"
3973 };
3974 static const true_false_string tfs_write_mode_return_remaining = {
3975         "RETURN REMAINING (pipe/dev) requested",
3976         "DON'T return remaining (pipe/dev)"
3977 };
3978 static const true_false_string tfs_write_mode_raw = {
3979         "Use WriteRawNamedPipe (pipe)",
3980         "DON'T use WriteRawNamedPipe (pipe)"
3981 };
3982 static const true_false_string tfs_write_mode_message_start = {
3983         "This is the START of a MESSAGE (pipe)",
3984         "This is NOT the start of a message (pipe)"
3985 };
3986 static const true_false_string tfs_write_mode_connectionless = {
3987         "CONNECTIONLESS mode requested",
3988         "Connectionless mode NOT requested"
3989 };
3990 static int
3991 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
3992 {
3993         guint16 mask;
3994         proto_item *item = NULL;
3995         proto_tree *tree = NULL;
3996
3997         mask = tvb_get_letohs(tvb, offset);
3998
3999         if(parent_tree){
4000                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4001                         "Write Mode: 0x%04x", mask);
4002                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4003         }
4004
4005         if(bm&0x0080){
4006                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4007                         tvb, offset, 2, mask);
4008         }
4009         if(bm&0x0008){
4010                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4011                         tvb, offset, 2, mask);
4012         }
4013         if(bm&0x0004){
4014                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4015                         tvb, offset, 2, mask);
4016         }
4017         if(bm&0x0002){
4018                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4019                         tvb, offset, 2, mask);
4020         }
4021         if(bm&0x0001){
4022                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4023                         tvb, offset, 2, mask);
4024         }
4025
4026         offset += 2;
4027         return offset;
4028 }
4029
4030 static int
4031 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4032 {
4033         guint32 to;
4034         guint16 datalen=0, bc, fid;
4035         guint8 wc;
4036
4037         WORD_COUNT;
4038
4039         /* fid */
4040         fid = tvb_get_letohs(tvb, offset);
4041         add_fid(tvb, pinfo, tree, offset, 2, fid);
4042         offset += 2;
4043
4044         /* total data length */
4045         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4046         offset += 2;
4047
4048         /* 2 reserved bytes */
4049         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4050         offset += 2;
4051
4052         /* offset */
4053         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4054         offset += 4;
4055
4056         /* timeout */
4057         to = tvb_get_letohl(tvb, offset);
4058         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4059         offset += 4;
4060
4061         /* mode */
4062         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4063
4064         /* 4 reserved bytes */
4065         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4066         offset += 4;
4067
4068         /* data len */
4069         datalen = tvb_get_letohs(tvb, offset);
4070         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4071         offset += 2;
4072
4073         /* data offset */
4074         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4075         offset += 2;
4076
4077         BYTE_COUNT;
4078
4079         /* file data */
4080         /* XXX - use the data offset to determine where the data starts? */
4081         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4082         bc = 0;
4083
4084         END_OF_SMB
4085
4086         return offset;
4087 }
4088  
4089 static int
4090 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4091 {
4092         guint8 wc;
4093         guint16 bc;
4094
4095         WORD_COUNT;
4096
4097         /* remaining */
4098         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4099         offset += 2;
4100
4101         BYTE_COUNT;
4102
4103         END_OF_SMB
4104
4105         return offset;
4106 }
4107
4108 static int
4109 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4110 {
4111         guint32 to;
4112         guint16 datalen=0, bc, fid;
4113         guint8 wc;
4114
4115         WORD_COUNT;
4116
4117         /* fid */
4118         fid = tvb_get_letohs(tvb, offset);
4119         add_fid(tvb, pinfo, tree, offset, 2, fid);
4120         offset += 2;
4121
4122         /* total data length */
4123         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4124         offset += 2;
4125
4126         /* 2 reserved bytes */
4127         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4128         offset += 2;
4129
4130         /* offset */
4131         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4132         offset += 4;
4133
4134         /* timeout */
4135         to = tvb_get_letohl(tvb, offset);
4136         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4137         offset += 4;
4138
4139         /* mode */
4140         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4141
4142         /* request mask */
4143         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4144         offset += 4;
4145         
4146         /* data len */
4147         datalen = tvb_get_letohs(tvb, offset);
4148         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4149         offset += 2;
4150
4151         /* data offset */
4152         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4153         offset += 2;
4154
4155         BYTE_COUNT;
4156
4157         /* file data */
4158         /* XXX - use the data offset to determine where the data starts? */
4159         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4160         bc = 0;
4161
4162         END_OF_SMB
4163
4164         return offset;
4165 }
4166  
4167 static int
4168 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4169 {
4170         guint8 wc;
4171         guint16 bc;
4172
4173         WORD_COUNT;
4174
4175         /* response mask */
4176         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4177         offset += 4;
4178         
4179         BYTE_COUNT;
4180
4181         END_OF_SMB
4182
4183         return offset;
4184 }
4185
4186 static int
4187 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4188 {
4189         guint8 wc;
4190         guint16 bc;
4191
4192         WORD_COUNT;
4193
4194         /* sid */
4195         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
4196         offset += 2;
4197
4198         BYTE_COUNT;
4199
4200         END_OF_SMB
4201
4202         return offset;
4203 }
4204
4205 static int
4206 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4207     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4208     gboolean has_find_id)
4209 {
4210         proto_item *item = NULL;
4211         proto_tree *tree = NULL;
4212         int fn_len;
4213         const char *fn;
4214         char fname[11+1];
4215
4216         if(parent_tree){
4217                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4218                         "Resume Key");
4219                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4220         }
4221
4222         /* reserved byte */
4223         CHECK_BYTE_COUNT_SUBR(1);
4224         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4225         COUNT_BYTES_SUBR(1);
4226
4227         /* file name */
4228         fn_len = 11;
4229         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4230                 TRUE, TRUE, bcp);
4231         CHECK_STRING_SUBR(fn);
4232         /* ensure that it's null-terminated */
4233         strncpy(fname, fn, 11);
4234         fname[11] = '\0';
4235         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4236                 fname);
4237         COUNT_BYTES_SUBR(fn_len);
4238
4239         if (has_find_id) {
4240                 CHECK_BYTE_COUNT_SUBR(1);
4241                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4242                 COUNT_BYTES_SUBR(1);
4243
4244                 /* server cookie */
4245                 CHECK_BYTE_COUNT_SUBR(4);
4246                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4247                 COUNT_BYTES_SUBR(4);
4248         } else {
4249                 /* server cookie */
4250                 CHECK_BYTE_COUNT_SUBR(5);
4251                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4252                 COUNT_BYTES_SUBR(5);
4253         }
4254
4255         /* client cookie */
4256         CHECK_BYTE_COUNT_SUBR(4);
4257         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4258         COUNT_BYTES_SUBR(4);
4259
4260         *trunc = FALSE;
4261         return offset;
4262 }
4263
4264 static int
4265 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4266     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4267     gboolean has_find_id)
4268 {
4269         proto_item *item = NULL;
4270         proto_tree *tree = NULL;
4271         int fn_len;
4272         const char *fn;
4273         char fname[13+1];
4274
4275         if(parent_tree){
4276                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4277                         "Directory Information");
4278                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4279         }
4280
4281         /* resume key */
4282         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4283             trunc, has_find_id);
4284         if (*trunc)
4285                 return offset;
4286
4287         /* File Attributes */
4288         CHECK_BYTE_COUNT_SUBR(1);
4289         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4290         *bcp -= 1;
4291
4292         /* last write time */
4293         CHECK_BYTE_COUNT_SUBR(4);
4294         offset = dissect_smb_datetime(tvb, tree, offset,
4295                 hf_smb_last_write_time,
4296                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4297                 TRUE);
4298         *bcp -= 4;
4299
4300         /* File Size */
4301         CHECK_BYTE_COUNT_SUBR(4);
4302         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4303         COUNT_BYTES_SUBR(4);
4304
4305         /* file name */
4306         fn_len = 13;
4307         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4308                 TRUE, TRUE, bcp);
4309         CHECK_STRING_SUBR(fn);
4310         /* ensure that it's null-terminated */
4311         strncpy(fname, fn, 13);
4312         fname[13] = '\0';
4313         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4314                 fname);
4315         COUNT_BYTES_SUBR(fn_len);
4316
4317         *trunc = FALSE;
4318         return offset;
4319 }
4320
4321
4322 static int
4323 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4324     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4325     gboolean has_find_id)
4326 {
4327         int fn_len;
4328         const char *fn;
4329         guint16 rkl;
4330         guint8 wc;
4331         guint16 bc;
4332         gboolean trunc;
4333
4334         WORD_COUNT;
4335
4336         /* max count */
4337         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4338         offset += 2;
4339
4340         /* Search Attributes */
4341         offset = dissect_search_attributes(tvb, tree, offset);
4342
4343         BYTE_COUNT;
4344
4345         /* buffer format */
4346         CHECK_BYTE_COUNT(1);
4347         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4348         COUNT_BYTES(1);
4349
4350         /* file name */
4351         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4352                 TRUE, FALSE, &bc);
4353         if (fn == NULL)
4354                 goto endofcommand;
4355         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4356                 fn);
4357         COUNT_BYTES(fn_len);
4358
4359         if (check_col(pinfo->cinfo, COL_INFO)) {
4360                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4361         }
4362
4363         /* buffer format */
4364         CHECK_BYTE_COUNT(1);
4365         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4366         COUNT_BYTES(1);
4367
4368         /* resume key length */
4369         CHECK_BYTE_COUNT(2);
4370         rkl = tvb_get_letohs(tvb, offset);
4371         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4372         COUNT_BYTES(2);
4373
4374         /* resume key */
4375         if(rkl){
4376                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4377                     &bc, &trunc, has_find_id);
4378                 if (trunc)
4379                         goto endofcommand;
4380         }
4381
4382         END_OF_SMB
4383
4384         return offset;
4385 }
4386
4387 static int
4388 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4389     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4390 {
4391         return dissect_search_find_request(tvb, pinfo, tree, offset,
4392             smb_tree, FALSE);
4393 }
4394
4395 static int
4396 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4397     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4398 {
4399         return dissect_search_find_request(tvb, pinfo, tree, offset,
4400             smb_tree, TRUE);
4401 }
4402
4403 static int
4404 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4405     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4406 {
4407         return dissect_search_find_request(tvb, pinfo, tree, offset,
4408             smb_tree, TRUE);
4409 }
4410
4411 static int
4412 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4413     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4414     gboolean has_find_id)
4415 {
4416         guint16 count=0;
4417         guint8 wc;
4418         guint16 bc;
4419         gboolean trunc;
4420
4421         WORD_COUNT;
4422
4423         /* count */
4424         count = tvb_get_letohs(tvb, offset);
4425         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4426         offset += 2;
4427
4428         BYTE_COUNT;
4429
4430         /* buffer format */
4431         CHECK_BYTE_COUNT(1);
4432         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4433         COUNT_BYTES(1);
4434
4435         /* data len */
4436         CHECK_BYTE_COUNT(2);
4437         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4438         COUNT_BYTES(2);
4439
4440         while(count--){
4441                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4442                     &bc, &trunc, has_find_id);
4443                 if (trunc)
4444                         goto endofcommand;
4445         }
4446
4447         END_OF_SMB
4448
4449         return offset;
4450 }
4451
4452 static int
4453 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4454 {
4455         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4456             FALSE);
4457 }
4458
4459 static int
4460 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4461 {
4462         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4463             TRUE);
4464 }
4465
4466 static int
4467 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4468     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4469 {
4470         guint8 wc;
4471         guint16 bc;
4472         guint16 data_len;
4473
4474         WORD_COUNT;
4475
4476         /* reserved */
4477         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4478         offset += 2;
4479
4480         BYTE_COUNT;
4481
4482         /* buffer format */
4483         CHECK_BYTE_COUNT(1);
4484         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4485         COUNT_BYTES(1);
4486
4487         /* data len */
4488         CHECK_BYTE_COUNT(2);
4489         data_len = tvb_get_ntohs(tvb, offset);
4490         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4491         COUNT_BYTES(2);
4492
4493         if (data_len != 0) {
4494                 CHECK_BYTE_COUNT(data_len);
4495                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4496                     data_len, TRUE);
4497                 COUNT_BYTES(data_len);
4498         }
4499
4500         END_OF_SMB
4501
4502         return offset;
4503 }
4504
4505 static const value_string locking_ol_vals[] = {
4506         {0,     "Client is not holding oplock on this file"},
4507         {1,     "Level 2 oplock currently held by client"},
4508         {0, NULL}
4509 };
4510
4511 static const true_false_string tfs_lock_type_large = {
4512         "Large file locking format requested",
4513         "Large file locking format not requested"
4514 };
4515 static const true_false_string tfs_lock_type_cancel = {
4516         "Cancel outstanding lock request",
4517         "Don't cancel outstanding lock request"
4518 };
4519 static const true_false_string tfs_lock_type_change = {
4520         "Change lock type",
4521         "Don't change lock type"
4522 };
4523 static const true_false_string tfs_lock_type_oplock = {
4524         "This is an oplock break notification/response",
4525         "This is not an oplock break notification/response"
4526 };
4527 static const true_false_string tfs_lock_type_shared = {
4528         "This is a shared lock",
4529         "This is an exclusive lock"
4530 };
4531 static int
4532 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4533 {
4534         guint8  wc, cmd=0xff, lt=0;
4535         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4536         guint32 to;
4537         proto_item *litem = NULL;
4538         proto_tree *ltree = NULL;
4539         proto_item *it = NULL;
4540         proto_tree *tr = NULL;
4541         int old_offset = offset;
4542
4543         WORD_COUNT;
4544
4545         /* next smb command */
4546         cmd = tvb_get_guint8(tvb, offset);
4547         if(cmd!=0xff){
4548                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4549         } else {
4550                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4551         }
4552         offset += 1;
4553
4554         /* reserved byte */
4555         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4556         offset += 1;
4557
4558         /* andxoffset */
4559         andxoffset = tvb_get_letohs(tvb, offset);
4560         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4561         offset += 2;
4562
4563         /* fid */
4564         fid = tvb_get_letohs(tvb, offset);
4565         add_fid(tvb, pinfo, tree, offset, 2, fid);
4566         offset += 2;
4567
4568         /* lock type */
4569         lt = tvb_get_guint8(tvb, offset);
4570         if(tree){
4571                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4572                         "Lock Type: 0x%02x", lt);
4573                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4574         }
4575         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4576                 tvb, offset, 1, lt);
4577         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4578                 tvb, offset, 1, lt);
4579         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4580                 tvb, offset, 1, lt);
4581         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4582                 tvb, offset, 1, lt);
4583         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4584                 tvb, offset, 1, lt);
4585         offset += 1;
4586
4587         /* oplock level */
4588         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4589         offset += 1;
4590
4591         /* timeout */
4592         to = tvb_get_letohl(tvb, offset);
4593         if (to == 0)
4594                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4595         else if (to == 0xffffffff)
4596                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4597         else
4598                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4599         offset += 4;
4600
4601         /* number of unlocks */
4602         un = tvb_get_letohs(tvb, offset);
4603         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4604         offset += 2;
4605
4606         /* number of locks */
4607         ln = tvb_get_letohs(tvb, offset);
4608         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4609         offset += 2;
4610
4611         BYTE_COUNT;
4612
4613         /* unlocks */
4614         if(un){
4615                 old_offset = offset;
4616
4617                 it = proto_tree_add_text(tree, tvb, offset, -1,
4618                         "Unlocks");
4619                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4620                 while(un--){
4621                         proto_item *litem = NULL;
4622                         proto_tree *ltree = NULL;
4623                         if(lt&0x10){
4624                                 /* large lock format */
4625                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4626                                         "Unlock");
4627                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4628                                 
4629                                 /* PID */
4630                                 CHECK_BYTE_COUNT(2);
4631                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4632                                 COUNT_BYTES(2);
4633
4634                                 /* 2 reserved bytes */
4635                                 CHECK_BYTE_COUNT(2);
4636                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4637                                 COUNT_BYTES(2);
4638
4639                                 /* offset */
4640                                 CHECK_BYTE_COUNT(8);
4641                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4642                                 COUNT_BYTES(8);
4643
4644                                 /* length */
4645                                 CHECK_BYTE_COUNT(8);
4646                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4647                                 COUNT_BYTES(8);
4648                         } else {
4649                                 /* normal lock format */
4650                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4651                                         "Unlock");
4652                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4653                                 
4654                                 /* PID */
4655                                 CHECK_BYTE_COUNT(2);
4656                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4657                                 COUNT_BYTES(2);
4658
4659                                 /* offset */
4660                                 CHECK_BYTE_COUNT(4);
4661                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4662                                 COUNT_BYTES(4);
4663
4664                                 /* lock count */
4665                                 CHECK_BYTE_COUNT(4);
4666                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4667                                 COUNT_BYTES(4);
4668                         }
4669                 }
4670                 proto_item_set_len(it, offset-old_offset);
4671                 it = NULL;
4672         }
4673
4674         /* locks */
4675         if(ln){
4676                 old_offset = offset;
4677
4678                 it = proto_tree_add_text(tree, tvb, offset, -1,
4679                         "Locks");
4680                 tr = proto_item_add_subtree(it, ett_smb_locks);
4681                 while(ln--){
4682                         proto_item *litem = NULL;
4683                         proto_tree *ltree = NULL;
4684                         if(lt&0x10){
4685                                 /* large lock format */
4686                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4687                                         "Lock");
4688                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4689                                 
4690                                 /* PID */
4691                                 CHECK_BYTE_COUNT(2);
4692                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4693                                 COUNT_BYTES(2);
4694
4695                                 /* 2 reserved bytes */
4696                                 CHECK_BYTE_COUNT(2);
4697                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4698                                 COUNT_BYTES(2);
4699
4700                                 /* offset */
4701                                 CHECK_BYTE_COUNT(8);
4702                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4703                                 COUNT_BYTES(8);
4704
4705                                 /* length */
4706                                 CHECK_BYTE_COUNT(8);
4707                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4708                                 COUNT_BYTES(8);
4709                         } else {
4710                                 /* normal lock format */
4711                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4712                                         "Unlock");
4713                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4714                                 
4715                                 /* PID */
4716                                 CHECK_BYTE_COUNT(2);
4717                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4718                                 COUNT_BYTES(2);
4719
4720                                 /* offset */
4721                                 CHECK_BYTE_COUNT(4);
4722                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4723                                 COUNT_BYTES(4);
4724
4725                                 /* lock count */
4726                                 CHECK_BYTE_COUNT(4);
4727                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4728                                 COUNT_BYTES(4);
4729                         }
4730                 }
4731                 proto_item_set_len(it, offset-old_offset);
4732                 it = NULL;
4733         }
4734
4735         END_OF_SMB
4736
4737         if (it != NULL) {
4738                 /*
4739                  * We ran out of byte count in the middle of dissecting
4740                  * the locks or the unlocks; set the site of the item
4741                  * we were dissecting.
4742                  */
4743                 proto_item_set_len(it, offset-old_offset);
4744         }
4745
4746         /* call AndXCommand (if there are any) */
4747         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4748
4749         return offset;
4750 }
4751
4752 static int
4753 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4754 {
4755         guint8  wc, cmd=0xff;
4756         guint16 andxoffset=0;
4757         guint16 bc;
4758
4759         WORD_COUNT;
4760
4761         /* next smb command */
4762         cmd = tvb_get_guint8(tvb, offset);
4763         if(cmd!=0xff){
4764                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4765         } else {
4766                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4767         }
4768         offset += 1;
4769
4770         /* reserved byte */
4771         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4772         offset += 1;
4773
4774         /* andxoffset */
4775         andxoffset = tvb_get_letohs(tvb, offset);
4776         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4777         offset += 2;
4778
4779         BYTE_COUNT;
4780
4781         END_OF_SMB
4782
4783         /* call AndXCommand (if there are any) */
4784         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4785
4786         return offset;
4787 }
4788
4789
4790 static const value_string oa_open_vals[] = {
4791         { 0,            "No action taken?"},
4792         { 1,            "The file existed and was opened"},
4793         { 2,            "The file did not exist but was created"},
4794         { 3,            "The file existed and was truncated"},
4795         {0,     NULL}
4796 };
4797 static const true_false_string tfs_oa_lock = {
4798         "File is currently opened only by this user",
4799         "File is opened by another user (or mode not supported by server)"
4800 };
4801 static int
4802 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4803 {
4804         guint16 mask;
4805         proto_item *item = NULL;
4806         proto_tree *tree = NULL;
4807
4808         mask = tvb_get_letohs(tvb, offset);
4809
4810         if(parent_tree){
4811                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4812                         "Action: 0x%04x", mask);
4813                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4814         }
4815
4816         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4817                 tvb, offset, 2, mask);
4818         proto_tree_add_uint(tree, hf_smb_open_action_open,
4819                 tvb, offset, 2, mask);
4820
4821         offset += 2;
4822
4823         return offset;
4824 }
4825
4826 static const true_false_string tfs_open_flags_add_info = {
4827         "Additional information requested",
4828         "Additional information not requested"
4829 };
4830 static const true_false_string tfs_open_flags_ex_oplock = {
4831         "Exclusive oplock requested",
4832         "Exclusive oplock not requested"
4833 };
4834 static const true_false_string tfs_open_flags_batch_oplock = {
4835         "Batch oplock requested",
4836         "Batch oplock not requested"
4837 };
4838 static const true_false_string tfs_open_flags_ealen = {
4839         "Total length of EAs requested",
4840         "Total length of EAs not requested"
4841 };
4842 static int
4843 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4844 {
4845         guint16 mask;
4846         proto_item *item = NULL;
4847         proto_tree *tree = NULL;
4848
4849         mask = tvb_get_letohs(tvb, offset);
4850
4851         if(parent_tree){
4852                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4853                         "Flags: 0x%04x", mask);
4854                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4855         }
4856
4857         if(bm&0x0001){
4858                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4859                         tvb, offset, 2, mask);
4860         }
4861         if(bm&0x0002){
4862                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4863                         tvb, offset, 2, mask);
4864         }
4865         if(bm&0x0004){
4866                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4867                         tvb, offset, 2, mask);
4868         }
4869         if(bm&0x0008){
4870                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4871                         tvb, offset, 2, mask);
4872         }
4873
4874         offset += 2;
4875
4876         return offset;
4877 }
4878
4879 static const value_string filetype_vals[] = {
4880         { 0,            "Disk file or directory"},
4881         { 1,            "Named pipe in byte mode"},
4882         { 2,            "Named pipe in message mode"},
4883         { 3,            "Spooled printer"},
4884         {0, NULL}
4885 };
4886 static int
4887 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4888 {
4889         guint8  wc, cmd=0xff;
4890         guint16 andxoffset=0, bc;
4891         int fn_len;
4892         const char *fn;
4893
4894         WORD_COUNT;
4895
4896         /* next smb command */
4897         cmd = tvb_get_guint8(tvb, offset);
4898         if(cmd!=0xff){
4899                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4900         } else {
4901                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4902         }
4903         offset += 1;
4904
4905         /* reserved byte */
4906         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4907         offset += 1;
4908
4909         /* andxoffset */
4910         andxoffset = tvb_get_letohs(tvb, offset);
4911         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4912         offset += 2;
4913
4914         /* open flags */
4915         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
4916
4917         /* desired access */
4918         offset = dissect_access(tvb, tree, offset, "Desired");
4919
4920         /* Search Attributes */
4921         offset = dissect_search_attributes(tvb, tree, offset);
4922
4923         /* File Attributes */
4924         offset = dissect_file_attributes(tvb, tree, offset);
4925
4926         /* creation time */
4927         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4928         
4929         /* open function */
4930         offset = dissect_open_function(tvb, tree, offset);
4931
4932         /* allocation size */
4933         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4934         offset += 4;
4935
4936         /* 8 reserved bytes */
4937         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4938         offset += 8;
4939
4940         BYTE_COUNT;
4941
4942         /* file name */
4943         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4944                 FALSE, FALSE, &bc);
4945         if (fn == NULL)
4946                 goto endofcommand;
4947         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4948                 fn);
4949         COUNT_BYTES(fn_len);
4950
4951         if (check_col(pinfo->cinfo, COL_INFO)) {
4952                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4953         }
4954
4955         END_OF_SMB
4956
4957         /* call AndXCommand (if there are any) */
4958         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4959
4960         return offset;
4961 }
4962
4963 static const true_false_string tfs_ipc_state_nonblocking = {
4964         "Reads/writes return immediately if no data available",
4965         "Reads/writes block if no data available"
4966 };
4967 static const value_string ipc_state_endpoint_vals[] = {
4968         { 0,            "Consumer end of pipe"},
4969         { 1,            "Server end of pipe"},
4970         {0,     NULL}
4971 };
4972 static const value_string ipc_state_pipe_type_vals[] = {
4973         { 0,            "Byte stream pipe"},
4974         { 1,            "Message pipe"},
4975         {0,     NULL}
4976 };
4977 static const value_string ipc_state_read_mode_vals[] = {
4978         { 0,            "Read pipe as a byte stream"},
4979         { 1,            "Read messages from pipe"},
4980         {0,     NULL}
4981 };
4982
4983 int
4984 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
4985     gboolean setstate)
4986 {
4987         guint16 mask;
4988         proto_item *item = NULL;
4989         proto_tree *tree = NULL;
4990
4991         mask = tvb_get_letohs(tvb, offset);
4992
4993         if(parent_tree){
4994                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4995                         "IPC State: 0x%04x", mask);
4996                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4997         }
4998
4999         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5000                 tvb, offset, 2, mask);
5001         if (!setstate) {
5002                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5003                         tvb, offset, 2, mask);
5004                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5005                         tvb, offset, 2, mask);
5006         }
5007         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5008                 tvb, offset, 2, mask);
5009         if (!setstate) {
5010                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5011                         tvb, offset, 2, mask);
5012         }
5013
5014         offset += 2;
5015
5016         return offset;
5017 }
5018
5019 static int
5020 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5021 {
5022         guint8  wc, cmd=0xff;
5023         guint16 andxoffset=0, bc;
5024         guint16 fid;
5025
5026         WORD_COUNT;
5027
5028         /* next smb command */
5029         cmd = tvb_get_guint8(tvb, offset);
5030         if(cmd!=0xff){
5031                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5032         } else {
5033                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5034         }
5035         offset += 1;
5036
5037         /* reserved byte */
5038         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5039         offset += 1;
5040
5041         /* andxoffset */
5042         andxoffset = tvb_get_letohs(tvb, offset);
5043         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5044         offset += 2;
5045
5046         /* fid */
5047         fid = tvb_get_letohs(tvb, offset);
5048         add_fid(tvb, pinfo, tree, offset, 2, fid);
5049         offset += 2;
5050
5051         /* File Attributes */
5052         offset = dissect_file_attributes(tvb, tree, offset);
5053
5054         /* last write time */
5055         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5056         
5057         /* File Size */
5058         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5059         offset += 4;
5060
5061         /* granted access */
5062         offset = dissect_access(tvb, tree, offset, "Granted");
5063
5064         /* File Type */
5065         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5066         offset += 2;
5067
5068         /* IPC State */
5069         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5070
5071         /* open_action */
5072         offset = dissect_open_action(tvb, tree, offset);
5073
5074         /* server fid */
5075         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5076         offset += 4;
5077
5078         /* 2 reserved bytes */
5079         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5080         offset += 2;
5081
5082         BYTE_COUNT;
5083
5084         END_OF_SMB
5085
5086         /* call AndXCommand (if there are any) */
5087         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5088
5089         return offset;
5090 }
5091
5092 static int
5093 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5094 {
5095         guint8  wc, cmd=0xff;
5096         guint16 andxoffset=0, bc, maxcnt = 0;
5097         guint32 ofs = 0;
5098         smb_info_t *si;
5099         unsigned int fid;
5100
5101         WORD_COUNT;
5102
5103         /* next smb command */
5104         cmd = tvb_get_guint8(tvb, offset);
5105         if(cmd!=0xff){
5106                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5107         } else {
5108                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5109         }
5110         offset += 1;
5111
5112         /* reserved byte */
5113         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5114         offset += 1;
5115
5116         /* andxoffset */
5117         andxoffset = tvb_get_letohs(tvb, offset);
5118         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5119         offset += 2;
5120
5121         /* fid */
5122         fid = tvb_get_letohs(tvb, offset);
5123         add_fid(tvb, pinfo, tree, offset, 2, fid);
5124         offset += 2;
5125         if (!pinfo->fd->flags.visited) {
5126                 /* remember the FID for the processing of the response */
5127                 si = (smb_info_t *)pinfo->private_data;
5128                 si->sip->extra_info=(void *)fid;
5129         }
5130
5131         /* offset */
5132         ofs = tvb_get_letohl(tvb, offset);
5133         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5134         offset += 4;
5135
5136         /* max count */
5137         maxcnt = tvb_get_letohs(tvb, offset);
5138         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5139         offset += 2;
5140
5141         if (check_col(pinfo->cinfo, COL_INFO))
5142                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5143                                 ", %u byte%s at offset %u", maxcnt, 
5144                                 (maxcnt == 1) ? "" : "s", ofs);
5145
5146         /* min count */
5147         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5148         offset += 2;
5149
5150         /* XXX - max count high */
5151         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5152         offset += 4;
5153
5154         /* remaining */
5155         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5156         offset += 2;
5157
5158         if(wc==12){
5159                 /* high offset */
5160                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5161                 offset += 4;
5162         }
5163
5164         BYTE_COUNT;
5165
5166         END_OF_SMB
5167
5168         /* call AndXCommand (if there are any) */
5169         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5170
5171         return offset;
5172 }
5173
5174 static int
5175 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5176 {
5177         guint8  wc, cmd=0xff;
5178         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5179         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5180         int fid=0;
5181
5182         WORD_COUNT;
5183
5184         /* next smb command */
5185         cmd = tvb_get_guint8(tvb, offset);
5186         if(cmd!=0xff){
5187                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5188         } else {
5189                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5190         }
5191         offset += 1;
5192  
5193         /* reserved byte */
5194         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5195         offset += 1;
5196
5197         /* andxoffset */
5198         andxoffset = tvb_get_letohs(tvb, offset);
5199         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5200         offset += 2;
5201
5202         /* If we have seen the request, then print which FID this refers to */
5203         /* first check if we have seen the request */
5204         if(si->sip != NULL && si->sip->frame_req>0){
5205                 fid=(int)si->sip->extra_info;
5206                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5207         }
5208
5209         /* remaining */
5210         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5211         offset += 2;
5212
5213         /* data compaction mode */
5214         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5215         offset += 2;
5216
5217         /* 2 reserved bytes */
5218         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5219         offset += 2;
5220
5221         /* data len */
5222         datalen = tvb_get_letohs(tvb, offset);
5223         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5224         offset += 2;
5225
5226         if (check_col(pinfo->cinfo, COL_INFO))
5227                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5228                                 ", %u byte%s", datalen, 
5229                                 (datalen == 1) ? "" : "s");
5230
5231         /* data offset */
5232         dataoffset=tvb_get_letohs(tvb, offset);
5233         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5234         offset += 2;
5235
5236         /* 10 reserved bytes */
5237         /* XXX - first 2 bytes are data length high, not reserved */
5238         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5239         offset += 10;
5240
5241         BYTE_COUNT;
5242
5243         /* is this part of DCERPC over SMB reassembly?*/
5244         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
5245             && (bc<=tvb_length_remaining(tvb, offset)) ){
5246                 gpointer hash_value;
5247                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
5248                                                 si->ct->dcerpc_fid_to_frame,
5249                                                 si->sip->extra_info)) != NULL) {
5250                         fragment_data *fd_head;
5251                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5252
5253                         /* first fragment is always from a SMB Trans command and
5254                            offset 0 of the following read/write SMB commands start
5255                            BEYOND the first Trans SMB payload. Look for offset
5256                            in first read fragment */
5257                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5258                         if(fd_head){
5259                                 /* skip to last fragment  and add this data there*/
5260                                 while(fd_head->next){
5261                                         fd_head=fd_head->next;
5262                                 }
5263                                 /* if dataoffset was not specified in the SMB command
5264                                    then we try to guess it as good as we can
5265                                 */
5266                                 if(dataoffset==0){
5267                                         dataoffset=offset+bc-datalen;
5268                                 }
5269                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5270                                         frame, dcerpc_fragment_table,
5271                                         fd_head->offset+fd_head->len, 
5272                                         datalen, TRUE);
5273                                 /* we completed reassembly, abort searching for more 
5274                                    fragments*/
5275                                 if(fd_head){
5276                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5277                                                 si->sip->extra_info);   
5278                                 }
5279                         }
5280                 }
5281         }
5282
5283         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
5284            read write */
5285         if(bc){
5286                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
5287                         /* dcerpc call */
5288                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5289                             top_tree, offset, bc, datalen, fid);
5290                 } else {
5291                         /* ordinary file data, or we didn't see the request,
5292                            so we don't know whether this is a DCERPC call
5293                            or not */
5294                         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5295                 }
5296                 bc = 0;
5297         }
5298
5299         END_OF_SMB
5300
5301         /* call AndXCommand (if there are any) */
5302         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5303
5304         return offset;
5305 }
5306
5307 static int
5308 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5309 {
5310         guint32 ofs=0;
5311         guint8  wc, cmd=0xff;
5312         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5313         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5314         unsigned int fid=0;
5315
5316         WORD_COUNT;
5317
5318         /* next smb command */
5319         cmd = tvb_get_guint8(tvb, offset);
5320         if(cmd!=0xff){
5321                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5322         } else {
5323                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5324         }
5325         offset += 1;
5326
5327         /* reserved byte */
5328         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5329         offset += 1;
5330
5331         /* andxoffset */
5332         andxoffset = tvb_get_letohs(tvb, offset);
5333         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5334         offset += 2;
5335
5336         /* fid */
5337         fid = tvb_get_letohs(tvb, offset);
5338         add_fid(tvb, pinfo, tree, offset, 2, fid);
5339         offset += 2;
5340         if (!pinfo->fd->flags.visited) {
5341                 /* remember the FID for the processing of the response */
5342                 si->sip->extra_info=(void *)fid;
5343         }
5344
5345         /* offset */
5346         ofs = tvb_get_letohl(tvb, offset);
5347         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5348         offset += 4;
5349
5350         /* reserved */
5351         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5352         offset += 4;
5353
5354         /* mode */
5355         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5356
5357         /* remaining */
5358         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5359         offset += 2;
5360
5361         /* XXX - data length high */
5362         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5363         offset += 2;
5364
5365         /* data len */
5366         datalen = tvb_get_letohs(tvb, offset);
5367         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5368         offset += 2;
5369
5370         /* data offset */
5371         dataoffset=tvb_get_letohs(tvb, offset);
5372         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5373         offset += 2;
5374
5375         /* FIXME: add byte/offset to COL_INFO */
5376
5377         if(wc==14){
5378                 /* high offset */
5379                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5380                 offset += 4;
5381         }
5382
5383         BYTE_COUNT;
5384
5385         /* is this part of DCERPC over SMB reassembly?*/
5386         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5387                 gpointer hash_value;
5388                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5389                         si->sip->extra_info);
5390                 if(hash_value){
5391                         fragment_data *fd_head;
5392                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5393
5394                         /* first fragment is always from a SMB Trans command and
5395                            offset 0 of the following read/write SMB commands start
5396                            BEYOND the first Trans SMB payload. Look for offset
5397                            in first read fragment */
5398                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5399                         if(fd_head){
5400                                 /* skip to last fragment  and add this data there*/
5401                                 while(fd_head->next){
5402                                         fd_head=fd_head->next;
5403                                 }
5404                                 /* if dataoffset was not specified in the SMB command
5405                                    then we try to guess it as good as we can
5406                                 */
5407                                 if(dataoffset==0){
5408                                         dataoffset=offset+bc-datalen;
5409                                 }
5410                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5411                                         frame, dcerpc_fragment_table,
5412                                         fd_head->offset+fd_head->len, 
5413                                         datalen, TRUE);
5414                                 /* we completed reassembly, abort searching for more 
5415                                    fragments*/
5416                                 if(fd_head){
5417                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5418                                                 si->sip->extra_info);   
5419                                 }
5420                         }
5421                 }
5422         }
5423
5424         /* file data */
5425         if (bc != 0) {
5426                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5427                         /* dcerpc call */
5428                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5429                             top_tree, offset, bc, datalen, fid);
5430                 } else {
5431                         /* ordinary file data */
5432                         offset = dissect_file_data(tvb, tree, offset,
5433                             bc, datalen);
5434                 }
5435                 bc = 0;
5436         }
5437
5438         END_OF_SMB
5439
5440         /* call AndXCommand (if there are any) */
5441         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5442
5443         return offset;
5444 }
5445
5446 static int
5447 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5448 {
5449         guint8  wc, cmd=0xff;
5450         guint16 andxoffset=0, bc;
5451         smb_info_t *si;
5452
5453         WORD_COUNT;
5454
5455         /* next smb command */
5456         cmd = tvb_get_guint8(tvb, offset);
5457         if(cmd!=0xff){
5458                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5459         } else {
5460                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5461         }
5462         offset += 1;
5463  
5464         /* reserved byte */
5465         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5466         offset += 1;
5467
5468         /* andxoffset */
5469         andxoffset = tvb_get_letohs(tvb, offset);
5470         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5471         offset += 2;
5472
5473         /* If we have seen the request, then print which FID this refers to */
5474         si = (smb_info_t *)pinfo->private_data;
5475         /* first check if we have seen the request */
5476         if(si->sip != NULL && si->sip->frame_req>0){
5477                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5478         }
5479
5480         /* write count */
5481         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5482         offset += 2;
5483
5484         /* remaining */
5485         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5486         offset += 2;
5487
5488         /* 4 reserved bytes */
5489         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5490         offset += 4;
5491
5492         BYTE_COUNT;
5493
5494         END_OF_SMB
5495
5496         /* call AndXCommand (if there are any) */
5497         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5498
5499         return offset;
5500 }
5501
5502
5503 static const true_false_string tfs_setup_action_guest = {
5504         "Logged in as GUEST",
5505         "Not logged in as GUEST"
5506 };
5507 static int
5508 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5509 {
5510         guint16 mask;
5511         proto_item *item = NULL;
5512         proto_tree *tree = NULL;
5513
5514         mask = tvb_get_letohs(tvb, offset);
5515
5516         if(parent_tree){
5517                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5518                         "Action: 0x%04x", mask);
5519                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5520         }
5521
5522         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5523                 tvb, offset, 2, mask);
5524
5525         offset += 2;
5526
5527         return offset;
5528 }
5529  
5530
5531 static int
5532 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5533 {
5534         guint8  wc, cmd=0xff;
5535         guint16 bc;
5536         guint16 andxoffset=0;
5537         int an_len;
5538         const char *an;
5539         int dn_len;
5540         const char *dn;
5541         guint16 pwlen=0;
5542         guint16 sbloblen=0;
5543         guint16 apwlen=0, upwlen=0;
5544
5545         WORD_COUNT;
5546
5547         /* next smb command */
5548         cmd = tvb_get_guint8(tvb, offset);
5549         if(cmd!=0xff){
5550                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5551         } else {
5552                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5553         }
5554         offset += 1;
5555
5556         /* reserved byte */
5557         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5558         offset += 1;
5559
5560         /* andxoffset */
5561         andxoffset = tvb_get_letohs(tvb, offset);
5562         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5563         offset += 2;
5564
5565         /* Maximum Buffer Size */
5566         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5567         offset += 2;
5568
5569         /* Maximum Multiplex Count */
5570         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5571         offset += 2;
5572
5573         /* VC Number */
5574         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5575         offset += 2;
5576
5577         /* session key */
5578         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5579         offset += 4;
5580
5581         switch (wc) {
5582         case 10:
5583                 /* password length, ASCII*/
5584                 pwlen = tvb_get_letohs(tvb, offset);
5585                 proto_tree_add_uint(tree, hf_smb_password_len,
5586                         tvb, offset, 2, pwlen);
5587                 offset += 2;
5588
5589                 /* 4 reserved bytes */
5590                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5591                 offset += 4;
5592
5593                 break;
5594
5595         case 12:
5596                 /* security blob length */
5597                 sbloblen = tvb_get_letohs(tvb, offset);
5598                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5599                 offset += 2;
5600
5601                 /* 4 reserved bytes */
5602                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5603                 offset += 4;
5604
5605                 /* capabilities */
5606                 dissect_negprot_capabilities(tvb, tree, offset);
5607                 offset += 4;
5608
5609                 break;
5610
5611         case 13:
5612                 /* password length, ANSI*/
5613                 apwlen = tvb_get_letohs(tvb, offset);
5614                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5615                         tvb, offset, 2, apwlen);
5616                 offset += 2;
5617
5618                 /* password length, Unicode*/
5619                 upwlen = tvb_get_letohs(tvb, offset);
5620                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5621                         tvb, offset, 2, upwlen);
5622                 offset += 2;
5623
5624                 /* 4 reserved bytes */
5625                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5626                 offset += 4;
5627
5628                 /* capabilities */
5629                 dissect_negprot_capabilities(tvb, tree, offset);
5630                 offset += 4;
5631
5632                 break;
5633         }
5634
5635         BYTE_COUNT;
5636
5637         if (wc==12) {
5638                 /* security blob */
5639                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5640                    data structure, at least in NT 5.0-and-later
5641                    server replies? */
5642                 if(sbloblen){
5643                         CHECK_BYTE_COUNT(sbloblen);
5644                         proto_tree_add_item(tree, hf_smb_security_blob,
5645                                 tvb, offset, sbloblen, TRUE);
5646                         COUNT_BYTES(sbloblen);
5647                 }
5648
5649                 /* OS */
5650                 an = get_unicode_or_ascii_string(tvb, &offset,
5651                         pinfo, &an_len, FALSE, FALSE, &bc);
5652                 if (an == NULL)
5653                         goto endofcommand;
5654                 proto_tree_add_string(tree, hf_smb_os, tvb,
5655                         offset, an_len, an);
5656                 COUNT_BYTES(an_len);
5657
5658                 /* LANMAN */
5659                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5660                  * padding/null string/whatever in front of this. W2K doesn't
5661                  * appear to. I suspect that's a bug that got fixed; I also
5662                  * suspect that, in practice, nobody ever looks at that field
5663                  * because the bug didn't appear to get fixed until NT 5.0....
5664                  */
5665                 an = get_unicode_or_ascii_string(tvb, &offset,
5666                         pinfo, &an_len, FALSE, FALSE, &bc);
5667                 if (an == NULL)
5668                         goto endofcommand;
5669                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5670                         offset, an_len, an);
5671                 COUNT_BYTES(an_len);
5672
5673                 /* Primary domain */
5674                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5675                  * byte in front of this, at least if all the strings are
5676                  * ASCII and the account name is empty. Another bug?
5677                  */
5678                 dn = get_unicode_or_ascii_string(tvb, &offset,
5679                         pinfo, &dn_len, FALSE, FALSE, &bc);
5680                 if (dn == NULL)
5681                         goto endofcommand;
5682                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5683                         offset, dn_len, dn);
5684                 COUNT_BYTES(dn_len);
5685         } else {
5686                 switch (wc) {
5687
5688                 case 10:
5689                         if(pwlen){
5690                                 /* password, ASCII */
5691                                 CHECK_BYTE_COUNT(pwlen);
5692                                 proto_tree_add_item(tree, hf_smb_password, 
5693                                         tvb, offset, pwlen, TRUE);
5694                                 COUNT_BYTES(pwlen);
5695                         }
5696
5697                         break;
5698
5699                 case 13:
5700                         if(apwlen){
5701                                 /* password, ANSI */
5702                                 CHECK_BYTE_COUNT(apwlen);
5703                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5704                                         tvb, offset, apwlen, TRUE);
5705                                 COUNT_BYTES(apwlen);
5706                         }
5707
5708                         if(upwlen){
5709                                 /* password, Unicode */
5710                                 CHECK_BYTE_COUNT(upwlen);
5711                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5712                                         tvb, offset, upwlen, TRUE);
5713                                 COUNT_BYTES(upwlen);
5714                         }
5715
5716                         break;
5717                 }
5718
5719                 /* Account Name */
5720                 an = get_unicode_or_ascii_string(tvb, &offset,
5721                         pinfo, &an_len, FALSE, FALSE, &bc);
5722                 if (an == NULL)
5723                         goto endofcommand;
5724                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5725                         an);
5726                 COUNT_BYTES(an_len);
5727
5728                 /* Primary domain */
5729                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5730                  * byte in front of this, at least if all the strings are
5731                  * ASCII and the account name is empty. Another bug?
5732                  */
5733                 dn = get_unicode_or_ascii_string(tvb, &offset,
5734                         pinfo, &dn_len, FALSE, FALSE, &bc);
5735                 if (dn == NULL)
5736                         goto endofcommand;
5737                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5738                         offset, dn_len, dn);
5739                 COUNT_BYTES(dn_len);
5740
5741                 if (check_col(pinfo->cinfo, COL_INFO)) {
5742                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5743
5744                         if (!dn[0] && !an[0])
5745                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5746                                                 "anonymous");
5747                         else
5748                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5749                                                 "%s\\%s", dn,an);
5750                 }
5751
5752                 /* OS */
5753                 an = get_unicode_or_ascii_string(tvb, &offset,
5754                         pinfo, &an_len, FALSE, FALSE, &bc);
5755                 if (an == NULL)
5756                         goto endofcommand;
5757                 proto_tree_add_string(tree, hf_smb_os, tvb,
5758                         offset, an_len, an);
5759                 COUNT_BYTES(an_len);
5760
5761                 /* LANMAN */
5762                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5763                  * padding/null string/whatever in front of this. W2K doesn't
5764                  * appear to. I suspect that's a bug that got fixed; I also
5765                  * suspect that, in practice, nobody ever looks at that field
5766                  * because the bug didn't appear to get fixed until NT 5.0....
5767                  */
5768                 an = get_unicode_or_ascii_string(tvb, &offset,
5769                         pinfo, &an_len, FALSE, FALSE, &bc);
5770                 if (an == NULL)
5771                         goto endofcommand;
5772                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5773                         offset, an_len, an);
5774                 COUNT_BYTES(an_len);
5775         }
5776
5777         END_OF_SMB
5778
5779         /* call AndXCommand (if there are any) */
5780         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5781
5782         return offset;
5783 }
5784
5785 static int
5786 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5787 {
5788         guint8  wc, cmd=0xff;
5789         guint16 andxoffset=0, bc;
5790         guint16 sbloblen=0;
5791         int an_len;
5792         const char *an;
5793
5794         WORD_COUNT;
5795
5796         /* next smb command */
5797         cmd = tvb_get_guint8(tvb, offset);
5798         if(cmd!=0xff){
5799                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5800         } else {
5801                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5802         }
5803         offset += 1;
5804
5805         /* reserved byte */
5806         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5807         offset += 1;
5808
5809         /* andxoffset */
5810         andxoffset = tvb_get_letohs(tvb, offset);
5811         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5812         offset += 2;
5813
5814         /* flags */
5815         offset = dissect_setup_action(tvb, tree, offset);
5816
5817         if(wc==4){
5818                 /* security blob length */
5819                 sbloblen = tvb_get_letohs(tvb, offset);
5820                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5821                 offset += 2;
5822         }
5823
5824         BYTE_COUNT;
5825
5826         if(wc==4) {
5827                 /* security blob */
5828                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5829                    data structure, at least in NT 5.0-and-later
5830                    server replies? */
5831                 if(sbloblen){
5832                         CHECK_BYTE_COUNT(sbloblen);
5833                         proto_tree_add_item(tree, hf_smb_security_blob,
5834                                 tvb, offset, sbloblen, TRUE);
5835                         COUNT_BYTES(sbloblen);
5836                 }
5837         }
5838
5839         /* OS */
5840         an = get_unicode_or_ascii_string(tvb, &offset,
5841                 pinfo, &an_len, FALSE, FALSE, &bc);
5842         if (an == NULL)
5843                 goto endofcommand;
5844         proto_tree_add_string(tree, hf_smb_os, tvb,
5845                 offset, an_len, an);
5846         COUNT_BYTES(an_len);
5847
5848         /* LANMAN */
5849         an = get_unicode_or_ascii_string(tvb, &offset,
5850                 pinfo, &an_len, FALSE, FALSE, &bc);
5851         if (an == NULL)
5852                 goto endofcommand;
5853         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5854                 offset, an_len, an);
5855         COUNT_BYTES(an_len);
5856
5857         if(wc==3) {
5858                 /* Primary domain */
5859                 an = get_unicode_or_ascii_string(tvb, &offset,
5860                         pinfo, &an_len, FALSE, FALSE, &bc);
5861                 if (an == NULL)
5862                         goto endofcommand;
5863                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5864                         offset, an_len, an);
5865                 COUNT_BYTES(an_len);
5866         }
5867
5868         END_OF_SMB
5869
5870         /* call AndXCommand (if there are any) */
5871         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5872
5873         return offset;
5874 }
5875
5876  
5877 static int
5878 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5879 {
5880         guint8  wc, cmd=0xff;
5881         guint16 andxoffset=0;
5882         guint16 bc;
5883
5884         WORD_COUNT;
5885
5886         /* next smb command */
5887         cmd = tvb_get_guint8(tvb, offset);
5888         if(cmd!=0xff){
5889                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5890         } else {
5891                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5892         }
5893         offset += 1;
5894
5895         /* reserved byte */
5896         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5897         offset += 1;
5898
5899         /* andxoffset */
5900         andxoffset = tvb_get_letohs(tvb, offset);
5901         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5902         offset += 2;
5903
5904         BYTE_COUNT;
5905
5906         END_OF_SMB
5907
5908         /* call AndXCommand (if there are any) */
5909         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5910
5911         return offset;
5912 }
5913
5914  
5915 static const true_false_string tfs_connect_support_search = {
5916         "Exclusive search bits supported",
5917         "Exclusive search bits not supported"
5918 };
5919 static const true_false_string tfs_connect_support_in_dfs = {
5920         "Share is in Dfs",
5921         "Share isn't in Dfs"
5922 };
5923
5924 static int
5925 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5926 {
5927         guint16 mask;
5928         proto_item *item = NULL;
5929         proto_tree *tree = NULL;
5930
5931         mask = tvb_get_letohs(tvb, offset);
5932
5933         if(parent_tree){
5934                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5935                         "Optional Support: 0x%04x", mask);
5936                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5937         }
5938
5939         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5940                 tvb, offset, 2, mask);
5941         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5942                 tvb, offset, 2, mask);
5943
5944         offset += 2;
5945
5946         return offset;
5947 }
5948
5949 static const true_false_string tfs_disconnect_tid = {
5950         "DISCONNECT TID",
5951         "Do NOT disconnect TID"
5952 };
5953
5954 static int
5955 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5956 {
5957         guint16 mask;
5958         proto_item *item = NULL;
5959         proto_tree *tree = NULL;
5960
5961         mask = tvb_get_letohs(tvb, offset);
5962
5963         if(parent_tree){
5964                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5965                         "Flags: 0x%04x", mask);
5966                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5967         }
5968
5969         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5970                 tvb, offset, 2, mask);
5971
5972         offset += 2;
5973
5974         return offset;
5975 }
5976
5977 static int
5978 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5979 {
5980         guint8  wc, cmd=0xff;
5981         guint16 bc;
5982         guint16 andxoffset=0, pwlen=0;
5983         int an_len;
5984         const char *an;
5985
5986         WORD_COUNT;
5987
5988         /* next smb command */
5989         cmd = tvb_get_guint8(tvb, offset);
5990         if(cmd!=0xff){
5991                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5992         } else {
5993                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5994         }
5995         offset += 1;
5996
5997         /* reserved byte */
5998         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5999         offset += 1;
6000
6001         /* andxoffset */
6002         andxoffset = tvb_get_letohs(tvb, offset);
6003         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6004         offset += 2;
6005
6006         /* flags */
6007         offset = dissect_connect_flags(tvb, tree, offset);
6008
6009         /* password length*/
6010         pwlen = tvb_get_letohs(tvb, offset);
6011         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6012         offset += 2;
6013
6014         BYTE_COUNT;
6015
6016         /* password */
6017         CHECK_BYTE_COUNT(pwlen);
6018         proto_tree_add_item(tree, hf_smb_password, 
6019                 tvb, offset, pwlen, TRUE);
6020         COUNT_BYTES(pwlen);
6021
6022         /* Path */
6023         an = get_unicode_or_ascii_string(tvb, &offset,
6024                 pinfo, &an_len, FALSE, FALSE, &bc);
6025         if (an == NULL)
6026                 goto endofcommand;
6027         proto_tree_add_string(tree, hf_smb_path, tvb,
6028                 offset, an_len, an);
6029         COUNT_BYTES(an_len);
6030
6031         if (check_col(pinfo->cinfo, COL_INFO)) {
6032                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6033         }
6034
6035         /*
6036          * NOTE: the Service string is always ASCII, even if the
6037          * "strings are Unicode" bit is set in the flags2 field
6038          * of the SMB.
6039          */
6040
6041         /* Service */
6042         /* XXX - what if this runs past bc? */
6043         an_len = tvb_strsize(tvb, offset);
6044         CHECK_BYTE_COUNT(an_len);
6045         an = tvb_get_ptr(tvb, offset, an_len);
6046         proto_tree_add_string(tree, hf_smb_service, tvb,
6047                 offset, an_len, an);
6048         COUNT_BYTES(an_len);
6049
6050         END_OF_SMB
6051
6052         /* call AndXCommand (if there are any) */
6053         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
6054
6055         return offset;
6056 }
6057
6058
6059 static int
6060 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6061 {
6062         guint8  wc, wleft, cmd=0xff;
6063         guint16 andxoffset=0;
6064         guint16 bc;
6065         int an_len;
6066         const char *an;
6067
6068         WORD_COUNT;
6069
6070         wleft = wc;     /* this is at least 1 */
6071
6072         /* next smb command */
6073         cmd = tvb_get_guint8(tvb, offset);
6074         if(cmd!=0xff){
6075                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6076         } else {
6077                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6078         }
6079         offset += 1;
6080
6081         /* reserved byte */
6082         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6083         offset += 1;
6084
6085         wleft--;
6086         if (wleft == 0)
6087                 goto bytecount;
6088
6089         /* andxoffset */
6090         andxoffset = tvb_get_letohs(tvb, offset);
6091         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6092         offset += 2;
6093         wleft--;
6094         if (wleft == 0)
6095                 goto bytecount;
6096
6097         /* flags */
6098         offset = dissect_connect_support_bits(tvb, tree, offset);
6099         wleft--;
6100
6101         /* XXX - I've seen captures where this is 7, but I have no
6102            idea how to dissect it.  I'm guessing the third word
6103            contains connect support bits, which looks plausible
6104            from the values I've seen. */
6105
6106         while (wleft != 0) {
6107                 proto_tree_add_text(tree, tvb, offset, 2,
6108                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6109                 offset += 2;
6110                 wleft--;
6111         }
6112
6113         BYTE_COUNT;
6114
6115         /*
6116          * NOTE: even though the SNIA CIFS spec doesn't say there's
6117          * a "Service" string if there's a word count of 2, the
6118          * document at
6119          *
6120          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6121          *
6122          * (it's in an ugly format - text intended to be sent to a
6123          * printer, with backspaces and overstrikes used for boldfacing
6124          * and underlining; UNIX "col -b" can be used to strip the
6125          * overstrikes out) says there's a "Service" string there, and
6126          * some network traffic has it.
6127          */
6128
6129         /*
6130          * NOTE: the Service string is always ASCII, even if the
6131          * "strings are Unicode" bit is set in the flags2 field
6132          * of the SMB.
6133          */
6134
6135         /* Service */
6136         /* XXX - what if this runs past bc? */
6137         an_len = tvb_strsize(tvb, offset);
6138         CHECK_BYTE_COUNT(an_len);
6139         an = tvb_get_ptr(tvb, offset, an_len);
6140         proto_tree_add_string(tree, hf_smb_service, tvb,
6141                 offset, an_len, an);
6142         COUNT_BYTES(an_len);
6143
6144         /* Now when we know the service type, store it so that we know it for later commands down
6145            this tree */
6146         if(!pinfo->fd->flags.visited){
6147                 smb_info_t *si = (smb_info_t *)pinfo->private_data;
6148                 /* Remove any previous entry for this TID */
6149                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6150                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6151                 }
6152                 if(strcmp(an,"IPC") == 0){
6153                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6154                 } else {
6155                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6156                 }
6157         }
6158
6159
6160         if(wc==3){
6161                 if (bc != 0) {
6162                         /*
6163                          * Sometimes this isn't present.
6164                          */
6165
6166                         /* Native FS */
6167                         an = get_unicode_or_ascii_string(tvb, &offset,
6168                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
6169                         if (an == NULL)
6170                                 goto endofcommand;
6171                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6172                                 offset, an_len, an);
6173                         COUNT_BYTES(an_len);
6174                 }
6175         }
6176
6177         END_OF_SMB
6178
6179         /* call AndXCommand (if there are any) */
6180         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
6181
6182         return offset;
6183 }
6184
6185
6186
6187 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6188    NT Transaction command  begins here
6189    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6190 #define NT_TRANS_CREATE         1
6191 #define NT_TRANS_IOCTL          2
6192 #define NT_TRANS_SSD            3
6193 #define NT_TRANS_NOTIFY         4
6194 #define NT_TRANS_RENAME         5
6195 #define NT_TRANS_QSD            6
6196 #define NT_TRANS_GET_USER_QUOTA 7
6197 #define NT_TRANS_SET_USER_QUOTA 8
6198 static const value_string nt_cmd_vals[] = {
6199         {NT_TRANS_CREATE,               "NT CREATE"},
6200         {NT_TRANS_IOCTL,                "NT IOCTL"},
6201         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6202         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6203         {NT_TRANS_RENAME,               "NT RENAME"},
6204         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6205         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6206         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6207         {0, NULL}
6208 };
6209
6210 static const value_string nt_ioctl_isfsctl_vals[] = {
6211         {0,     "Device IOCTL"},
6212         {1,     "FS control : FSCTL"},
6213         {0, NULL}
6214 };
6215
6216 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6217 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6218         "Apply the command to share root handle (MUST BE Dfs)",
6219         "Apply to this share",
6220 };
6221
6222 static const value_string nt_notify_action_vals[] = {
6223         {1,     "ADDED (object was added"},
6224         {2,     "REMOVED (object was removed)"},
6225         {3,     "MODIFIED (object was modified)"},
6226         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6227         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6228         {6,     "ADDED_STREAM (a stream was added)"},
6229         {7,     "REMOVED_STREAM (a stream was removed)"},
6230         {8,     "MODIFIED_STREAM (a stream was modified)"},
6231         {0, NULL}
6232 };
6233
6234 static const value_string watch_tree_vals[] = {
6235         {0,     "Current directory only"},
6236         {1,     "Subdirectories also"},
6237         {0, NULL}
6238 };
6239
6240 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6241 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6242 #define NT_NOTIFY_STREAM_NAME   0x00000200
6243 #define NT_NOTIFY_SECURITY      0x00000100
6244 #define NT_NOTIFY_EA            0x00000080
6245 #define NT_NOTIFY_CREATION      0x00000040
6246 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6247 #define NT_NOTIFY_LAST_WRITE    0x00000010
6248 #define NT_NOTIFY_SIZE          0x00000008
6249 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6250 #define NT_NOTIFY_DIR_NAME      0x00000002
6251 #define NT_NOTIFY_FILE_NAME     0x00000001
6252 static const true_false_string tfs_nt_notify_stream_write = {
6253         "Notify on changes to STREAM WRITE",
6254         "Do NOT notify on changes to stream write",
6255 };
6256 static const true_false_string tfs_nt_notify_stream_size = {
6257         "Notify on changes to STREAM SIZE",
6258         "Do NOT notify on changes to stream size",
6259 };
6260 static const true_false_string tfs_nt_notify_stream_name = {
6261         "Notify on changes to STREAM NAME",
6262         "Do NOT notify on changes to stream name",
6263 };
6264 static const true_false_string tfs_nt_notify_security = {
6265         "Notify on changes to SECURITY",
6266         "Do NOT notify on changes to security",
6267 };
6268 static const true_false_string tfs_nt_notify_ea = {
6269         "Notify on changes to EA",
6270         "Do NOT notify on changes to EA",
6271 };
6272 static const true_false_string tfs_nt_notify_creation = {
6273         "Notify on changes to CREATION TIME",
6274         "Do NOT notify on changes to creation time",
6275 };
6276 static const true_false_string tfs_nt_notify_last_access = {
6277         "Notify on changes to LAST ACCESS TIME",
6278         "Do NOT notify on changes to last access time",
6279 };
6280 static const true_false_string tfs_nt_notify_last_write = {
6281         "Notify on changes to LAST WRITE TIME",
6282         "Do NOT notify on changes to last write time",
6283 };
6284 static const true_false_string tfs_nt_notify_size = {
6285         "Notify on changes to SIZE",
6286         "Do NOT notify on changes to size",
6287 };
6288 static const true_false_string tfs_nt_notify_attributes = {
6289         "Notify on changes to ATTRIBUTES",
6290         "Do NOT notify on changes to attributes",
6291 };
6292 static const true_false_string tfs_nt_notify_dir_name = {
6293         "Notify on changes to DIR NAME",
6294         "Do NOT notify on changes to dir name",
6295 };
6296 static const true_false_string tfs_nt_notify_file_name = {
6297         "Notify on changes to FILE NAME",
6298         "Do NOT notify on changes to file name",
6299 };
6300
6301 static const value_string create_disposition_vals[] = {
6302         {0,     "Supersede (supersede existing file (if it exists))"},
6303         {1,     "Open (if file exists open it, else fail)"},
6304         {2,     "Create (if file exists fail, else create it)"},
6305         {3,     "Open If (if file exists open it, else create it)"},
6306         {4,     "Overwrite (if file exists overwrite, else fail)"},
6307         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6308         {0, NULL}
6309 };
6310
6311 static const value_string impersonation_level_vals[] = {
6312         {0,     "Anonymous"},
6313         {1,     "Identification"},
6314         {2,     "Impersonation"},
6315         {3,     "Delegation"},
6316         {0, NULL}
6317 };
6318
6319 static const true_false_string tfs_nt_security_flags_context_tracking = {
6320         "Security tracking mode is DYNAMIC",
6321         "Security tracking mode is STATIC",
6322 };
6323
6324 static const true_false_string tfs_nt_security_flags_effective_only = {
6325         "ONLY ENABLED aspects of the client's security context are available",
6326         "ALL aspects of the client's security context are available",
6327 };
6328
6329 static const true_false_string tfs_nt_create_bits_oplock = {
6330         "Requesting OPLOCK",
6331         "Does NOT request oplock"
6332 };
6333
6334 static const true_false_string tfs_nt_create_bits_boplock = {
6335         "Requesting BATCH OPLOCK",
6336         "Does NOT request batch oplock"
6337 };
6338
6339 /*
6340  * XXX - must be a directory, and can be a file, or can be a directory,
6341  * and must be a file?
6342  */
6343 static const true_false_string tfs_nt_create_bits_dir = {
6344         "Target of open MUST be a DIRECTORY",
6345         "Target of open can be a file"
6346 };
6347
6348 static const true_false_string tfs_nt_access_mask_generic_read = {
6349         "GENERIC READ is set",
6350         "Generic read is NOT set"
6351 };
6352 static const true_false_string tfs_nt_access_mask_generic_write = {
6353         "GENERIC WRITE is set",
6354         "Generic write is NOT set"
6355 };
6356 static const true_false_string tfs_nt_access_mask_generic_execute = {
6357         "GENERIC EXECUTE is set",
6358         "Generic execute is NOT set"
6359 };
6360 static const true_false_string tfs_nt_access_mask_generic_all = {
6361         "GENERIC ALL is set",
6362         "Generic all is NOT set"
6363 };
6364 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6365         "MAXIMUM ALLOWED is set",
6366         "Maximum allowed is NOT set"
6367 };
6368 static const true_false_string tfs_nt_access_mask_system_security = {
6369         "SYSTEM SECURITY is set",
6370         "System security is NOT set"
6371 };
6372 static const true_false_string tfs_nt_access_mask_synchronize = {
6373         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6374         "Can NOT wait on handle to synchronize on completion of I/O"
6375 };
6376 static const true_false_string tfs_nt_access_mask_write_owner = {
6377         "Can WRITE OWNER (take ownership)",
6378         "Can NOT write owner (take ownership)"
6379 };
6380 static const true_false_string tfs_nt_access_mask_write_dac = {
6381         "OWNER may WRITE the DAC",
6382         "Owner may NOT write to the DAC"
6383 };
6384 static const true_false_string tfs_nt_access_mask_read_control = {
6385         "READ ACCESS to owner, group and ACL of the SID",
6386         "Read access is NOT granted to owner, group and ACL of the SID"
6387 };
6388 static const true_false_string tfs_nt_access_mask_delete = {
6389         "DELETE access",
6390         "NO delete access"
6391 };
6392 static const true_false_string tfs_nt_access_mask_write_attributes = {
6393         "WRITE ATTRIBUTES access",
6394         "NO write attributes access"
6395 };
6396 static const true_false_string tfs_nt_access_mask_read_attributes = {
6397         "READ ATTRIBUTES access",
6398         "NO read attributes access"
6399 };
6400 static const true_false_string tfs_nt_access_mask_delete_child = {
6401         "DELETE CHILD access",
6402         "NO delete child access"
6403 };
6404 static const true_false_string tfs_nt_access_mask_execute = {
6405         "EXECUTE access",
6406         "NO execute access"
6407 };
6408 static const true_false_string tfs_nt_access_mask_write_ea = {
6409         "WRITE EXTENDED ATTRIBUTES access",
6410         "NO write extended attributes access"
6411 };
6412 static const true_false_string tfs_nt_access_mask_read_ea = {
6413         "READ EXTENDED ATTRIBUTES access",
6414         "NO read extended attributes access"
6415 };
6416 static const true_false_string tfs_nt_access_mask_append = {
6417         "APPEND access",
6418         "NO append access"
6419 };
6420 static const true_false_string tfs_nt_access_mask_write = {
6421         "WRITE access",
6422         "NO write access"
6423 };
6424 static const true_false_string tfs_nt_access_mask_read = {
6425         "READ access",
6426         "NO read access"
6427 };
6428
6429 static const true_false_string tfs_nt_share_access_delete = {
6430         "Object can be shared for DELETE",
6431         "Object can NOT be shared for delete"
6432 };
6433 static const true_false_string tfs_nt_share_access_write = {
6434         "Object can be shared for WRITE",
6435         "Object can NOT be shared for write"
6436 };
6437 static const true_false_string tfs_nt_share_access_read = {
6438         "Object can be shared for READ",
6439         "Object can NOT be shared for delete"
6440 };
6441
6442 static const value_string oplock_level_vals[] = {
6443         {0,     "No oplock granted"},
6444         {1,     "Exclusive oplock granted"},
6445         {2,     "Batch oplock granted"},
6446         {3,     "Level II oplock granted"},
6447         {0, NULL}
6448 };
6449
6450 static const value_string device_type_vals[] = {
6451         {0x00000001,    "Beep"},
6452         {0x00000002,    "CDROM"},
6453         {0x00000003,    "CDROM Filesystem"},
6454         {0x00000004,    "Controller"},
6455         {0x00000005,    "Datalink"},
6456         {0x00000006,    "Dfs"},
6457         {0x00000007,    "Disk"},
6458         {0x00000008,    "Disk Filesystem"},
6459         {0x00000009,    "Filesystem"},
6460         {0x0000000a,    "Inport Port"},
6461         {0x0000000b,    "Keyboard"},
6462         {0x0000000c,    "Mailslot"},
6463         {0x0000000d,    "MIDI-In"},
6464         {0x0000000e,    "MIDI-Out"},
6465         {0x0000000f,    "Mouse"},
6466         {0x00000010,    "Multi UNC Provider"},
6467         {0x00000011,    "Named Pipe"},
6468         {0x00000012,    "Network"},
6469         {0x00000013,    "Network Browser"},
6470         {0x00000014,    "Network Filesystem"},
6471         {0x00000015,    "NULL"},
6472         {0x00000016,    "Parallel Port"},
6473         {0x00000017,    "Physical card"},
6474         {0x00000018,    "Printer"},
6475         {0x00000019,    "Scanner"},
6476         {0x0000001a,    "Serial Mouse port"},
6477         {0x0000001b,    "Serial port"},
6478         {0x0000001c,    "Screen"},
6479         {0x0000001d,    "Sound"},
6480         {0x0000001e,    "Streams"},
6481         {0x0000001f,    "Tape"},
6482         {0x00000020,    "Tape Filesystem"},
6483         {0x00000021,    "Transport"},
6484         {0x00000022,    "Unknown"},
6485         {0x00000023,    "Video"},
6486         {0x00000024,    "Virtual Disk"},
6487         {0x00000025,    "WAVE-In"},
6488         {0x00000026,    "WAVE-Out"},
6489         {0x00000027,    "8042 Port"},
6490         {0x00000028,    "Network Redirector"},
6491         {0x00000029,    "Battery"},
6492         {0x0000002a,    "Bus Extender"},
6493         {0x0000002b,    "Modem"},
6494         {0x0000002c,    "VDM"},
6495         {0,     NULL}
6496 };
6497
6498 static const value_string is_directory_vals[] = {
6499         {0,     "This is NOT a directory"},
6500         {1,     "This is a DIRECTORY"},
6501         {0, NULL}
6502 };
6503
6504 typedef struct _nt_trans_data {
6505         int subcmd;
6506         guint32 sd_len;
6507         guint32 ea_len;
6508 } nt_trans_data;
6509
6510
6511
6512 static int
6513 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6514 {
6515         guint8 mask;
6516         proto_item *item = NULL;
6517         proto_tree *tree = NULL;
6518
6519         mask = tvb_get_guint8(tvb, offset);
6520
6521         if(parent_tree){
6522                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6523                         "Security Flags: 0x%02x", mask);
6524                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6525         }
6526
6527         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6528                 tvb, offset, 1, mask);
6529         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6530                 tvb, offset, 1, mask);
6531
6532         offset += 1;
6533
6534         return offset;
6535 }
6536
6537 static int
6538 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6539 {
6540         guint32 mask;
6541         proto_item *item = NULL;
6542         proto_tree *tree = NULL;
6543
6544         mask = tvb_get_letohl(tvb, offset);
6545
6546         if(parent_tree){
6547                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6548                         "Share Access: 0x%08x", mask);
6549                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6550         }
6551
6552         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6553                 tvb, offset, 4, mask);
6554         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6555                 tvb, offset, 4, mask);
6556         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6557                 tvb, offset, 4, mask);
6558
6559         offset += 4;
6560
6561         return offset;
6562 }
6563
6564
6565 static int
6566 dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6567 {
6568         guint32 mask;
6569         proto_item *item = NULL;
6570         proto_tree *tree = NULL;
6571
6572         mask = tvb_get_letohl(tvb, offset);
6573
6574         if(parent_tree){
6575                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6576                         "Access Mask: 0x%08x", mask);
6577                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6578         }
6579
6580         /*
6581          * Some of these bits come from 
6582          *
6583          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6584          *
6585          * and others come from the section on ZwOpenFile in "Windows(R)
6586          * NT(R)/2000 Native API Reference".
6587          */
6588         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6589                 tvb, offset, 4, mask);
6590         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6591                 tvb, offset, 4, mask);
6592         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6593                 tvb, offset, 4, mask);
6594         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6595                 tvb, offset, 4, mask);
6596         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6597                 tvb, offset, 4, mask);
6598         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6599                 tvb, offset, 4, mask);
6600         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6601                 tvb, offset, 4, mask);
6602         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6603                 tvb, offset, 4, mask);
6604         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6605                 tvb, offset, 4, mask);
6606         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6607                 tvb, offset, 4, mask);
6608         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6609                 tvb, offset, 4, mask);
6610         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6611                 tvb, offset, 4, mask);
6612         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6613                 tvb, offset, 4, mask);
6614         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6615                 tvb, offset, 4, mask);
6616         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6617                 tvb, offset, 4, mask);
6618         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6619                 tvb, offset, 4, mask);
6620         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6621                 tvb, offset, 4, mask);
6622         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6623                 tvb, offset, 4, mask);
6624         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6625                 tvb, offset, 4, mask);
6626         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6627                 tvb, offset, 4, mask);
6628
6629         offset += 4;
6630
6631         return offset;
6632 }
6633
6634 static int
6635 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6636 {
6637         guint32 mask;
6638         proto_item *item = NULL;
6639         proto_tree *tree = NULL;
6640
6641         mask = tvb_get_letohl(tvb, offset);
6642
6643         if(parent_tree){
6644                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6645                         "Create Flags: 0x%08x", mask);
6646                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6647         }
6648
6649         /*
6650          * XXX - it's 0x00000016 in at least one capture, but
6651          * Network Monitor doesn't say what the 0x00000010 bit is.
6652          * Does the Win32 API documentation, or NT Native API book,
6653          * suggest anything?
6654          */
6655         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6656                 tvb, offset, 4, mask);
6657         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6658                 tvb, offset, 4, mask);
6659         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6660                 tvb, offset, 4, mask);
6661
6662         offset += 4;
6663
6664         return offset;
6665 }
6666
6667 /*
6668  * XXX - there are some more flags in the description of "ZwOpenFile()"
6669  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6670  * the wire as well?  (The spec at
6671  *
6672  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6673  *
6674  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6675  * via the SMB protocol.  The NT redirector should convert this option
6676  * to FILE_WRITE_THROUGH."
6677  *
6678  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6679  * values one would infer from their position in the list of flags for
6680  * "ZwOpenFile()".  Most of the others probably have those values
6681  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6682  * which might go over the wire (for the benefit of backup/restore software).
6683  */
6684 static const true_false_string tfs_nt_create_options_directory = {
6685         "File being created/opened must be a directory",
6686         "File being created/opened must not be a directory"
6687 };
6688 static const true_false_string tfs_nt_create_options_write_through = {
6689         "Writes should flush buffered data before completing",
6690         "Writes need not flush buffered data before completing"
6691 };
6692 static const true_false_string tfs_nt_create_options_sequential_only = {
6693         "The file will only be accessed sequentially",
6694         "The file might not only be accessed sequentially"
6695 };
6696 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6697         "All operations SYNCHRONOUS, waits subject to termination from alert",
6698         "Operations NOT necessarily synchronous"
6699 };
6700 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6701         "All operations SYNCHRONOUS, waits not subject to alert",
6702         "Operations NOT necessarily synchronous"
6703 };
6704 static const true_false_string tfs_nt_create_options_non_directory = {
6705         "File being created/opened must not be a directory",
6706         "File being created/opened must be a directory"
6707 };
6708 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6709         "The client does not understand extended attributes",
6710         "The client understands extended attributes"
6711 };
6712 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6713         "The client understands only 8.3 file names",
6714         "The client understands long file names"
6715 };
6716 static const true_false_string tfs_nt_create_options_random_access = {
6717         "The file will be accessed randomly",
6718         "The file will not be accessed randomly"
6719 };
6720 static const true_false_string tfs_nt_create_options_delete_on_close = {
6721         "The file should be deleted when it is closed",
6722         "The file should not be deleted when it is closed"
6723 };
6724
6725 static int
6726 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6727 {
6728         guint32 mask;
6729         proto_item *item = NULL;
6730         proto_tree *tree = NULL;
6731
6732         mask = tvb_get_letohl(tvb, offset);
6733
6734         if(parent_tree){
6735                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6736                         "Create Options: 0x%08x", mask);
6737                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6738         }
6739
6740         /*
6741          * From
6742          *
6743          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6744          */
6745         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6746                 tvb, offset, 4, mask);
6747         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6748                 tvb, offset, 4, mask);
6749         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6750                 tvb, offset, 4, mask);
6751         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6752                 tvb, offset, 4, mask);
6753         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6754                 tvb, offset, 4, mask);
6755         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6756                 tvb, offset, 4, mask);
6757         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6758                 tvb, offset, 4, mask);
6759         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6760                 tvb, offset, 4, mask);
6761         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6762                 tvb, offset, 4, mask);
6763         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6764                 tvb, offset, 4, mask);
6765
6766         offset += 4;
6767
6768         return offset;
6769 }
6770  
6771 static int
6772 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6773 {
6774         guint32 mask;
6775         proto_item *item = NULL;
6776         proto_tree *tree = NULL;
6777
6778         mask = tvb_get_letohl(tvb, offset);
6779
6780         if(parent_tree){
6781                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6782                         "Completion Filter: 0x%08x", mask);
6783                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6784         }
6785  
6786         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6787                 tvb, offset, 4, mask);
6788         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6789                 tvb, offset, 4, mask);
6790         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6791                 tvb, offset, 4, mask);
6792         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6793                 tvb, offset, 4, mask);
6794         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6795                 tvb, offset, 4, mask);
6796         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6797                 tvb, offset, 4, mask);
6798         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6799                 tvb, offset, 4, mask);
6800         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6801                 tvb, offset, 4, mask);
6802         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6803                 tvb, offset, 4, mask);
6804         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6805                 tvb, offset, 4, mask);
6806         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6807                 tvb, offset, 4, mask);
6808         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6809                 tvb, offset, 4, mask);
6810
6811         offset += 4;
6812         return offset;
6813 }
6814  
6815 static int
6816 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6817 {
6818         guint8 mask;
6819         proto_item *item = NULL;
6820         proto_tree *tree = NULL;
6821
6822         mask = tvb_get_guint8(tvb, offset);
6823
6824         if(parent_tree){
6825                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6826                         "Completion Filter: 0x%02x", mask);
6827                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6828         }
6829
6830         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6831                 tvb, offset, 1, mask);
6832
6833         offset += 1;
6834         return offset;
6835 }
6836
6837 /*
6838  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6839  * Native API Reference".
6840  */
6841 static const true_false_string tfs_nt_qsd_owner = {
6842         "Requesting OWNER security information",
6843         "NOT requesting owner security information",
6844 };
6845
6846 static const true_false_string tfs_nt_qsd_group = {
6847         "Requesting GROUP security information",
6848         "NOT requesting group security information",
6849 };
6850
6851 static const true_false_string tfs_nt_qsd_dacl = {
6852         "Requesting DACL security information",
6853         "NOT requesting DACL security information",
6854 };
6855
6856 static const true_false_string tfs_nt_qsd_sacl = {
6857         "Requesting SACL security information",
6858         "NOT requesting SACL security information",
6859 };
6860
6861 #define NT_QSD_OWNER    0x00000001
6862 #define NT_QSD_GROUP    0x00000002
6863 #define NT_QSD_DACL     0x00000004
6864 #define NT_QSD_SACL     0x00000008
6865
6866 static int
6867 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6868 {
6869         guint32 mask;
6870         proto_item *item = NULL;
6871         proto_tree *tree = NULL;
6872
6873         mask = tvb_get_letohl(tvb, offset);
6874
6875         if(parent_tree){
6876                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6877                         "Security Information: 0x%08x", mask);
6878                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6879         }
6880
6881         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6882                 tvb, offset, 4, mask);
6883         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6884                 tvb, offset, 4, mask);
6885         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6886                 tvb, offset, 4, mask);
6887         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6888                 tvb, offset, 4, mask);
6889
6890         offset += 4;
6891
6892         return offset;
6893 }
6894
6895 static void
6896 free_g_string(void *arg)
6897 {
6898         g_string_free(arg, TRUE);
6899 }
6900
6901 int
6902 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
6903 {
6904         proto_item *item = NULL;
6905         proto_tree *tree = NULL;
6906         int old_offset = offset, sa_offset = offset;
6907         guint rid;
6908         guint8 revision;
6909         guint8 num_auth;
6910         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6911         int i;
6912         GString *gstr;
6913
6914         if(parent_tree){
6915                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6916                                            "NT %s SID", name);
6917                 tree = proto_item_add_subtree(item, ett_smb_sid);
6918         }
6919
6920         /* revision of sid */
6921         revision = tvb_get_guint8(tvb, offset);
6922         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6923         offset += 1;
6924
6925         switch(revision){
6926         case 1:  
6927         case 2:  /* Not sure what the different revision numbers mean */
6928           /* number of authorities*/
6929           num_auth = tvb_get_guint8(tvb, offset);
6930           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6931           offset += 1;
6932
6933           /* XXX perhaps we should have these thing searchable?
6934              a new FT_xxx thingie? SMB is quite common!*/
6935           /* identifier authorities */
6936
6937           for(i=0;i<6;i++){
6938             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
6939
6940             offset++;
6941           }
6942
6943           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
6944
6945           sa_offset = offset;
6946
6947           gstr = g_string_new("");
6948           
6949           CLEANUP_PUSH(free_g_string, gstr);
6950
6951           /* sub authorities, leave RID to last */
6952           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
6953             /*
6954              * XXX should not be letohl but native byteorder according to
6955              * Samba header files.
6956              *
6957              * However, considering that there were never any NT ports
6958              * to big-endian platforms (PowerPC and MIPS ran little-endian,
6959              * and IA-64 runs little-endian, as does x86-64), we can (?)
6960              * assume that non le byte encodings will be "uncommon"?
6961              */
6962              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
6963                   tvb_get_letohl(tvb, offset));
6964              offset+=4;
6965           }
6966
6967           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
6968
6969           if (num_auth > 4) {
6970             rid = tvb_get_letohl(tvb, offset);
6971             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
6972             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
6973             offset+=4;
6974           }
6975           else {
6976             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
6977           }
6978
6979           CLEANUP_CALL_AND_POP;
6980
6981         }
6982
6983         proto_item_set_len(item, offset-old_offset);
6984         return offset;
6985 }
6986
6987
6988 static const value_string ace_type_vals[] = {
6989   { 0, "Access Allowed"},
6990   { 1, "Access Denied"},
6991   { 2, "System Audit"},
6992   { 3, "System Alarm"},
6993   { 0, NULL}
6994 };
6995 static const true_false_string tfs_ace_flags_object_inherit = {
6996   "Subordinate files will inherit this ACE",
6997   "Subordinate files will not inherit this ACE"
6998 };
6999 static const true_false_string tfs_ace_flags_container_inherit = {
7000   "Subordinate containers will inherit this ACE",
7001   "Subordinate containers will not inherit this ACE"
7002 };
7003 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7004   "Subordinate object will not propagate the inherited ACE further",
7005   "Subordinate object will propagate the inherited ACE further"
7006 };
7007 static const true_false_string tfs_ace_flags_inherit_only = {
7008   "This ACE does not apply to the current object",
7009   "This ACE applies to the current object"
7010 };
7011 static const true_false_string tfs_ace_flags_inherited_ace = {
7012   "This ACE was inherited from its parent object",
7013   "This ACE was not inherited from its parent object"
7014 };
7015 static const true_false_string tfs_ace_flags_successful_access = {
7016   "Successful accesses will be audited",
7017   "Successful accesses will not be audited"
7018 };
7019 static const true_false_string tfs_ace_flags_failed_access = {
7020   "Failed accesses will be audited",
7021   "Failed accesses will not be audited"
7022 };
7023
7024 #define APPEND_ACE_TEXT(flag, item, string) \
7025         if(flag){                                                       \
7026                 if(item)                                                \
7027                         proto_item_append_text(item, string, sep);      \
7028                 sep = ", ";                                             \
7029         }
7030
7031 static int
7032 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7033 {
7034         proto_item *item = NULL;
7035         proto_tree *tree = NULL;
7036         guint8 mask;
7037         char *sep = " ";
7038
7039         mask = tvb_get_guint8(tvb, offset);
7040         if(parent_tree){
7041                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7042                                            "NT ACE Flags: 0x%02x", mask);
7043                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7044         }
7045
7046         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7047                        tvb, offset, 1, mask);
7048         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7049
7050         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7051                        tvb, offset, 1, mask);
7052         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7053
7054         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7055                        tvb, offset, 1, mask);
7056         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7057
7058         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7059                        tvb, offset, 1, mask);
7060         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7061
7062         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7063                        tvb, offset, 1, mask);
7064         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7065
7066         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7067                        tvb, offset, 1, mask);
7068         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7069
7070         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7071                        tvb, offset, 1, mask);
7072         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7073
7074
7075         offset += 1;
7076         return offset;
7077 }
7078
7079 static int
7080 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7081 {
7082         proto_item *item = NULL;
7083         proto_tree *tree = NULL;
7084         int old_offset = offset;
7085         guint16 size;
7086         
7087         if(parent_tree){
7088                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7089                                            "NT ACE: ");
7090                 tree = proto_item_add_subtree(item, ett_smb_ace);
7091         }
7092
7093         /* type */
7094         if(item){
7095           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
7096         }
7097         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
7098         offset += 1;
7099
7100         /* flags */
7101         offset = dissect_nt_v2_ace_flags(tvb, offset, tree);
7102
7103         /* size */
7104         size = tvb_get_letohs(tvb, offset);
7105         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7106         offset += 2;
7107
7108         /* access mask */
7109         offset = dissect_nt_access_mask(tvb, tree, offset);
7110
7111         /* SID */
7112         offset = dissect_nt_sid(tvb, offset, tree, "ACE");
7113
7114         proto_item_set_len(item, offset-old_offset);
7115
7116         /* Sometimes there is some spare space at the end of the ACE so use
7117            the size field to work out where the end is. */
7118
7119         return old_offset + size;
7120 }
7121
7122 static int
7123 dissect_nt_acl(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
7124 {
7125         proto_item *item = NULL;
7126         proto_tree *tree = NULL;
7127         int old_offset = offset;
7128         guint16 revision;
7129         guint32 num_aces;
7130
7131         if(parent_tree){
7132                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7133                                            "NT %s ACL", name);
7134                 tree = proto_item_add_subtree(item, ett_smb_acl);
7135         }
7136
7137         /* revision */
7138         revision = tvb_get_letohs(tvb, offset);
7139         proto_tree_add_uint(tree, hf_smb_acl_revision,
7140                 tvb, offset, 2, revision);
7141         offset += 2;
7142
7143         switch(revision){
7144         case 2:  /* only version we will ever see of this structure?*/
7145         case 3:
7146           /* size */
7147           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7148           offset += 2;
7149
7150           /* number of ace structures */
7151           num_aces = tvb_get_letohl(tvb, offset);
7152           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7153                               tvb, offset, 4, num_aces);
7154           offset += 4;
7155
7156           while(num_aces--){
7157             offset=dissect_nt_v2_ace(tvb, offset, tree);
7158           }
7159         }
7160
7161         proto_item_set_len(item, offset-old_offset);
7162         return offset;
7163 }
7164
7165 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7166   "OWNER is DEFAULTED",
7167   "Owner is NOT defaulted"
7168 };
7169 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7170   "GROUP is DEFAULTED",
7171   "Group is NOT defaulted"
7172 };
7173 static const true_false_string tfs_sec_desc_type_dacl_present = {
7174   "DACL is PRESENT",
7175   "DACL is NOT present"
7176 };
7177 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7178   "DACL is DEFAULTED",
7179   "DACL is NOT defaulted"
7180 };
7181 static const true_false_string tfs_sec_desc_type_sacl_present = {
7182   "SACL is PRESENT",
7183   "SACL is NOT present"
7184 };
7185 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7186   "SACL is DEFAULTED",
7187   "SACL is NOT defaulted"
7188 };
7189 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7190   "DACL has AUTO INHERIT REQUIRED",
7191   "DACL does NOT require auto inherit"
7192 };
7193 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7194   "SACL has AUTO INHERIT REQUIRED",
7195   "SACL does NOT require auto inherit"
7196 };
7197 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7198   "DACL is AUTO INHERITED",
7199   "DACL is NOT auto inherited"
7200 };
7201 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7202   "SACL is AUTO INHERITED",
7203   "SACL is NOT auto inherited"
7204 };
7205 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7206   "The DACL is PROTECTED",
7207   "The DACL is NOT protected"
7208 };
7209 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7210   "The SACL is PROTECTED",
7211   "The SACL is NOT protected"
7212 };
7213 static const true_false_string tfs_sec_desc_type_self_relative = {
7214   "This SecDesc is SELF RELATIVE",
7215   "This SecDesc is NOT self relative"
7216 };
7217
7218
7219 static int
7220 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7221 {
7222         proto_item *item = NULL;
7223         proto_tree *tree = NULL;
7224         guint16 mask;
7225
7226         mask = tvb_get_letohs(tvb, offset);
7227         if(parent_tree){
7228                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7229                                            "Type: 0x%04x", mask);
7230                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7231         }
7232
7233         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7234                                tvb, offset, 2, mask);
7235         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7236                                tvb, offset, 2, mask);
7237         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7238                                tvb, offset, 2, mask);
7239         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7240                                tvb, offset, 2, mask);
7241         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7242                                tvb, offset, 2, mask);
7243         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7244                                tvb, offset, 2, mask);
7245         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7246                                tvb, offset, 2, mask);
7247         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7248                                tvb, offset, 2, mask);
7249         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7250                                tvb, offset, 2, mask);
7251         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7252                                tvb, offset, 2, mask);
7253         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7254                                tvb, offset, 2, mask);
7255         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7256                                tvb, offset, 2, mask);
7257         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7258                                tvb, offset, 2, mask);
7259
7260
7261         offset += 2;
7262         return offset;
7263 }
7264
7265 int
7266 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, int len)
7267 {
7268         proto_item *item = NULL;
7269         proto_tree *tree = NULL;
7270         guint16 revision;
7271         int old_offset = offset;
7272         guint32 owner_sid_offset;
7273         guint32 group_sid_offset;
7274         guint32 sacl_offset;
7275         guint32 dacl_offset;
7276
7277         if(parent_tree){
7278                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7279                                            "NT Security Descriptor");
7280                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7281         }
7282
7283         /* revision */
7284         revision = tvb_get_letohs(tvb, offset);
7285         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7286                 tvb, offset, 2, revision);
7287         offset += 2;
7288
7289         switch(revision){
7290         case 1:  /* only version we will ever see of this structure?*/
7291           /* type */
7292           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7293
7294           /* offset to owner sid */
7295           owner_sid_offset = tvb_get_letohl(tvb, offset);
7296           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
7297           offset += 4;
7298
7299           /* offset to group sid */
7300           group_sid_offset = tvb_get_letohl(tvb, offset);
7301           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
7302           offset += 4;
7303
7304           /* offset to sacl */
7305           sacl_offset = tvb_get_letohl(tvb, offset);
7306           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
7307           offset += 4;
7308
7309           /* offset to dacl */
7310           dacl_offset = tvb_get_letohl(tvb, offset);
7311           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
7312           offset += 4;
7313
7314           /*owner SID*/
7315           if(owner_sid_offset){
7316             if (len == -1)
7317               offset = dissect_nt_sid(tvb, offset, tree, "Owner");
7318             else
7319               dissect_nt_sid(tvb, old_offset+owner_sid_offset, tree, "Owner");
7320           }
7321
7322           /*group SID*/
7323           if(group_sid_offset){
7324             dissect_nt_sid(tvb, old_offset+group_sid_offset, tree, "Group");
7325           }
7326
7327           /* sacl */
7328           if(sacl_offset){
7329             dissect_nt_acl(tvb, old_offset+sacl_offset, tree, "System (SACL)");
7330           }
7331
7332           /* dacl */
7333           if(dacl_offset){
7334             dissect_nt_acl(tvb, old_offset+dacl_offset, tree, "User (DACL)");
7335           }
7336
7337         }
7338
7339         return offset+len;
7340 }
7341
7342 static int
7343 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7344 {
7345         int old_offset, old_sid_offset;
7346         guint32 qsize;
7347
7348         do {
7349                 old_offset=offset;
7350
7351                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7352                 qsize=tvb_get_letohl(tvb, offset);
7353                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7354                 COUNT_BYTES_TRANS_SUBR(4);
7355
7356                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7357                 /* length of SID */
7358                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7359                 COUNT_BYTES_TRANS_SUBR(4);
7360
7361                 /* 16 unknown bytes */
7362                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7363                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7364                             offset, 8, TRUE);
7365                 COUNT_BYTES_TRANS_SUBR(8);
7366
7367                 /* number of bytes for used quota */
7368                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7369                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7370                 COUNT_BYTES_TRANS_SUBR(8);
7371
7372                 /* number of bytes for quota warning */
7373                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7374                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7375                 COUNT_BYTES_TRANS_SUBR(8);
7376
7377                 /* number of bytes for quota limit */
7378                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7379                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7380                 COUNT_BYTES_TRANS_SUBR(8);
7381
7382                 /* SID of the user */
7383                 old_sid_offset=offset;
7384                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7385                 *bcp -= (offset-old_sid_offset);
7386
7387                 if(qsize){
7388                         offset = old_offset+qsize;
7389                 }
7390         }while(qsize);
7391
7392
7393         return offset;
7394 }
7395
7396
7397 static int
7398 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7399 {
7400         proto_item *item = NULL;
7401         proto_tree *tree = NULL;
7402         smb_info_t *si;
7403         int old_offset = offset;
7404         guint16 bcp=bc; /* XXX fixme */
7405
7406         si = (smb_info_t *)pinfo->private_data;
7407
7408         if(parent_tree){
7409                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7410                                 "%s Data",
7411                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7412                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7413         }
7414
7415         switch(ntd->subcmd){
7416         case NT_TRANS_CREATE:
7417                 /* security descriptor */
7418                 if(ntd->sd_len){
7419                         offset = dissect_nt_sec_desc(tvb, offset, tree, ntd->sd_len);
7420                 }
7421
7422                 /* extended attributes */
7423                 if(ntd->ea_len){
7424                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7425                         offset += ntd->ea_len;
7426                 }
7427
7428                 break;
7429         case NT_TRANS_IOCTL:
7430                 /* ioctl data */
7431                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7432                 offset += bc;
7433
7434                 break;
7435         case NT_TRANS_SSD:
7436                 offset = dissect_nt_sec_desc(tvb, offset, tree, bc);
7437                 break;
7438         case NT_TRANS_NOTIFY:
7439                 break;
7440         case NT_TRANS_RENAME:
7441                 /* XXX not documented */
7442                 break;
7443         case NT_TRANS_QSD:
7444                 break;
7445         case NT_TRANS_GET_USER_QUOTA:
7446                 /* unknown 4 bytes */
7447                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7448                             offset, 4, TRUE);
7449                 offset += 4;
7450
7451                 /* length of SID */
7452                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7453                 offset +=4;
7454
7455                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7456                 break;
7457         case NT_TRANS_SET_USER_QUOTA:
7458                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7459                 break;
7460         }
7461
7462         /* ooops there were data we didnt know how to process */
7463         if((offset-old_offset) < bc){
7464                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7465                     bc - (offset-old_offset), TRUE);
7466                 offset += bc - (offset-old_offset);
7467         }
7468
7469         return offset;
7470 }
7471
7472 static int
7473 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)
7474 {
7475         proto_item *item = NULL;
7476         proto_tree *tree = NULL;
7477         smb_info_t *si;
7478         guint32 fn_len;
7479         const char *fn;
7480
7481         si = (smb_info_t *)pinfo->private_data;
7482
7483         if(parent_tree){
7484                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7485                                 "%s Parameters",
7486                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7487                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7488         }
7489
7490         switch(ntd->subcmd){
7491         case NT_TRANS_CREATE:
7492                 /* Create flags */
7493                 offset = dissect_nt_create_bits(tvb, tree, offset);
7494                 bc -= 4;
7495
7496                 /* root directory fid */
7497                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7498                 COUNT_BYTES(4);
7499
7500                 /* nt access mask */
7501                 offset = dissect_nt_access_mask(tvb, tree, offset);
7502                 bc -= 4;
7503         
7504                 /* allocation size */
7505                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7506                 COUNT_BYTES(8);
7507         
7508                 /* Extended File Attributes */
7509                 offset = dissect_file_ext_attr(tvb, tree, offset);
7510                 bc -= 4;
7511
7512                 /* share access */
7513                 offset = dissect_nt_share_access(tvb, tree, offset);
7514                 bc -= 4;
7515         
7516                 /* create disposition */
7517                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7518                 COUNT_BYTES(4);
7519
7520                 /* create options */
7521                 offset = dissect_nt_create_options(tvb, tree, offset);
7522                 bc -= 4;
7523
7524                 /* sd length */
7525                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7526                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7527                 COUNT_BYTES(4);
7528
7529                 /* ea length */
7530                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7531                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7532                 COUNT_BYTES(4);
7533
7534                 /* file name len */
7535                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7536                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7537                 COUNT_BYTES(4);
7538
7539                 /* impersonation level */
7540                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7541                 COUNT_BYTES(4);
7542         
7543                 /* security flags */
7544                 offset = dissect_nt_security_flags(tvb, tree, offset);
7545                 bc -= 1;
7546
7547                 /* file name */
7548                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7549                 if (fn != NULL) {
7550                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7551                                 fn);
7552                         COUNT_BYTES(fn_len);
7553                 }
7554
7555                 break;
7556         case NT_TRANS_IOCTL:
7557                 break;
7558         case NT_TRANS_SSD: {
7559                 guint16 fid;
7560
7561                 /* fid */
7562                 fid = tvb_get_letohs(tvb, offset);
7563                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7564                 offset += 2;
7565
7566                 /* 2 reserved bytes */
7567                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7568                 offset += 2;
7569
7570                 /* security information */
7571                 offset = dissect_security_information_mask(tvb, tree, offset);
7572                 break;
7573         }
7574         case NT_TRANS_NOTIFY:
7575                 break;
7576         case NT_TRANS_RENAME:
7577                 /* XXX not documented */
7578                 break;
7579         case NT_TRANS_QSD: {
7580                 guint16 fid;
7581
7582                 /* fid */
7583                 fid = tvb_get_letohs(tvb, offset);
7584                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7585                 offset += 2;
7586
7587                 /* 2 reserved bytes */
7588                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7589                 offset += 2;
7590
7591                 /* security information */
7592                 offset = dissect_security_information_mask(tvb, tree, offset);
7593                 break;
7594         }
7595         case NT_TRANS_GET_USER_QUOTA:
7596                 /* not decoded yet */
7597                 break;
7598         case NT_TRANS_SET_USER_QUOTA:
7599                 /* not decoded yet */
7600                 break;
7601         }
7602
7603         return offset;
7604 }
7605
7606 static int
7607 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7608 {
7609         proto_item *item = NULL;
7610         proto_tree *tree = NULL;
7611         smb_info_t *si;
7612         int old_offset = offset;
7613
7614         si = (smb_info_t *)pinfo->private_data;
7615
7616         if(parent_tree){
7617                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7618                                 "%s Setup",
7619                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7620                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7621         }
7622  
7623         switch(ntd->subcmd){
7624         case NT_TRANS_CREATE:
7625                 break;
7626         case NT_TRANS_IOCTL: {
7627                 guint16 fid;
7628
7629                 /* function code */
7630                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7631                 offset += 4;
7632
7633                 /* fid */
7634                 fid = tvb_get_letohs(tvb, offset);
7635                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7636                 offset += 2;
7637
7638                 /* isfsctl */
7639                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7640                 offset += 1;
7641
7642                 /* isflags */
7643                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
7644
7645                 break;
7646         }
7647         case NT_TRANS_SSD:
7648                 break;
7649         case NT_TRANS_NOTIFY: {
7650                 guint16 fid;
7651
7652                 /* completion filter */
7653                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
7654
7655                 /* fid */
7656                 fid = tvb_get_letohs(tvb, offset);
7657                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7658                 offset += 2;
7659
7660                 /* watch tree */
7661                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7662                 offset += 1;
7663
7664                 /* reserved byte */
7665                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7666                 offset += 1;
7667
7668                 break;
7669         }
7670         case NT_TRANS_RENAME:
7671                 /* XXX not documented */
7672                 break;
7673         case NT_TRANS_QSD:
7674                 break;
7675         case NT_TRANS_GET_USER_QUOTA:
7676                 /* not decoded yet */
7677                 break;
7678         case NT_TRANS_SET_USER_QUOTA:
7679                 /* not decoded yet */
7680                 break;
7681         }
7682  
7683         return old_offset+len;
7684 }
7685
7686
7687 static int
7688 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
7689 {
7690         guint8 wc, sc;
7691         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7692         smb_info_t *si;
7693         smb_saved_info_t *sip;
7694         int subcmd;
7695         nt_trans_data ntd;
7696         guint16 bc;
7697         int padcnt;
7698         smb_nt_transact_info_t *nti;
7699
7700         si = (smb_info_t *)pinfo->private_data;
7701         sip = si->sip;
7702
7703         WORD_COUNT;
7704
7705         if(wc>=19){
7706                 /* primary request */
7707                 /* max setup count */
7708                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7709                 offset += 1;
7710
7711                 /* 2 reserved bytes */
7712                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7713                 offset += 2;
7714         } else {
7715                 /* secondary request */
7716                 /* 3 reserved bytes */
7717                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7718                 offset += 3;
7719         }
7720
7721
7722         /* total param count */
7723         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7724         offset += 4;
7725         
7726         /* total data count */
7727         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7728         offset += 4;
7729
7730         if(wc>=19){
7731                 /* primary request */
7732                 /* max param count */
7733                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7734                 offset += 4;
7735
7736                 /* max data count */
7737                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7738                 offset += 4;
7739         }
7740
7741         /* param count */
7742         pc = tvb_get_letohl(tvb, offset);
7743         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7744         offset += 4;
7745         
7746         /* param offset */
7747         po = tvb_get_letohl(tvb, offset);
7748         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7749         offset += 4;
7750
7751         /* param displacement */
7752         if(wc>=19){
7753                 /* primary request*/
7754                 pd = 0;
7755         } else {
7756                 /* secondary request */
7757                 pd = tvb_get_letohl(tvb, offset);
7758                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7759                 offset += 4;
7760         }
7761
7762         /* data count */
7763         dc = tvb_get_letohl(tvb, offset);
7764         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7765         offset += 4;
7766
7767         /* data offset */
7768         od = tvb_get_letohl(tvb, offset);
7769         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7770         offset += 4;
7771
7772         /* data displacement */
7773         if(wc>=19){
7774                 /* primary request */
7775                 dd = 0;
7776         } else {
7777                 /* secondary request */
7778                 dd = tvb_get_letohl(tvb, offset);
7779                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7780                 offset += 4;
7781         }
7782
7783         /* setup count */
7784         if(wc>=19){
7785                 /* primary request */
7786                 sc = tvb_get_guint8(tvb, offset);
7787                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7788                 offset += 1;
7789         } else {
7790                 /* secondary request */
7791                 sc = 0;
7792         }
7793
7794         /* function */
7795         if(wc>=19){
7796                 /* primary request */
7797                 subcmd = tvb_get_letohs(tvb, offset);
7798                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7799                 if(check_col(pinfo->cinfo, COL_INFO)){
7800                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7801                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7802                 }
7803                 ntd.subcmd = subcmd;
7804                 if (!si->unidir) {
7805                         if(!pinfo->fd->flags.visited){
7806                                 /* 
7807                                  * Allocate a new smb_nt_transact_info_t
7808                                  * structure.
7809                                  */
7810                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7811                                 nti->subcmd = subcmd;
7812                                 sip->extra_info = nti;
7813                         }
7814                 }
7815         } else {
7816                 /* secondary request */
7817                 if(check_col(pinfo->cinfo, COL_INFO)){
7818                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7819                 }
7820         }
7821         offset += 2;
7822
7823         /* this is a padding byte */
7824         if(offset%1){
7825                 /* pad byte */
7826                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7827                 offset += 1;
7828         }
7829
7830         /* if there were any setup bytes, decode them */
7831         if(sc){
7832                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7833                 offset += sc*2;
7834         }
7835
7836         BYTE_COUNT;
7837         
7838         /* parameters */
7839         if(po>(guint32)offset){
7840                 /* We have some initial padding bytes.
7841                 */
7842                 padcnt = po-offset;
7843                 if (padcnt > bc)
7844                         padcnt = bc;
7845                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7846                 COUNT_BYTES(padcnt);
7847         }
7848         if(pc){
7849                 CHECK_BYTE_COUNT(pc);
7850                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7851                 COUNT_BYTES(pc);
7852         }
7853
7854         /* data */
7855         if(od>(guint32)offset){
7856                 /* We have some initial padding bytes.
7857                 */
7858                 padcnt = od-offset;
7859                 if (padcnt > bc)
7860                         padcnt = bc;
7861                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7862                 COUNT_BYTES(padcnt);
7863         }
7864         if(dc){
7865                 CHECK_BYTE_COUNT(dc);
7866                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7867                 COUNT_BYTES(dc);
7868         }
7869
7870         END_OF_SMB
7871
7872         return offset;
7873 }
7874
7875
7876
7877 static int
7878 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7879 {
7880         proto_item *item = NULL;
7881         proto_tree *tree = NULL;
7882         smb_info_t *si;
7883         smb_nt_transact_info_t *nti;
7884         guint16 bcp;
7885
7886         si = (smb_info_t *)pinfo->private_data;
7887         if (si->sip != NULL)
7888                 nti = si->sip->extra_info;
7889         else
7890                 nti = NULL;
7891
7892         if(parent_tree){
7893                 if(nti != NULL){
7894                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7895                                 "%s Data",
7896                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7897                 } else {
7898                         /*
7899                          * We never saw the request to which this is a
7900                          * response.
7901                          */
7902                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7903                                 "Unknown NT Transaction Data (matching request not seen)");
7904                 }
7905                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7906         }
7907
7908         if (nti == NULL) {
7909                 offset += len;
7910                 return offset;
7911         }
7912         switch(nti->subcmd){
7913         case NT_TRANS_CREATE:
7914                 break;
7915         case NT_TRANS_IOCTL:
7916                 /* ioctl data */
7917                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7918                 offset += len;
7919
7920                 break;
7921         case NT_TRANS_SSD:
7922                 break;
7923         case NT_TRANS_NOTIFY:
7924                 break;
7925         case NT_TRANS_RENAME:
7926                 /* XXX not documented */
7927                 break;
7928         case NT_TRANS_QSD:
7929                 /*
7930                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7931                  * which may be documented in the Win32 documentation
7932                  * somewhere.
7933                  */
7934                 offset = dissect_nt_sec_desc(tvb, offset, tree, len);
7935                 break;
7936         case NT_TRANS_GET_USER_QUOTA:
7937                 bcp=len;
7938                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7939                 break;
7940         case NT_TRANS_SET_USER_QUOTA:
7941                 /* not decoded yet */
7942                 break;
7943         }
7944
7945         return offset;
7946 }
7947  
7948 static int
7949 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)
7950 {
7951         proto_item *item = NULL;
7952         proto_tree *tree = NULL;
7953         guint32 fn_len;
7954         const char *fn;
7955         smb_info_t *si;
7956         smb_nt_transact_info_t *nti;
7957         guint16 fid;
7958         int old_offset;
7959         guint32 neo;
7960         int padcnt;
7961
7962         si = (smb_info_t *)pinfo->private_data;
7963         if (si->sip != NULL)
7964                 nti = si->sip->extra_info;
7965         else
7966                 nti = NULL;
7967
7968         if(parent_tree){
7969                 if(nti != NULL){
7970                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7971                                 "%s Parameters",
7972                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7973                 } else {
7974                         /*
7975                          * We never saw the request to which this is a
7976                          * response.
7977                          */
7978                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7979                                 "Unknown NT Transaction Parameters (matching request not seen)");
7980                 }
7981                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7982         }
7983
7984         if (nti == NULL) {
7985                 offset += len;
7986                 return offset;
7987         }
7988         switch(nti->subcmd){
7989         case NT_TRANS_CREATE:
7990                 /* oplock level */
7991                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7992                 offset += 1;
7993
7994                 /* reserved byte */
7995                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7996                 offset += 1;
7997                 
7998                 /* fid */
7999                 fid = tvb_get_letohs(tvb, offset);
8000                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8001                 offset += 2;
8002
8003                 /* create action */
8004                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8005                 offset += 4;
8006
8007                 /* ea error offset */
8008                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8009                 offset += 4;
8010
8011                 /* create time */
8012                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8013                         hf_smb_create_time);
8014         
8015                 /* access time */
8016                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8017                         hf_smb_access_time);
8018         
8019                 /* last write time */
8020                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8021                         hf_smb_last_write_time);
8022         
8023                 /* last change time */
8024                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8025                         hf_smb_change_time);
8026         
8027                 /* Extended File Attributes */
8028                 offset = dissect_file_ext_attr(tvb, tree, offset);
8029
8030                 /* allocation size */
8031                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8032                 offset += 8;
8033
8034                 /* end of file */
8035                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8036                 offset += 8;
8037
8038                 /* File Type */
8039                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8040                 offset += 2;
8041
8042                 /* device state */
8043                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8044
8045                 /* is directory */
8046                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8047                 offset += 1;
8048                 break;
8049         case NT_TRANS_IOCTL:
8050                 break;
8051         case NT_TRANS_SSD:
8052                 break;
8053         case NT_TRANS_NOTIFY:
8054                 while(len){
8055                         old_offset = offset;
8056
8057                         /* next entry offset */
8058                         neo = tvb_get_letohl(tvb, offset);
8059                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8060                         COUNT_BYTES(4);
8061                         len -= 4;
8062                         /* broken implementations */
8063                         if(len<0)break;
8064         
8065                         /* action */
8066                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8067                         COUNT_BYTES(4);
8068                         len -= 4;
8069                         /* broken implementations */
8070                         if(len<0)break;
8071
8072                         /* file name len */
8073                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8074                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8075                         COUNT_BYTES(4);
8076                         len -= 4;
8077                         /* broken implementations */
8078                         if(len<0)break;
8079
8080                         /* file name */
8081                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
8082                         if (fn == NULL)
8083                                 break;
8084                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8085                                 fn);
8086                         COUNT_BYTES(fn_len);
8087                         len -= fn_len;
8088                         /* broken implementations */
8089                         if(len<0)break;
8090
8091                         if (neo == 0)
8092                                 break;  /* no more structures */
8093
8094                         /* skip to next structure */
8095                         padcnt = (old_offset + neo) - offset;
8096                         if (padcnt < 0) {
8097                                 /*
8098                                  * XXX - this is bogus; flag it?
8099                                  */
8100                                 padcnt = 0;
8101                         }
8102                         if (padcnt != 0) {
8103                                 COUNT_BYTES(padcnt);
8104                                 len -= padcnt;
8105                                 /* broken implementations */
8106                                 if(len<0)break;
8107                         }
8108                 }
8109                 break;
8110         case NT_TRANS_RENAME:
8111                 /* XXX not documented */
8112                 break;
8113         case NT_TRANS_QSD:
8114                 /*
8115                  * This appears to be the size of the security
8116                  * descriptor; the calling sequence of
8117                  * "ZwQuerySecurityObject()" suggests that it would
8118                  * be.  The actual security descriptor wouldn't
8119                  * follow if the max data count in the request
8120                  * was smaller; this lets the client know how
8121                  * big a buffer it needs to provide.
8122                  */
8123                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8124                 offset += 4;
8125                 break;
8126         case NT_TRANS_GET_USER_QUOTA:
8127                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8128                         tvb_get_letohl(tvb, offset));
8129                 offset += 4;
8130                 break;
8131         case NT_TRANS_SET_USER_QUOTA:
8132                 /* not decoded yet */
8133                 break;
8134         }
8135
8136         return offset;
8137 }
8138  
8139 static int
8140 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8141 {
8142         proto_item *item = NULL;
8143         proto_tree *tree = NULL;
8144         smb_info_t *si;
8145         smb_nt_transact_info_t *nti;
8146
8147         si = (smb_info_t *)pinfo->private_data;
8148         if (si->sip != NULL)
8149                 nti = si->sip->extra_info;
8150         else
8151                 nti = NULL;
8152
8153         if(parent_tree){
8154                 if(nti != NULL){
8155                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8156                                 "%s Setup",
8157                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8158                 } else {
8159                         /*
8160                          * We never saw the request to which this is a
8161                          * response.
8162                          */
8163                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8164                                 "Unknown NT Transaction Setup (matching request not seen)");
8165                 }
8166                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8167         }
8168
8169         if (nti == NULL) {
8170                 offset += len;
8171                 return offset;
8172         }
8173         switch(nti->subcmd){
8174         case NT_TRANS_CREATE:
8175                 break;
8176         case NT_TRANS_IOCTL:
8177                 break;
8178         case NT_TRANS_SSD:
8179                 break;
8180         case NT_TRANS_NOTIFY:
8181                 break;
8182         case NT_TRANS_RENAME:
8183                 /* XXX not documented */
8184                 break;
8185         case NT_TRANS_QSD:
8186                 break;
8187         case NT_TRANS_GET_USER_QUOTA:
8188                 /* not decoded yet */
8189                 break;
8190         case NT_TRANS_SET_USER_QUOTA:
8191                 /* not decoded yet */
8192                 break;
8193         }
8194
8195         return offset;
8196 }
8197
8198 static int
8199 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8200 {
8201         guint8 wc, sc;
8202         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8203         guint32 td=0, tp=0;
8204         smb_info_t *si;
8205         smb_nt_transact_info_t *nti;
8206         static nt_trans_data ntd;
8207         guint16 bc;
8208         int padcnt;
8209         fragment_data *r_fd = NULL;
8210         tvbuff_t *pd_tvb=NULL;
8211         gboolean save_fragmented;
8212
8213         si = (smb_info_t *)pinfo->private_data;
8214         if (si->sip != NULL)
8215                 nti = si->sip->extra_info;
8216         else
8217                 nti = NULL;
8218
8219         /* primary request */
8220         if(nti != NULL){
8221                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8222                 if(check_col(pinfo->cinfo, COL_INFO)){
8223                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8224                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8225                 }
8226         } else {
8227                 proto_tree_add_text(tree, tvb, offset, 0,
8228                         "Function: <unknown function - could not find matching request>");
8229                 if(check_col(pinfo->cinfo, COL_INFO)){
8230                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8231                 }
8232         }
8233
8234         WORD_COUNT;
8235
8236         /* 3 reserved bytes */
8237         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8238         offset += 3;
8239
8240         /* total param count */
8241         tp = tvb_get_letohl(tvb, offset);
8242         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8243         offset += 4;
8244         
8245         /* total data count */
8246         td = tvb_get_letohl(tvb, offset);
8247         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8248         offset += 4;
8249
8250         /* param count */
8251         pc = tvb_get_letohl(tvb, offset);
8252         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8253         offset += 4;
8254         
8255         /* param offset */
8256         po = tvb_get_letohl(tvb, offset);
8257         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8258         offset += 4;
8259
8260         /* param displacement */
8261         pd = tvb_get_letohl(tvb, offset);
8262         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8263         offset += 4;
8264
8265         /* data count */
8266         dc = tvb_get_letohl(tvb, offset);
8267         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8268         offset += 4;
8269
8270         /* data offset */
8271         od = tvb_get_letohl(tvb, offset);
8272         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8273         offset += 4;
8274
8275         /* data displacement */
8276         dd = tvb_get_letohl(tvb, offset);
8277         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8278         offset += 4;
8279
8280         /* setup count */
8281         sc = tvb_get_guint8(tvb, offset);
8282         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8283         offset += 1;
8284
8285         /* setup data */        
8286         if(sc){
8287                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8288                 offset += sc*2;
8289         }
8290
8291         BYTE_COUNT;
8292
8293         /* reassembly of SMB NT Transaction data payload.
8294            In this section we do reassembly of both the data and parameters
8295            blocks of the SMB transaction command.
8296         */
8297         save_fragmented = pinfo->fragmented;
8298         /* do we need reassembly? */
8299         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8300                 /* oh yeah, either data or parameter section needs 
8301                    reassembly...
8302                 */
8303                 pinfo->fragmented = TRUE;
8304                 if(smb_trans_reassembly){
8305                         /* ...and we were told to do reassembly */
8306                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8307                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8308                                                              po, pc, pd, td+tp);
8309                                 
8310                         }
8311                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8312                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8313                                                              od, dc, dd+tp, td+tp);
8314                         }
8315                 }
8316         }
8317
8318         /* if we got a reassembled fd structure from the reassembly routine we
8319            must create pd_tvb from it 
8320         */
8321         if(r_fd){
8322                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8323                                              r_fd->datalen);
8324                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8325                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8326
8327                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8328         }
8329
8330
8331         if(pd_tvb){
8332           /* we have reassembled data, grab param and data from there */
8333           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8334                                           &ntd, tvb_length(pd_tvb));
8335           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8336         } else {
8337           /* we do not have reassembled data, just use what we have in the 
8338              packet as well as we can */
8339           /* parameters */
8340           if(po>(guint32)offset){
8341             /* We have some initial padding bytes.
8342              */
8343             padcnt = po-offset;
8344             if (padcnt > bc)
8345               padcnt = bc;
8346             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8347             COUNT_BYTES(padcnt);
8348           }
8349           if(pc){
8350             CHECK_BYTE_COUNT(pc);
8351             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8352             COUNT_BYTES(pc);
8353           }
8354           
8355           /* data */
8356           if(od>(guint32)offset){
8357             /* We have some initial padding bytes.
8358              */
8359             padcnt = od-offset;
8360             if (padcnt > bc)
8361               padcnt = bc;
8362             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8363             COUNT_BYTES(padcnt);
8364           }
8365           if(dc){
8366             CHECK_BYTE_COUNT(dc);
8367             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8368             COUNT_BYTES(dc);
8369           }
8370         }
8371         pinfo->fragmented = save_fragmented;
8372
8373         END_OF_SMB
8374
8375         return offset;
8376 }
8377
8378 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8379    NT Transaction command  ends here
8380    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8381
8382 static const value_string print_mode_vals[] = {
8383         {0,     "Text Mode"},
8384         {1,     "Graphics Mode"},
8385         {0, NULL}
8386 };
8387  
8388 static int
8389 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8390 {
8391         int fn_len;
8392         const char *fn;
8393         guint8 wc;
8394         guint16 bc;
8395
8396         WORD_COUNT;
8397
8398         /* setup len */
8399         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8400         offset += 2;
8401
8402         /* print mode */
8403         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8404         offset += 2;
8405
8406         BYTE_COUNT;
8407
8408         /* buffer format */
8409         CHECK_BYTE_COUNT(1);
8410         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8411         COUNT_BYTES(1);
8412
8413         /* print identifier */
8414         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
8415         if (fn == NULL)
8416                 goto endofcommand;
8417         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8418                 fn);
8419         COUNT_BYTES(fn_len);
8420
8421         END_OF_SMB
8422
8423         return offset;
8424 }
8425
8426
8427 static int
8428 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8429 {
8430         int cnt;
8431         guint8 wc;
8432         guint16 bc, fid;
8433
8434         WORD_COUNT;
8435
8436         /* fid */
8437         fid = tvb_get_letohs(tvb, offset);
8438         add_fid(tvb, pinfo, tree, offset, 2, fid);
8439         offset += 2;
8440
8441         BYTE_COUNT;
8442
8443         /* buffer format */
8444         CHECK_BYTE_COUNT(1);
8445         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8446         COUNT_BYTES(1);
8447
8448         /* data len */
8449         CHECK_BYTE_COUNT(2);
8450         cnt = tvb_get_letohs(tvb, offset);
8451         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8452         COUNT_BYTES(2);
8453
8454         /* file data */
8455         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8456
8457         END_OF_SMB
8458
8459         return offset;
8460 }
8461
8462
8463 static const value_string print_status_vals[] = {
8464         {1,     "Held or Stopped"},
8465         {2,     "Printing"},
8466         {3,     "Awaiting print"},
8467         {4,     "In intercept"},
8468         {5,     "File had error"},
8469         {6,     "Printer error"},
8470         {0, NULL}
8471 };
8472  
8473 static int
8474 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8475 {
8476         guint8 wc;
8477         guint16 bc;
8478
8479         WORD_COUNT;
8480
8481         /* max count */
8482         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8483         offset += 2;
8484
8485         /* start index */
8486         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8487         offset += 2;
8488
8489         BYTE_COUNT;
8490
8491         END_OF_SMB
8492
8493         return offset;
8494 }
8495
8496 static int
8497 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8498     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8499 {
8500         proto_item *item = NULL;
8501         proto_tree *tree = NULL;
8502         int fn_len;
8503         const char *fn;
8504
8505         if(parent_tree){
8506                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8507                         "Queue entry");
8508                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8509         }
8510
8511         /* queued time */
8512         CHECK_BYTE_COUNT_SUBR(4);
8513         offset = dissect_smb_datetime(tvb, tree, offset,
8514                 hf_smb_print_queue_date,
8515                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8516         *bcp -= 4;
8517
8518         /* status */
8519         CHECK_BYTE_COUNT_SUBR(1);
8520         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8521         COUNT_BYTES_SUBR(1);
8522
8523         /* spool file number */
8524         CHECK_BYTE_COUNT_SUBR(2);
8525         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8526         COUNT_BYTES_SUBR(2);
8527
8528         /* spool file size */
8529         CHECK_BYTE_COUNT_SUBR(4);
8530         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8531         COUNT_BYTES_SUBR(4);
8532
8533         /* reserved byte */
8534         CHECK_BYTE_COUNT_SUBR(1);
8535         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8536         COUNT_BYTES_SUBR(1);
8537
8538         /* file name */
8539         fn_len = 16;
8540         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
8541         CHECK_STRING_SUBR(fn);
8542         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8543                 fn);
8544         COUNT_BYTES_SUBR(fn_len);
8545
8546         *trunc = FALSE;
8547         return offset;
8548 }
8549
8550 static int
8551 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8552 {
8553         guint16 cnt=0, len;
8554         guint8 wc;
8555         guint16 bc;
8556         gboolean trunc;
8557
8558         WORD_COUNT;
8559
8560         /* count */
8561         cnt = tvb_get_letohs(tvb, offset);
8562         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8563         offset += 2;
8564
8565         /* restart index */
8566         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8567         offset += 2;
8568
8569         BYTE_COUNT;
8570
8571         /* buffer format */
8572         CHECK_BYTE_COUNT(1);
8573         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8574         COUNT_BYTES(1);
8575
8576         /* data len */
8577         CHECK_BYTE_COUNT(2);
8578         len = tvb_get_letohs(tvb, offset);
8579         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8580         COUNT_BYTES(2);
8581
8582         /* queue elements */
8583         while(cnt--){
8584                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8585                     &bc, &trunc);
8586                 if (trunc)
8587                         goto endofcommand;
8588         }
8589
8590         END_OF_SMB
8591
8592         return offset;
8593 }
8594
8595
8596 static int
8597 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8598 {
8599         int name_len;
8600         guint16 bc;
8601         guint8 wc;
8602         guint16 message_len;
8603
8604         WORD_COUNT;
8605
8606         BYTE_COUNT;
8607
8608         /* buffer format */
8609         CHECK_BYTE_COUNT(1);
8610         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8611         COUNT_BYTES(1);
8612
8613         /* originator name */
8614         /* XXX - what if this runs past bc? */
8615         name_len = tvb_strsize(tvb, offset);
8616         CHECK_BYTE_COUNT(name_len);
8617         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8618             name_len, TRUE);
8619         COUNT_BYTES(name_len);
8620
8621         /* buffer format */
8622         CHECK_BYTE_COUNT(1);
8623         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8624         COUNT_BYTES(1);
8625
8626         /* destination name */
8627         /* XXX - what if this runs past bc? */
8628         name_len = tvb_strsize(tvb, offset);
8629         CHECK_BYTE_COUNT(name_len);
8630         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8631             name_len, TRUE);
8632         COUNT_BYTES(name_len);
8633
8634         /* buffer format */
8635         CHECK_BYTE_COUNT(1);
8636         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8637         COUNT_BYTES(1);
8638
8639         /* message len */
8640         CHECK_BYTE_COUNT(2);
8641         message_len = tvb_get_letohs(tvb, offset);
8642         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8643             message_len);
8644         COUNT_BYTES(2);
8645
8646         /* message */
8647         CHECK_BYTE_COUNT(message_len);
8648         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8649             TRUE);
8650         COUNT_BYTES(message_len);
8651
8652         END_OF_SMB
8653
8654         return offset;
8655 }
8656
8657 static int
8658 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8659 {
8660         int name_len;
8661         guint16 bc;
8662         guint8 wc;
8663
8664         WORD_COUNT;
8665
8666         BYTE_COUNT;
8667
8668         /* buffer format */
8669         CHECK_BYTE_COUNT(1);
8670         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8671         COUNT_BYTES(1);
8672
8673         /* originator name */
8674         /* XXX - what if this runs past bc? */
8675         name_len = tvb_strsize(tvb, offset);
8676         CHECK_BYTE_COUNT(name_len);
8677         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8678             name_len, TRUE);
8679         COUNT_BYTES(name_len);
8680
8681         /* buffer format */
8682         CHECK_BYTE_COUNT(1);
8683         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8684         COUNT_BYTES(1);
8685
8686         /* destination name */
8687         /* XXX - what if this runs past bc? */
8688         name_len = tvb_strsize(tvb, offset);
8689         CHECK_BYTE_COUNT(name_len);
8690         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8691             name_len, TRUE);
8692         COUNT_BYTES(name_len);
8693
8694         END_OF_SMB
8695
8696         return offset;
8697 }
8698
8699 static int
8700 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8701 {
8702         guint16 bc;
8703         guint8 wc;
8704
8705         WORD_COUNT;
8706
8707         /* message group ID */
8708         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
8709         offset += 2;
8710
8711         BYTE_COUNT;
8712
8713         END_OF_SMB
8714
8715         return offset;
8716 }
8717
8718 static int
8719 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8720 {
8721         guint16 bc;
8722         guint8 wc;
8723         guint16 message_len;
8724
8725         WORD_COUNT;
8726
8727         BYTE_COUNT;
8728
8729         /* buffer format */
8730         CHECK_BYTE_COUNT(1);
8731         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8732         COUNT_BYTES(1);
8733
8734         /* message len */
8735         CHECK_BYTE_COUNT(2);
8736         message_len = tvb_get_letohs(tvb, offset);
8737         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8738             message_len);
8739         COUNT_BYTES(2);
8740
8741         /* message */
8742         CHECK_BYTE_COUNT(message_len);
8743         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8744             TRUE);
8745         COUNT_BYTES(message_len);
8746
8747         END_OF_SMB
8748
8749         return offset;
8750 }
8751
8752 static int
8753 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8754 {
8755         int name_len;
8756         guint16 bc;
8757         guint8 wc;
8758
8759         WORD_COUNT;
8760
8761         BYTE_COUNT;
8762
8763         /* buffer format */
8764         CHECK_BYTE_COUNT(1);
8765         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8766         COUNT_BYTES(1);
8767
8768         /* forwarded name */
8769         /* XXX - what if this runs past bc? */
8770         name_len = tvb_strsize(tvb, offset);
8771         CHECK_BYTE_COUNT(name_len);
8772         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
8773             name_len, TRUE);
8774         COUNT_BYTES(name_len);
8775
8776         END_OF_SMB
8777
8778         return offset;
8779 }
8780
8781 static int
8782 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8783 {
8784         int name_len;
8785         guint16 bc;
8786         guint8 wc;
8787
8788         WORD_COUNT;
8789
8790         BYTE_COUNT;
8791
8792         /* buffer format */
8793         CHECK_BYTE_COUNT(1);
8794         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8795         COUNT_BYTES(1);
8796
8797         /* machine name */
8798         /* XXX - what if this runs past bc? */
8799         name_len = tvb_strsize(tvb, offset);
8800         CHECK_BYTE_COUNT(name_len);
8801         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
8802             name_len, TRUE);
8803         COUNT_BYTES(name_len);
8804
8805         END_OF_SMB
8806
8807         return offset;
8808 }
8809
8810
8811 static int
8812 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8813 {
8814         guint8  wc, cmd=0xff;
8815         guint16 andxoffset=0;
8816         guint16 bc;
8817         int fn_len;
8818         const char *fn;
8819
8820         WORD_COUNT;
8821
8822         /* next smb command */
8823         cmd = tvb_get_guint8(tvb, offset);
8824         if(cmd!=0xff){
8825                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8826         } else {
8827                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8828         }
8829         offset += 1;
8830
8831         /* reserved byte */
8832         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8833         offset += 1;
8834
8835         /* andxoffset */
8836         andxoffset = tvb_get_letohs(tvb, offset);
8837         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8838         offset += 2;
8839
8840         /* reserved byte */
8841         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8842         offset += 1;
8843
8844         /* file name len */
8845         fn_len = tvb_get_letohs(tvb, offset);
8846         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8847         offset += 2;
8848
8849         /* Create flags */
8850         offset = dissect_nt_create_bits(tvb, tree, offset);
8851
8852         /* root directory fid */
8853         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8854         offset += 4;
8855
8856         /* nt access mask */
8857         offset = dissect_nt_access_mask(tvb, tree, offset);
8858
8859         /* allocation size */
8860         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8861         offset += 8;
8862
8863         /* Extended File Attributes */
8864         offset = dissect_file_ext_attr(tvb, tree, offset);
8865
8866         /* share access */
8867         offset = dissect_nt_share_access(tvb, tree, offset);
8868
8869         /* create disposition */
8870         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8871         offset += 4;
8872
8873         /* create options */
8874         offset = dissect_nt_create_options(tvb, tree, offset);
8875
8876         /* impersonation level */
8877         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8878         offset += 4;
8879
8880         /* security flags */
8881         offset = dissect_nt_security_flags(tvb, tree, offset);
8882
8883         BYTE_COUNT;
8884
8885         /* file name */
8886         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8887         if (fn == NULL)
8888                 goto endofcommand;
8889         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8890                 fn);
8891         COUNT_BYTES(fn_len);
8892
8893         if (check_col(pinfo->cinfo, COL_INFO)) {
8894                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8895         }
8896
8897         END_OF_SMB
8898
8899         /* call AndXCommand (if there are any) */
8900         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
8901
8902         return offset;
8903 }
8904  
8905
8906 static int
8907 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8908 {
8909         guint8  wc, cmd=0xff;
8910         guint16 andxoffset=0;
8911         guint16 bc;
8912         guint16 fid;
8913
8914         WORD_COUNT;
8915
8916         /* next smb command */
8917         cmd = tvb_get_guint8(tvb, offset);
8918         if(cmd!=0xff){
8919                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8920         } else {
8921                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8922         }
8923         offset += 1;
8924
8925         /* reserved byte */
8926         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8927         offset += 1;
8928
8929         /* andxoffset */
8930         andxoffset = tvb_get_letohs(tvb, offset);
8931         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8932         offset += 2;
8933
8934         /* oplock level */
8935         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8936         offset += 1;
8937
8938         /* fid */
8939         fid = tvb_get_letohs(tvb, offset);
8940         add_fid(tvb, pinfo, tree, offset, 2, fid);
8941         offset += 2;
8942
8943         /* create action */
8944         /*XXX is this really the same as create disposition in the request? it looks so*/
8945         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8946         offset += 4;
8947
8948         /* create time */
8949         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
8950         
8951         /* access time */
8952         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
8953         
8954         /* last write time */
8955         offset = dissect_smb_64bit_time(tvb, tree, offset,
8956                 hf_smb_last_write_time);
8957
8958         /* last change time */
8959         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
8960         
8961         /* Extended File Attributes */
8962         offset = dissect_file_ext_attr(tvb, tree, offset);
8963
8964         /* allocation size */
8965         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8966         offset += 8;
8967
8968         /* end of file */
8969         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8970         offset += 8;
8971
8972         /* File Type */
8973         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8974         offset += 2;
8975
8976         /* IPC State */
8977         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8978
8979         /* is directory */
8980         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8981         offset += 1;
8982
8983         BYTE_COUNT;
8984
8985         END_OF_SMB
8986
8987         /* call AndXCommand (if there are any) */
8988         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
8989
8990         return offset;
8991 }
8992
8993
8994 static int
8995 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8996 {
8997         guint8 wc;
8998         guint16 bc;
8999
9000         WORD_COUNT;
9001  
9002         BYTE_COUNT;
9003
9004         END_OF_SMB
9005
9006         return offset;
9007 }
9008
9009 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9010    BEGIN Transaction/Transaction2 Primary and secondary requests
9011    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9012
9013
9014 static const value_string trans2_cmd_vals[] = {
9015         { 0x00,         "OPEN2" },
9016         { 0x01,         "FIND_FIRST2" },
9017         { 0x02,         "FIND_NEXT2" },
9018         { 0x03,         "QUERY_FS_INFORMATION" },
9019         { 0x04,         "SET_FS_QUOTA" },
9020         { 0x05,         "QUERY_PATH_INFORMATION" },
9021         { 0x06,         "SET_PATH_INFORMATION" },
9022         { 0x07,         "QUERY_FILE_INFORMATION" },
9023         { 0x08,         "SET_FILE_INFORMATION" },
9024         { 0x09,         "FSCTL" },
9025         { 0x0A,         "IOCTL2" },
9026         { 0x0B,         "FIND_NOTIFY_FIRST" },
9027         { 0x0C,         "FIND_NOTIFY_NEXT" },
9028         { 0x0D,         "CREATE_DIRECTORY" },
9029         { 0x0E,         "SESSION_SETUP" },
9030         { 0x10,         "GET_DFS_REFERRAL" },
9031         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9032         { 0,    NULL }
9033 };
9034
9035 static const true_false_string tfs_tf_dtid = {
9036         "Also DISCONNECT TID",
9037         "Do NOT disconnect TID"
9038 };
9039 static const true_false_string tfs_tf_owt = {
9040         "One Way Transaction (NO RESPONSE)",
9041         "Two way transaction"
9042 };
9043
9044 static const true_false_string tfs_ff2_backup = {
9045         "Find WITH backup intent",
9046         "No backup intent"
9047 };
9048 static const true_false_string tfs_ff2_continue = {
9049         "CONTINUE search from previous position",
9050         "New search, do NOT continue from previous position"
9051 };
9052 static const true_false_string tfs_ff2_resume = {
9053         "Return RESUME keys",
9054         "Do NOT return resume keys"
9055 };
9056 static const true_false_string tfs_ff2_close_eos = {
9057         "CLOSE search if END OF SEARCH is reached",
9058         "Do NOT close search if end of search reached"
9059 };
9060 static const true_false_string tfs_ff2_close = {
9061         "CLOSE search after this request",
9062         "Do NOT close search after this request"
9063 };
9064
9065 /* used by
9066    TRANS2_FIND_FIRST2
9067 */
9068 static const value_string ff2_il_vals[] = {
9069         { 1,            "Info Standard  (4.3.4.1)"},
9070         { 2,            "Info Query EA Size  (4.3.4.2)"},
9071         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9072         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9073         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9074         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9075         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9076         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9077         {0, NULL}
9078 };
9079
9080 /* values used by :
9081         TRANS2_QUERY_PATH_INFORMATION
9082         TRANS2_SET_PATH_INFORMATION
9083 */
9084 static const value_string qpi_loi_vals[] = {
9085         { 1,            "Info Standard  (4.2.14.1)"},
9086         { 2,            "Info Query EA Size  (4.2.14.1)"},
9087         { 3,            "Info Query EAs From List  (4.2.14.2)"},
9088         { 4,            "Info Query All EAs  (4.2.14.2)"},
9089         { 6,            "Info Is Name Valid  (4.2.14.3)"},
9090         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
9091         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
9092         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
9093         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
9094         { 0x0107,       "Query File All Info  (4.2.14.8)"},
9095         { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
9096         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
9097         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
9098         { 0x0200,       "Set File Unix Basic"},
9099         { 0x0201,       "Set File Unix Link"},
9100         { 0x0202,       "Set File Unix HardLink"},
9101         { 1004,         "Query File Basic Info  (4.2.14.4)"},
9102         { 1005,         "Query File Standard Info  (4.2.14.5)"},
9103         { 1006,         "Query File Internal Info  (4.2.14.?)"},
9104         { 1007,         "Query File EA Info  (4.2.14.6)"},
9105         { 1009,         "Query File Name Info  (4.2.14.7)"},
9106         { 1010,         "Query File Rename Info  (4.2.14.?)"},
9107         { 1011,         "Query File Link Info  (4.2.14.?)"},
9108         { 1012,         "Query File Names Info  (4.2.14.?)"},
9109         { 1013,         "Query File Disposition Info  (4.2.14.?)"},
9110         { 1014,         "Query File Position Info  (4.2.14.?)"},
9111         { 1015,         "Query File Full EA Info  (4.2.14.?)"},
9112         { 1016,         "Query File Mode Info  (4.2.14.?)"},
9113         { 1017,         "Query File Alignment Info  (4.2.14.?)"},
9114         { 1018,         "Query File All Info  (4.2.14.8)"},
9115         { 1019,         "Query File Allocation Info  (4.2.14.?)"},
9116         { 1020,         "Query File End of File Info  (4.2.14.?)"},
9117         { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
9118         { 1022,         "Query File Stream Info  (4.2.14.10)"},
9119         { 1023,         "Query File Pipe Info  (4.2.14.?)"},
9120         { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
9121         { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
9122         { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
9123         { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
9124         { 1028,         "Query File Compression Info  (4.2.14.11)"},
9125         { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
9126         { 1030,         "Query File Completion Info  (4.2.14.?)"},
9127         { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
9128         { 1032,         "Query File Quota Info  (4.2.14.?)"},
9129         { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
9130         { 1034,         "Query File Network Open Info  (4.2.14.?)"},
9131         { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
9132         { 1036,         "Query File Tracking Info  (4.2.14.?)"},
9133         { 1037,         "Query File Maximum Info  (4.2.14.?)"},
9134         {0, NULL}
9135 };
9136
9137 static const value_string qfsi_vals[] = {
9138         { 1,            "Info Allocation"},
9139         { 2,            "Info Volume"},
9140         { 0x0101,       "Query FS Label Info"},
9141         { 0x0102,       "Query FS Volume Info"},
9142         { 0x0103,       "Query FS Size Info"},
9143         { 0x0104,       "Query FS Device Info"},
9144         { 0x0105,       "Query FS Attribute Info"},
9145         { 1001,         "Query FS Label Info"},
9146         { 1002,         "Query FS Volume Info"},
9147         { 1003,         "Query FS Size Info"},
9148         { 1004,         "Query FS Device Info"},
9149         { 1005,         "Query FS Attribute Info"},
9150         { 1006,         "Query FS Quota Info"},
9151         { 1007,         "Query Full FS Size Info"},
9152         {0, NULL}
9153 };
9154
9155 static const value_string nt_rename_vals[] = {
9156         { 0x0103,       "Create Hard Link"},
9157         {0, NULL}
9158 };
9159
9160
9161 static const value_string delete_pending_vals[] = {
9162         {0,     "Normal, no pending delete"},
9163         {1,     "This object has DELETE PENDING"},
9164         {0, NULL}
9165 };
9166
9167 static const value_string alignment_vals[] = {
9168         {0,     "Byte alignment"},
9169         {1,     "Word (16bit) alignment"},
9170         {3,     "Long (32bit) alignment"},
9171         {7,     "8 byte boundary alignment"},
9172         {0x0f,  "16 byte boundary alignment"},
9173         {0x1f,  "32 byte boundary alignment"},
9174         {0x3f,  "64 byte boundary alignment"},
9175         {0x7f,  "128 byte boundary alignment"},
9176         {0xff,  "256 byte boundary alignment"},
9177         {0x1ff, "512 byte boundary alignment"},
9178         {0, NULL}
9179 };
9180
9181
9182 static const true_false_string tfs_get_dfs_server_hold_storage = {
9183         "Referral SERVER HOLDS STORAGE for the file",
9184         "Referral server does NOT hold storage for the file"
9185 };
9186 static const true_false_string tfs_get_dfs_fielding = {
9187         "The server in referral is FIELDING CAPABLE",
9188         "The server in referrals is NOT fielding capable"
9189 };
9190
9191 static const true_false_string tfs_dfs_referral_flags_strip = {
9192         "STRIP off pathconsumed characters before submitting",
9193         "Do NOT strip off any characters"
9194 };
9195
9196 static const value_string dfs_referral_server_type_vals[] = {
9197         {0,     "Don't know"},
9198         {1,     "SMB Server"},
9199         {2,     "Netware Server"},
9200         {3,     "Domain Server"},
9201         {0, NULL}
9202 };
9203
9204
9205 static const true_false_string tfs_device_char_removable = {
9206         "This is a REMOVABLE device",
9207         "This is NOT a removable device"
9208 };
9209 static const true_false_string tfs_device_char_read_only = {
9210         "This is a READ-ONLY device",
9211         "This is NOT a read-only device"
9212 };
9213 static const true_false_string tfs_device_char_floppy = {
9214         "This is a FLOPPY DISK device",
9215         "This is NOT a floppy disk device"
9216 };
9217 static const true_false_string tfs_device_char_write_once = {
9218         "This is a WRITE-ONCE device",
9219         "This is NOT a write-once device"
9220 };
9221 static const true_false_string tfs_device_char_remote = {
9222         "This is a REMOTE device",
9223         "This is NOT a remote device"
9224 };
9225 static const true_false_string tfs_device_char_mounted = {
9226         "This device is MOUNTED",
9227         "This device is NOT mounted"
9228 };
9229 static const true_false_string tfs_device_char_virtual = {
9230         "This is a VIRTUAL device",
9231         "This is NOT a virtual device"
9232 };
9233
9234
9235 static const true_false_string tfs_fs_attr_css = {
9236         "This FS supports CASE SENSITIVE SEARCHes",
9237         "This FS does NOT support case sensitive searches"
9238 };
9239 static const true_false_string tfs_fs_attr_cpn = {
9240         "This FS supports CASE PRESERVED NAMES",
9241         "This FS does NOT support case preserved names"
9242 };
9243 static const true_false_string tfs_fs_attr_pacls = {
9244         "This FS supports PERSISTENT ACLs",
9245         "This FS does NOT support persistent acls"
9246 };
9247 static const true_false_string tfs_fs_attr_fc = {
9248         "This FS supports COMPRESSED FILES",
9249         "This FS does NOT support compressed files"
9250 };
9251 static const true_false_string tfs_fs_attr_vq = {
9252         "This FS supports VOLUME QUOTAS",
9253         "This FS does NOT support volume quotas"
9254 };
9255 static const true_false_string tfs_fs_attr_dim = {
9256         "This FS is on a MOUNTED DEVICE",
9257         "This FS is NOT on a mounted device"
9258 };
9259 static const true_false_string tfs_fs_attr_vic = {
9260         "This FS is on a COMPRESSED VOLUME",
9261         "This FS is NOT on a compressed volume"
9262 };
9263
9264 #define FF2_RESUME      0x0004
9265
9266 static int
9267 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9268 {
9269         guint16 mask;
9270         proto_item *item = NULL;
9271         proto_tree *tree = NULL;
9272         smb_info_t *si;
9273         smb_transact2_info_t *t2i;
9274
9275         mask = tvb_get_letohs(tvb, offset);
9276
9277         si = (smb_info_t *)pinfo->private_data;
9278         if (si->sip != NULL) {
9279                 t2i = si->sip->extra_info;
9280                 if (t2i != NULL) {
9281                         if (!pinfo->fd->flags.visited)
9282                                 t2i->resume_keys = (mask & FF2_RESUME);
9283                 }
9284         }
9285
9286         if(parent_tree){
9287                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9288                         "Flags: 0x%04x", mask);
9289                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9290         }
9291
9292         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9293                 tvb, offset, 2, mask);
9294         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9295                 tvb, offset, 2, mask);
9296         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9297                 tvb, offset, 2, mask);
9298         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9299                 tvb, offset, 2, mask);
9300         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9301                 tvb, offset, 2, mask);
9302
9303         offset += 2;
9304
9305         return offset;
9306 }
9307
9308 #if 0
9309 static int
9310 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9311 {
9312         guint16 mask;
9313         proto_item *item = NULL;
9314         proto_tree *tree = NULL;
9315
9316         mask = tvb_get_letohs(tvb, offset);
9317
9318         if(parent_tree){
9319                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9320                         "IO Flag: 0x%04x", mask);
9321                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9322         }
9323
9324         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9325                 tvb, offset, 2, mask);
9326         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9327                 tvb, offset, 2, mask);
9328
9329         offset += 2;
9330
9331         return offset;
9332 }
9333 #endif
9334
9335 static int
9336 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9337     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9338 {
9339         proto_item *item = NULL;
9340         proto_tree *tree = NULL;
9341         smb_info_t *si;
9342         smb_transact2_info_t *t2i;
9343         int fn_len;
9344         const char *fn;
9345         int old_offset = offset;
9346
9347         si = (smb_info_t *)pinfo->private_data;
9348         if (si->sip != NULL)
9349                 t2i = si->sip->extra_info;
9350         else
9351                 t2i = NULL;
9352
9353         if(parent_tree){
9354                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9355                                 "%s Parameters",
9356                                 val_to_str(subcmd, trans2_cmd_vals, 
9357                                            "Unknown (0x%02x)"));
9358                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9359         }
9360
9361         switch(subcmd){
9362         case 0x00:      /*TRANS2_OPEN2*/
9363                 /* open flags */
9364                 CHECK_BYTE_COUNT_TRANS(2);
9365                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9366                 bc -= 2;
9367
9368                 /* desired access */
9369                 CHECK_BYTE_COUNT_TRANS(2);
9370                 offset = dissect_access(tvb, tree, offset, "Desired");
9371                 bc -= 2;
9372
9373                 /* Search Attributes */
9374                 CHECK_BYTE_COUNT_TRANS(2);
9375                 offset = dissect_search_attributes(tvb, tree, offset);
9376                 bc -= 2;
9377
9378                 /* File Attributes */
9379                 CHECK_BYTE_COUNT_TRANS(2);
9380                 offset = dissect_file_attributes(tvb, tree, offset);
9381                 bc -= 2;
9382
9383                 /* create time */
9384                 CHECK_BYTE_COUNT_TRANS(4);
9385                 offset = dissect_smb_datetime(tvb, tree, offset,
9386                         hf_smb_create_time,
9387                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9388                         TRUE);
9389                 bc -= 4;
9390
9391                 /* open function */
9392                 CHECK_BYTE_COUNT_TRANS(2);
9393                 offset = dissect_open_function(tvb, tree, offset);
9394                 bc -= 2;
9395
9396                 /* allocation size */
9397                 CHECK_BYTE_COUNT_TRANS(4);
9398                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9399                 COUNT_BYTES_TRANS(4);
9400
9401                 /* 10 reserved bytes */
9402                 CHECK_BYTE_COUNT_TRANS(10);
9403                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9404                 COUNT_BYTES_TRANS(10);
9405
9406                 /* file name */
9407                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9408                 CHECK_STRING_TRANS(fn);
9409                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9410                         fn);
9411                 COUNT_BYTES_TRANS(fn_len);
9412
9413                 if (check_col(pinfo->cinfo, COL_INFO)) {
9414                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9415                         fn);
9416                 }
9417                 break;
9418         case 0x01:      /*TRANS2_FIND_FIRST2*/
9419                 /* Search Attributes */
9420                 CHECK_BYTE_COUNT_TRANS(2);
9421                 offset = dissect_search_attributes(tvb, tree, offset);
9422                 bc -= 2;
9423
9424                 /* search count */
9425                 CHECK_BYTE_COUNT_TRANS(2);
9426                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9427                 COUNT_BYTES_TRANS(2);
9428
9429                 /* Find First2 flags */
9430                 CHECK_BYTE_COUNT_TRANS(2);
9431                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9432                 bc -= 2;
9433
9434                 /* Find First2 information level */
9435                 CHECK_BYTE_COUNT_TRANS(2);
9436                 si->info_level = tvb_get_letohs(tvb, offset);
9437                 if (!pinfo->fd->flags.visited)
9438                         t2i->info_level = si->info_level;
9439                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9440                 COUNT_BYTES_TRANS(2);
9441
9442                 /* storage type */
9443                 CHECK_BYTE_COUNT_TRANS(4);
9444                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9445                 COUNT_BYTES_TRANS(4);
9446
9447                 /* search pattern */
9448                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9449                 CHECK_STRING_TRANS(fn);
9450                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9451                         fn);
9452                 COUNT_BYTES_TRANS(fn_len);
9453
9454                 if (check_col(pinfo->cinfo, COL_INFO)) {
9455                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9456                         fn);
9457                 }
9458
9459                 break;
9460         case 0x02:      /*TRANS2_FIND_NEXT2*/
9461                 /* sid */
9462                 CHECK_BYTE_COUNT_TRANS(2);
9463                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
9464                 COUNT_BYTES_TRANS(2);
9465
9466                 /* search count */
9467                 CHECK_BYTE_COUNT_TRANS(2);
9468                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9469                 COUNT_BYTES_TRANS(2);
9470
9471                 /* Find First2 information level */
9472                 CHECK_BYTE_COUNT_TRANS(2);
9473                 si->info_level = tvb_get_letohs(tvb, offset);
9474                 if (!pinfo->fd->flags.visited)
9475                         t2i->info_level = si->info_level;
9476                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9477                 COUNT_BYTES_TRANS(2);
9478
9479                 /* resume key */
9480                 CHECK_BYTE_COUNT_TRANS(4);
9481                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9482                 COUNT_BYTES_TRANS(4);
9483
9484                 /* Find First2 flags */
9485                 CHECK_BYTE_COUNT_TRANS(2);
9486                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9487                 bc -= 2;
9488
9489                 /* file name */
9490                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9491                 CHECK_STRING_TRANS(fn);
9492                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9493                         fn);
9494                 COUNT_BYTES_TRANS(fn_len);
9495
9496                 if (check_col(pinfo->cinfo, COL_INFO)) {
9497                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9498                         fn);
9499                 }
9500
9501                 break;
9502         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9503                 /* level of interest */
9504                 CHECK_BYTE_COUNT_TRANS(2);
9505                 si->info_level = tvb_get_letohs(tvb, offset);
9506                 if (!pinfo->fd->flags.visited)
9507                         t2i->info_level = si->info_level;
9508                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9509                 COUNT_BYTES_TRANS(2);
9510
9511                 break;
9512         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9513                 /* level of interest */
9514                 CHECK_BYTE_COUNT_TRANS(2);
9515                 si->info_level = tvb_get_letohs(tvb, offset);
9516                 if (!pinfo->fd->flags.visited)
9517                         t2i->info_level = si->info_level;
9518                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9519                 COUNT_BYTES_TRANS(2);
9520                 
9521                 /* 4 reserved bytes */
9522                 CHECK_BYTE_COUNT_TRANS(4);
9523                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9524                 COUNT_BYTES_TRANS(4);
9525
9526                 /* file name */
9527                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9528                 CHECK_STRING_TRANS(fn);
9529                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9530                         fn);
9531                 COUNT_BYTES_TRANS(fn_len);
9532
9533                 if (check_col(pinfo->cinfo, COL_INFO)) {
9534                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9535                         fn);
9536                 }
9537
9538                 break;
9539         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9540                 /* level of interest */
9541                 CHECK_BYTE_COUNT_TRANS(2);
9542                 si->info_level = tvb_get_letohs(tvb, offset);
9543                 if (!pinfo->fd->flags.visited)
9544                         t2i->info_level = si->info_level;
9545                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9546                 COUNT_BYTES_TRANS(2);
9547                 
9548                 /* 4 reserved bytes */
9549                 CHECK_BYTE_COUNT_TRANS(4);
9550                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9551                 COUNT_BYTES_TRANS(4);
9552
9553                 /* file name */
9554                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9555                 CHECK_STRING_TRANS(fn);
9556                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9557                         fn);
9558                 COUNT_BYTES_TRANS(fn_len);
9559
9560                 if (check_col(pinfo->cinfo, COL_INFO)) {
9561                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9562                         fn);
9563                 }
9564
9565                 break;
9566         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9567                 guint16 fid;
9568
9569                 /* fid */
9570                 CHECK_BYTE_COUNT_TRANS(2);
9571                 fid = tvb_get_letohs(tvb, offset);
9572                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9573                 COUNT_BYTES_TRANS(2);
9574
9575                 /* level of interest */
9576                 CHECK_BYTE_COUNT_TRANS(2);
9577                 si->info_level = tvb_get_letohs(tvb, offset);
9578                 if (!pinfo->fd->flags.visited)
9579                         t2i->info_level = si->info_level;
9580                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9581                 COUNT_BYTES_TRANS(2);
9582                 
9583                 break;
9584         }
9585         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9586                 guint16 fid;
9587
9588                 /* fid */
9589                 CHECK_BYTE_COUNT_TRANS(2);
9590                 fid = tvb_get_letohs(tvb, offset);
9591                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9592                 COUNT_BYTES_TRANS(2);
9593
9594                 /* level of interest */
9595                 CHECK_BYTE_COUNT_TRANS(2);
9596                 si->info_level = tvb_get_letohs(tvb, offset);
9597                 if (!pinfo->fd->flags.visited)
9598                         t2i->info_level = si->info_level;
9599                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9600                 COUNT_BYTES_TRANS(2);
9601                 
9602 #if 0
9603                 /*
9604                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9605                  * Extensions Version 3.0, Document Version 1.11,
9606                  * July 19, 1990" says this is I/O flags, but it's
9607                  * reserved in the SNIA spec, and some clients appear
9608                  * to leave junk in it.
9609                  *
9610                  * Is this some field used only if a particular
9611                  * dialect was negotiated, so that clients can feel
9612                  * safe not setting it if they haven't negotiated that
9613                  * dialect?  Or do the (non-OS/2) clients simply not care
9614                  * about that particular OS/2-oriented dialect?
9615                  */
9616
9617                 /* IO Flag */
9618                 CHECK_BYTE_COUNT_TRANS(2);
9619                 offset = dissect_sfi_ioflag(tvb, tree, offset);
9620                 bc -= 2;
9621 #else
9622                 /* 2 reserved bytes */
9623                 CHECK_BYTE_COUNT_TRANS(2);
9624                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9625                 COUNT_BYTES_TRANS(2);
9626 #endif
9627
9628                 break;
9629         }
9630         case 0x09:      /*TRANS2_FSCTL*/
9631                 /* this call has no parameter block in the request */
9632
9633                 /*
9634                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9635                  * Extensions Version 3.0, Document Version 1.11,
9636                  * July 19, 1990" says this this contains a
9637                  * "File system specific parameter block".  (That means
9638                  * we may not be able to dissect it in any case.)
9639                  */
9640                 break;
9641         case 0x0a:      /*TRANS2_IOCTL2*/
9642                 /* this call has no parameter block in the request */
9643
9644                 /*
9645                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9646                  * Extensions Version 3.0, Document Version 1.11,
9647                  * July 19, 1990" says this this contains a
9648                  * "Device/function specific parameter block".  (That
9649                  * means we may not be able to dissect it in any case.)
9650                  */
9651                 break;
9652         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
9653                 /* Search Attributes */
9654                 CHECK_BYTE_COUNT_TRANS(2);
9655                 offset = dissect_search_attributes(tvb, tree, offset);
9656                 bc -= 2;
9657
9658                 /* Number of changes to wait for */
9659                 CHECK_BYTE_COUNT_TRANS(2);
9660                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9661                 COUNT_BYTES_TRANS(2);
9662
9663                 /* Find Notify information level */
9664                 CHECK_BYTE_COUNT_TRANS(2);
9665                 si->info_level = tvb_get_letohs(tvb, offset);
9666                 if (!pinfo->fd->flags.visited)
9667                         t2i->info_level = si->info_level;
9668                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
9669                 COUNT_BYTES_TRANS(2);
9670
9671                 /* 4 reserved bytes */
9672                 CHECK_BYTE_COUNT_TRANS(4);
9673                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9674                 COUNT_BYTES_TRANS(4);
9675
9676                 /* file name */
9677                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9678                 CHECK_STRING_TRANS(fn);
9679                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9680                         fn);
9681                 COUNT_BYTES_TRANS(fn_len);
9682
9683                 if (check_col(pinfo->cinfo, COL_INFO)) {
9684                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9685                         fn);
9686                 }
9687
9688                 break;
9689         }
9690         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
9691                 /* Monitor handle */
9692                 CHECK_BYTE_COUNT_TRANS(2);
9693                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
9694                 COUNT_BYTES_TRANS(2);
9695
9696                 /* Number of changes to wait for */
9697                 CHECK_BYTE_COUNT_TRANS(2);
9698                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9699                 COUNT_BYTES_TRANS(2);
9700
9701                 break;
9702         }
9703         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9704                 /* 4 reserved bytes */
9705                 CHECK_BYTE_COUNT_TRANS(4);
9706                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9707                 COUNT_BYTES_TRANS(4);
9708
9709                 /* dir name */
9710                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
9711                         FALSE, FALSE, &bc);
9712                 CHECK_STRING_TRANS(fn);
9713                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9714                         fn);
9715                 COUNT_BYTES_TRANS(fn_len);
9716
9717                 if (check_col(pinfo->cinfo, COL_INFO)) {
9718                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9719                         fn);
9720                 }
9721                 break;
9722         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9723                 /* XXX unknown structure*/
9724                 break;
9725         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9726                 /* referral level */
9727                 CHECK_BYTE_COUNT_TRANS(2);
9728                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9729                 COUNT_BYTES_TRANS(2);
9730                 
9731                 /* file name */
9732                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9733                 CHECK_STRING_TRANS(fn);
9734                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9735                         fn);
9736                 COUNT_BYTES_TRANS(fn_len);
9737
9738                 if (check_col(pinfo->cinfo, COL_INFO)) {
9739                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9740                         fn);
9741                 }
9742
9743                 break;
9744         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9745                 /* file name */
9746                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9747                 CHECK_STRING_TRANS(fn);
9748                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9749                         fn);
9750                 COUNT_BYTES_TRANS(fn_len);
9751
9752                 if (check_col(pinfo->cinfo, COL_INFO)) {
9753                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9754                         fn);
9755                 }
9756
9757                 break;
9758         }
9759
9760         /* ooops there were data we didnt know how to process */
9761         if((offset-old_offset) < bc){
9762                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9763                     bc - (offset-old_offset), TRUE);
9764                 offset += bc - (offset-old_offset);
9765         }
9766
9767         return offset;
9768 }
9769
9770 /*
9771  * XXX - just use "dissect_connect_flags()" here?
9772  */
9773 static guint16
9774 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9775 {
9776         guint16 mask;
9777         proto_item *item = NULL;
9778         proto_tree *tree = NULL;
9779
9780         mask = tvb_get_letohs(tvb, offset);
9781
9782         if(parent_tree){
9783                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9784                         "Flags: 0x%04x", mask);
9785                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9786         }
9787
9788         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9789                 tvb, offset, 2, mask);
9790         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9791                 tvb, offset, 2, mask);
9792
9793         return mask;
9794 }
9795  
9796
9797 static int
9798 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9799 {
9800         guint16 mask;
9801         proto_item *item = NULL;
9802         proto_tree *tree = NULL;
9803
9804         mask = tvb_get_letohs(tvb, offset);
9805
9806         if(parent_tree){
9807                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9808                         "Flags: 0x%04x", mask);
9809                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9810         }
9811
9812         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9813                 tvb, offset, 2, mask);
9814         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9815                 tvb, offset, 2, mask);
9816
9817         offset += 2;
9818         return offset;
9819 }
9820
9821 static int
9822 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9823 {
9824         guint16 mask;
9825         proto_item *item = NULL;
9826         proto_tree *tree = NULL;
9827
9828         mask = tvb_get_letohs(tvb, offset);
9829
9830         if(parent_tree){
9831                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9832                         "Flags: 0x%04x", mask);
9833                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9834         }
9835
9836         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9837                 tvb, offset, 2, mask);
9838
9839         offset += 2;
9840
9841         return offset;
9842 }
9843
9844
9845 /* dfs inconsistency data  (4.4.2)
9846 */
9847 static int
9848 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9849     proto_tree *tree, int offset, guint16 *bcp)
9850 {
9851         int fn_len;
9852         const char *fn;
9853
9854         /*XXX shouldn this data hold version and size? unclear from doc*/
9855         /* referral version */
9856         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9857         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9858         COUNT_BYTES_TRANS_SUBR(2);
9859
9860         /* referral size */
9861         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9862         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9863         COUNT_BYTES_TRANS_SUBR(2);
9864
9865         /* referral server type */
9866         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9867         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9868         COUNT_BYTES_TRANS_SUBR(2);
9869
9870         /* referral flags */
9871         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9872         offset = dissect_dfs_referral_flags(tvb, tree, offset);
9873         *bcp -= 2;
9874
9875         /* node name */
9876         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9877         CHECK_STRING_TRANS_SUBR(fn);
9878         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9879                 fn);
9880         COUNT_BYTES_TRANS_SUBR(fn_len);
9881
9882         return offset;
9883 }
9884
9885 /* get dfs referral data  (4.4.1)
9886 */
9887 static int
9888 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9889     proto_tree *tree, int offset, guint16 *bcp)
9890 {
9891         guint16 numref;
9892         guint16 refsize;
9893         guint16 pathoffset;
9894         guint16 altpathoffset;
9895         guint16 nodeoffset;
9896         int fn_len;
9897         int stroffset;
9898         int offsetoffset;
9899         guint16 save_bc;
9900         const char *fn;
9901         int unklen;
9902         int ucstring_end;
9903         int ucstring_len;
9904
9905         /* path consumed */
9906         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9907         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9908         COUNT_BYTES_TRANS_SUBR(2);
9909
9910         /* num referrals */
9911         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9912         numref = tvb_get_letohs(tvb, offset);
9913         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9914         COUNT_BYTES_TRANS_SUBR(2);
9915
9916         /* get dfs flags */
9917         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9918         offset = dissect_get_dfs_flags(tvb, tree, offset);
9919         *bcp -= 2;
9920
9921         /* XXX - in at least one capture there appears to be 2 bytes
9922            of stuff after the Dfs flags, perhaps so that the header
9923            in front of the referral list is a multiple of 4 bytes long. */
9924         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9925         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9926         COUNT_BYTES_TRANS_SUBR(2);
9927
9928         /* if there are any referrals */
9929         if(numref){
9930                 proto_item *ref_item = NULL;
9931                 proto_tree *ref_tree = NULL;
9932                 int old_offset=offset;
9933
9934                 if(tree){
9935                         ref_item = proto_tree_add_text(tree,
9936                                 tvb, offset, *bcp, "Referrals");
9937                         ref_tree = proto_item_add_subtree(ref_item,
9938                                 ett_smb_dfs_referrals);
9939                 }
9940                 ucstring_end = -1;
9941
9942                 while(numref--){
9943                         proto_item *ri = NULL;
9944                         proto_tree *rt = NULL;
9945                         int old_offset=offset;
9946                         guint16 version;
9947
9948                         if(tree){
9949                                 ri = proto_tree_add_text(ref_tree,
9950                                         tvb, offset, *bcp, "Referral");
9951                                 rt = proto_item_add_subtree(ri,
9952                                         ett_smb_dfs_referral);
9953                         }
9954                 
9955                         /* referral version */
9956                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9957                         version = tvb_get_letohs(tvb, offset);
9958                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9959                                 tvb, offset, 2, version);
9960                         COUNT_BYTES_TRANS_SUBR(2);
9961
9962                         /* referral size */
9963                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9964                         refsize = tvb_get_letohs(tvb, offset);
9965                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9966                         COUNT_BYTES_TRANS_SUBR(2);
9967
9968                         /* referral server type */
9969                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9970                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9971                         COUNT_BYTES_TRANS_SUBR(2);
9972
9973                         /* referral flags */
9974                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9975                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
9976                         *bcp -= 2;
9977
9978                         switch(version){
9979
9980                         case 1:
9981                                 /* node name */
9982                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9983                                 CHECK_STRING_TRANS_SUBR(fn);
9984                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9985                                         fn);
9986                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9987                                 break;
9988
9989                         case 2:
9990                         case 3: /* XXX - like version 2, but not identical;
9991                                    seen in a capture, but the format isn't
9992                                    documented */
9993                                 /* proximity */
9994                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9995                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9996                                 COUNT_BYTES_TRANS_SUBR(2);
9997
9998                                 /* ttl */
9999                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10000                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10001                                 COUNT_BYTES_TRANS_SUBR(2);
10002
10003                                 /* path offset */
10004                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10005                                 pathoffset = tvb_get_letohs(tvb, offset);
10006                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10007                                 COUNT_BYTES_TRANS_SUBR(2);
10008
10009                                 /* alt path offset */
10010                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10011                                 altpathoffset = tvb_get_letohs(tvb, offset);
10012                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10013                                 COUNT_BYTES_TRANS_SUBR(2);
10014
10015                                 /* node offset */
10016                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10017                                 nodeoffset = tvb_get_letohs(tvb, offset);
10018                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10019                                 COUNT_BYTES_TRANS_SUBR(2);
10020
10021                                 /* path */
10022                                 if (pathoffset != 0) {
10023                                         stroffset = old_offset + pathoffset;
10024                                         offsetoffset = stroffset - offset;
10025                                         if (offsetoffset > 0 &&
10026                                             *bcp > offsetoffset) {
10027                                                 save_bc = *bcp;
10028                                                 *bcp -= offsetoffset;
10029                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10030                                                 CHECK_STRING_TRANS_SUBR(fn);
10031                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10032                                                         fn);
10033                                                 stroffset += fn_len;
10034                                                 if (ucstring_end < stroffset)
10035                                                         ucstring_end = stroffset;
10036                                                 *bcp = save_bc;
10037                                         }
10038                                 }
10039                         
10040                                 /* alt path */
10041                                 if (altpathoffset != 0) {
10042                                         stroffset = old_offset + altpathoffset;
10043                                         offsetoffset = stroffset - offset;
10044                                         if (offsetoffset > 0 &&
10045                                             *bcp > offsetoffset) {
10046                                                 save_bc = *bcp;
10047                                                 *bcp -= offsetoffset;
10048                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10049                                                 CHECK_STRING_TRANS_SUBR(fn);
10050                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10051                                                         fn);
10052                                                 stroffset += fn_len;
10053                                                 if (ucstring_end < stroffset)
10054                                                         ucstring_end = stroffset;
10055                                                 *bcp = save_bc;
10056                                         }
10057                                 }
10058                         
10059                                 /* node */
10060                                 if (nodeoffset != 0) {
10061                                         stroffset = old_offset + nodeoffset;
10062                                         offsetoffset = stroffset - offset;
10063                                         if (offsetoffset > 0 &&
10064                                             *bcp > offsetoffset) {
10065                                                 save_bc = *bcp;
10066                                                 *bcp -= offsetoffset;
10067                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10068                                                 CHECK_STRING_TRANS_SUBR(fn);
10069                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10070                                                         fn);
10071                                                 stroffset += fn_len;
10072                                                 if (ucstring_end < stroffset)
10073                                                         ucstring_end = stroffset;
10074                                                 *bcp = save_bc;
10075                                         }
10076                                 }
10077                                 break;
10078                         }
10079
10080                         /*
10081                          * Show anything beyond the length of the referral
10082                          * as unknown data.
10083                          */
10084                         unklen = (old_offset + refsize) - offset;
10085                         if (unklen < 0) {
10086                                 /*
10087                                  * XXX - the length is bogus.
10088                                  */
10089                                 unklen = 0;
10090                         }
10091                         if (unklen != 0) {
10092                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10093                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10094                                     offset, unklen, TRUE);
10095                                 COUNT_BYTES_TRANS_SUBR(unklen);
10096                         }
10097
10098                         proto_item_set_len(ri, offset-old_offset);
10099                 }
10100
10101                 /*
10102                  * Treat the offset past the end of the last Unicode
10103                  * string after the referrals (if any) as the last
10104                  * offset.
10105                  */
10106                 if (ucstring_end > offset) {
10107                         ucstring_len = ucstring_end - offset;
10108                         if (*bcp < ucstring_len)
10109                                 ucstring_len = *bcp;
10110                         offset += ucstring_len;
10111                         *bcp -= ucstring_len;
10112                 }
10113                 proto_item_set_len(ref_item, offset-old_offset);
10114         }
10115
10116         return offset;
10117 }
10118
10119
10120 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10121    as described in 4.2.14.1
10122 */
10123 static int
10124 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10125     int offset, guint16 *bcp, gboolean *trunc)
10126 {
10127         /* create time */
10128         CHECK_BYTE_COUNT_SUBR(4);
10129         offset = dissect_smb_datetime(tvb, tree, offset,
10130                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10131                 FALSE);
10132         *bcp -= 4;
10133
10134         /* access time */
10135         CHECK_BYTE_COUNT_SUBR(4);
10136         offset = dissect_smb_datetime(tvb, tree, offset,
10137                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10138                 FALSE);
10139         *bcp -= 4;
10140
10141         /* last write time */
10142         CHECK_BYTE_COUNT_SUBR(4);
10143         offset = dissect_smb_datetime(tvb, tree, offset,
10144                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10145                 FALSE);
10146         *bcp -= 4;
10147
10148         /* data size */
10149         CHECK_BYTE_COUNT_SUBR(4);
10150         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10151         COUNT_BYTES_SUBR(4);
10152
10153         /* allocation size */
10154         CHECK_BYTE_COUNT_SUBR(4);
10155         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10156         COUNT_BYTES_SUBR(4);
10157
10158         /* File Attributes */
10159         CHECK_BYTE_COUNT_SUBR(2);
10160         offset = dissect_file_attributes(tvb, tree, offset);
10161         *bcp -= 2;
10162
10163         /* ea size */
10164         CHECK_BYTE_COUNT_SUBR(4);
10165         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10166         COUNT_BYTES_SUBR(4);
10167
10168         *trunc = FALSE;
10169         return offset;
10170 }
10171
10172 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10173    as described in 4.2.14.2
10174 */
10175 static int
10176 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10177     int offset, guint16 *bcp, gboolean *trunc)
10178 {
10179         /* list length */
10180         CHECK_BYTE_COUNT_SUBR(4);
10181         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
10182         COUNT_BYTES_SUBR(4);
10183
10184         *trunc = FALSE;
10185         return offset;
10186 }
10187
10188 /* this dissects the SMB_INFO_IS_NAME_VALID
10189    as described in 4.2.14.3
10190 */
10191 static int
10192 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10193     int offset, guint16 *bcp, gboolean *trunc)
10194 {
10195         int fn_len;
10196         const char *fn;
10197
10198         /* file name */
10199         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10200         CHECK_STRING_SUBR(fn);
10201         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10202                 fn);
10203         COUNT_BYTES_SUBR(fn_len);
10204
10205         *trunc = FALSE;
10206         return offset;
10207 }
10208
10209 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10210    as described in 4.2.14.4
10211 */
10212 static int
10213 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10214     int offset, guint16 *bcp, gboolean *trunc)
10215 {
10216         /* create time */
10217         CHECK_BYTE_COUNT_SUBR(8);
10218         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10219         *bcp -= 8;
10220         
10221         /* access time */
10222         CHECK_BYTE_COUNT_SUBR(8);
10223         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10224         *bcp -= 8;
10225         
10226         /* last write time */
10227         CHECK_BYTE_COUNT_SUBR(8);
10228         offset = dissect_smb_64bit_time(tvb, tree, offset,
10229                 hf_smb_last_write_time);
10230         *bcp -= 8;
10231         
10232         /* last change time */
10233         CHECK_BYTE_COUNT_SUBR(8);
10234         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10235         *bcp -= 8;
10236         
10237         /* File Attributes */
10238         CHECK_BYTE_COUNT_SUBR(2);
10239         offset = dissect_file_attributes(tvb, tree, offset);
10240         *bcp -= 2;
10241
10242         *trunc = FALSE;
10243         return offset;
10244 }
10245
10246 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10247    as described in 4.2.14.5
10248 */
10249 static int
10250 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10251     int offset, guint16 *bcp, gboolean *trunc)
10252 {
10253         /* allocation size */
10254         CHECK_BYTE_COUNT_SUBR(8);
10255         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10256         COUNT_BYTES_SUBR(8);
10257
10258         /* end of file */
10259         CHECK_BYTE_COUNT_SUBR(8);
10260         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10261         COUNT_BYTES_SUBR(8);
10262
10263         /* number of links */
10264         CHECK_BYTE_COUNT_SUBR(4);
10265         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10266         COUNT_BYTES_SUBR(4);
10267
10268         /* delete pending */
10269         CHECK_BYTE_COUNT_SUBR(2);
10270         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
10271         COUNT_BYTES_SUBR(2);
10272
10273         /* is directory */
10274         CHECK_BYTE_COUNT_SUBR(1);
10275         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10276         COUNT_BYTES_SUBR(1);
10277
10278         *trunc = FALSE;
10279         return offset;
10280 }
10281
10282 /* this dissects the SMB_QUERY_FILE_EA_INFO
10283    as described in 4.2.14.6
10284 */
10285 static int
10286 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10287     int offset, guint16 *bcp, gboolean *trunc)
10288 {
10289         /* ea size */
10290         CHECK_BYTE_COUNT_SUBR(4);
10291         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10292         COUNT_BYTES_SUBR(4);
10293
10294         *trunc = FALSE;
10295         return offset;
10296 }
10297
10298 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10299    as described in 4.2.14.7
10300    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10301    as described in 4.2.14.9
10302 */
10303 static int
10304 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10305     int offset, guint16 *bcp, gboolean *trunc)
10306 {
10307         int fn_len;
10308         const char *fn;
10309
10310         /* file name len */
10311         CHECK_BYTE_COUNT_SUBR(4);
10312         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10313         COUNT_BYTES_SUBR(4);
10314
10315         /* file name */
10316         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10317         CHECK_STRING_SUBR(fn);
10318         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10319                 fn);
10320         COUNT_BYTES_SUBR(fn_len);
10321
10322         *trunc = FALSE;
10323         return offset;
10324 }
10325
10326 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10327    as described in 4.2.14.8
10328 */
10329 static int
10330 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10331     int offset, guint16 *bcp, gboolean *trunc)
10332 {
10333
10334         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
10335         if (trunc)
10336                 return offset;
10337         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
10338         if (trunc)
10339                 return offset;
10340
10341         /* index number */
10342         CHECK_BYTE_COUNT_SUBR(8);
10343         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10344         COUNT_BYTES_SUBR(8);
10345
10346         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10347         if (trunc)
10348                 return offset;
10349
10350         /* access flags */
10351         CHECK_BYTE_COUNT_SUBR(4);
10352         offset = dissect_nt_access_mask(tvb, tree, offset);
10353         COUNT_BYTES_SUBR(4);
10354
10355         /* index number */
10356         CHECK_BYTE_COUNT_SUBR(8);
10357         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10358         COUNT_BYTES_SUBR(8);
10359
10360         /* current offset */
10361         CHECK_BYTE_COUNT_SUBR(8);
10362         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10363         COUNT_BYTES_SUBR(8);
10364
10365         /* mode */
10366         CHECK_BYTE_COUNT_SUBR(4);
10367         offset = dissect_nt_create_options(tvb, tree, offset);
10368         *bcp -= 4;
10369
10370         /* alignment */
10371         CHECK_BYTE_COUNT_SUBR(4);
10372         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10373         COUNT_BYTES_SUBR(4);
10374         
10375         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10376
10377         return offset;
10378 }
10379
10380 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10381    as described in 4.2.14.10
10382 */
10383 static int
10384 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10385     int offset, guint16 *bcp, gboolean *trunc)
10386 {
10387         proto_item *item;
10388         proto_tree *tree;
10389         int old_offset;
10390         guint32 neo;
10391         int fn_len;
10392         const char *fn;
10393         int padcnt;
10394
10395         for (;;) {
10396                 old_offset = offset;
10397
10398                 /* next entry offset */
10399                 CHECK_BYTE_COUNT_SUBR(4);
10400                 if(parent_tree){
10401                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10402                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10403                 } else {
10404                         item = NULL;
10405                         tree = NULL;
10406                 }
10407
10408                 neo = tvb_get_letohl(tvb, offset);
10409                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10410                 COUNT_BYTES_SUBR(4);
10411         
10412                 /* stream name len */
10413                 CHECK_BYTE_COUNT_SUBR(4);
10414                 fn_len = tvb_get_letohl(tvb, offset);
10415                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10416                 COUNT_BYTES_SUBR(4);
10417         
10418                 /* stream size */
10419                 CHECK_BYTE_COUNT_SUBR(8);
10420                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10421                 COUNT_BYTES_SUBR(8);
10422
10423                 /* allocation size */
10424                 CHECK_BYTE_COUNT_SUBR(8);
10425                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10426                 COUNT_BYTES_SUBR(8);
10427
10428                 /* stream name */
10429                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10430                 CHECK_STRING_SUBR(fn);
10431                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10432                         fn);
10433                 COUNT_BYTES_SUBR(fn_len);
10434  
10435                 proto_item_append_text(item, ": %s", fn);
10436                 proto_item_set_len(item, offset-old_offset);
10437
10438                 if (neo == 0)
10439                         break;  /* no more structures */
10440
10441                 /* skip to next structure */
10442                 padcnt = (old_offset + neo) - offset;
10443                 if (padcnt < 0) {
10444                         /*
10445                          * XXX - this is bogus; flag it?
10446                          */
10447                         padcnt = 0;
10448                 }
10449                 if (padcnt != 0) {
10450                         CHECK_BYTE_COUNT_SUBR(padcnt);
10451                         COUNT_BYTES_SUBR(padcnt);
10452                 }
10453         }
10454
10455         *trunc = FALSE;
10456         return offset;
10457 }
10458
10459 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10460    as described in 4.2.14.11
10461 */
10462 static int
10463 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10464     int offset, guint16 *bcp, gboolean *trunc)
10465 {
10466         /* compressed file size */
10467         CHECK_BYTE_COUNT_SUBR(8);
10468         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10469         COUNT_BYTES_SUBR(8);
10470
10471         /* compression format */
10472         CHECK_BYTE_COUNT_SUBR(2);
10473         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10474         COUNT_BYTES_SUBR(2);
10475         
10476         /* compression unit shift */
10477         CHECK_BYTE_COUNT_SUBR(1);
10478         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10479         COUNT_BYTES_SUBR(1);
10480         
10481         /* compression chunk shift */
10482         CHECK_BYTE_COUNT_SUBR(1);
10483         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10484         COUNT_BYTES_SUBR(1);
10485         
10486         /* compression cluster shift */
10487         CHECK_BYTE_COUNT_SUBR(1);
10488         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10489         COUNT_BYTES_SUBR(1);
10490         
10491         /* 3 reserved bytes */
10492         CHECK_BYTE_COUNT_SUBR(3);
10493         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10494         COUNT_BYTES_SUBR(3);
10495
10496         *trunc = FALSE;
10497         return offset;
10498 }
10499
10500
10501
10502 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
10503 static int
10504 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10505     int offset, guint16 *bcp)
10506 {
10507         smb_info_t *si;
10508         gboolean trunc;
10509
10510         if(!*bcp){
10511                 return offset;
10512         }
10513         
10514         si = (smb_info_t *)pinfo->private_data;
10515         switch(si->info_level){
10516         case 1:         /*Info Standard*/
10517         case 2:         /*Info Query EA Size*/
10518                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
10519                     &trunc);
10520                 break;
10521         case 3:         /*Info Query EAs From List*/
10522         case 4:         /*Info Query All EAs*/
10523                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
10524                     &trunc);
10525                 break;
10526         case 6:         /*Info Is Name Valid*/
10527                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
10528                     &trunc);
10529                 break;
10530         case 0x0101:    /*Query File Basic Info*/
10531         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10532                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
10533                     &trunc);
10534                 break;
10535         case 0x0102:    /*Query File Standard Info*/
10536         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
10537                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
10538                     &trunc);
10539                 break;
10540         case 0x0103:    /*Query File EA Info*/
10541         case 1007:      /* SMB_FILE_EA_INFORMATION */
10542                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
10543                     &trunc);
10544                 break;
10545         case 0x0104:    /*Query File Name Info*/
10546         case 1009:      /* SMB_FILE_NAME_INFORMATION */
10547                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10548                     &trunc);
10549                 break;
10550         case 0x0107:    /*Query File All Info*/
10551         case 1018:      /* SMB_FILE_ALL_INFORMATION */
10552                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
10553                     &trunc);
10554                 break;
10555         case 0x0108:    /*Query File Alt File Info*/
10556         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
10557                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10558                     &trunc);
10559                 break;
10560         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
10561                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
10562         case 0x0109:    /*Query File Stream Info*/
10563                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
10564                     &trunc);
10565                 break;
10566         case 0x010b:    /*Query File Compression Info*/
10567         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
10568                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
10569                     &trunc);
10570                 break;
10571         case 0x0200:    /*Set File Unix Basic*/
10572                 /* XXX add this from the SNIA doc */
10573                 break;
10574         case 0x0201:    /*Set File Unix Link*/
10575                 /* XXX add this from the SNIA doc */
10576                 break;
10577         case 0x0202:    /*Set File Unix HardLink*/
10578                 /* XXX add this from the SNIA doc */
10579                 break;
10580         }
10581         
10582         return offset;
10583 }
10584
10585
10586 static const true_false_string tfs_quota_flags_deny_disk = {
10587         "DENY DISK SPACE for users exceeding quota limit",
10588         "Do NOT deny disk space for users exceeding quota limit"
10589 };
10590 static const true_false_string tfs_quota_flags_log_limit = {
10591         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10592         "Do NOT log event when a user exceeds their quota limit"
10593 };
10594 static const true_false_string tfs_quota_flags_log_warning = {
10595         "LOG EVENT when a user exceeds their WARNING LEVEL",
10596         "Do NOT log event when a user exceeds their warning level"
10597 };
10598 static const true_false_string tfs_quota_flags_enabled = {
10599         "Quotas are ENABLED of this fs",
10600         "Quotas are NOT enabled on this fs"
10601 };
10602 static void
10603 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10604 {
10605         guint8 mask;
10606         proto_item *item = NULL;
10607         proto_tree *tree = NULL;
10608
10609         mask = tvb_get_guint8(tvb, offset);
10610
10611         if(parent_tree){
10612                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10613                         "Quota Flags: 0x%02x %s", mask,
10614                         mask?"Enabled":"Disabled");
10615                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10616         }
10617
10618         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10619                 tvb, offset, 1, mask);
10620         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10621                 tvb, offset, 1, mask);
10622         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10623                 tvb, offset, 1, mask);
10624
10625         if(mask && (!(mask&0x01))){
10626                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10627                         tvb, offset, 1, 0x01);
10628         } else {
10629                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10630                         tvb, offset, 1, mask);
10631         }
10632
10633 }
10634
10635 static int
10636 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
10637 {
10638         /* first 24 bytes are unknown */
10639         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10640         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10641                     offset, 24, TRUE);
10642         COUNT_BYTES_TRANS_SUBR(24);
10643
10644         /* number of bytes for quota warning */
10645         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10646         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10647         COUNT_BYTES_TRANS_SUBR(8);
10648
10649         /* number of bytes for quota limit */
10650         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10651         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10652         COUNT_BYTES_TRANS_SUBR(8);
10653
10654         /* one byte of quota flags */
10655         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10656         dissect_quota_flags(tvb, tree, offset);
10657         COUNT_BYTES_TRANS_SUBR(1);
10658
10659         /* these 7 bytes are unknown */
10660         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10661         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10662                     offset, 7, TRUE);
10663         COUNT_BYTES_TRANS_SUBR(7);
10664
10665         return offset;
10666 }
10667
10668 static int
10669 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10670     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10671 {
10672         proto_item *item = NULL;
10673         proto_tree *tree = NULL;
10674         smb_info_t *si;
10675
10676         si = (smb_info_t *)pinfo->private_data;
10677
10678         if(parent_tree){
10679                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10680                                 "%s Data",
10681                                 val_to_str(subcmd, trans2_cmd_vals, 
10682                                                 "Unknown (0x%02x)"));
10683                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10684         }
10685
10686         switch(subcmd){
10687         case 0x00:      /*TRANS2_OPEN2*/
10688                 /* XXX dont know how to decode FEAList */
10689                 break;
10690         case 0x01:      /*TRANS2_FIND_FIRST2*/
10691                 /* XXX dont know how to decode FEAList */
10692                 break;
10693         case 0x02:      /*TRANS2_FIND_NEXT2*/
10694                 /* XXX dont know how to decode FEAList */
10695                 break;
10696         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10697                 /* no data field in this request */
10698                 break;
10699         case 0x04:      /* TRANS2_SET_QUOTA */
10700                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
10701                 break;
10702         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10703                 /* no data field in this request */
10704                 /*
10705                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10706                  * Extensions Version 3.0, Document Version 1.11,
10707                  * July 19, 1990" says there may be "Additional
10708                  * FileInfoLevel dependent information" here.
10709                  *
10710                  * Was that just a cut-and-pasteo?
10711                  * TRANS2_SET_PATH_INFORMATION *does* have that information
10712                  * here.
10713                  */
10714                 break;
10715         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10716                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10717                 break;
10718         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10719                 /* no data field in this request */
10720                 /*
10721                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10722                  * Extensions Version 3.0, Document Version 1.11,
10723                  * July 19, 1990" says there may be "Additional
10724                  * FileInfoLevel dependent information" here.
10725                  *
10726                  * Was that just a cut-and-pasteo?
10727                  * TRANS2_SET_FILE_INFORMATION *does* have that information
10728                  * here.
10729                  */
10730                 break;
10731         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10732                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10733                 break;
10734         case 0x09:      /*TRANS2_FSCTL*/
10735                 /*XXX dont know how to decode this yet */
10736
10737                 /*
10738                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10739                  * Extensions Version 3.0, Document Version 1.11,
10740                  * July 19, 1990" says this this contains a
10741                  * "File system specific data block".  (That means we
10742                  * may not be able to dissect it in any case.)
10743                  */
10744                 break;
10745         case 0x0a:      /*TRANS2_IOCTL2*/
10746                 /*XXX dont know how to decode this yet */
10747
10748                 /*
10749                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10750                  * Extensions Version 3.0, Document Version 1.11,
10751                  * July 19, 1990" says this this contains a
10752                  * "Device/function specific data block".  (That
10753                  * means we may not be able to dissect it in any case.)
10754                  */
10755                 break;
10756         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10757                 /*XXX dont know how to decode this yet */
10758
10759                 /*
10760                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10761                  * Extensions Version 3.0, Document Version 1.11,
10762                  * July 19, 1990" says this this contains "additional
10763                  * level dependent match data".
10764                  */
10765                 break;
10766         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10767                 /*XXX dont know how to decode this yet */
10768
10769                 /*
10770                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10771                  * Extensions Version 3.0, Document Version 1.11,
10772                  * July 19, 1990" says this this contains "additional
10773                  * level dependent monitor information".
10774                  */
10775                 break;
10776         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10777                 /* XXX optional FEAList, unknown what FEAList looks like*/
10778                 break;
10779         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10780                 /*XXX dont know how to decode this yet */
10781                 break;
10782         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10783                 /* no data field in this request */
10784                 break;
10785         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10786                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10787                 break;
10788         }
10789
10790         /* ooops there were data we didnt know how to process */
10791         if(dc != 0){
10792                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10793                 offset += dc;
10794         }
10795
10796         return offset;
10797 }
10798
10799
10800 static void
10801 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10802     proto_tree *tree)
10803 {
10804         int i;
10805         int offset;
10806         guint length;
10807
10808         /*
10809          * Show the setup words.
10810          */
10811         if (s_tvb != NULL) {
10812                 length = tvb_reported_length(s_tvb);
10813                 for (i = 0, offset = 0; length >= 2;
10814                     i++, offset += 2, length -= 2) {
10815                         /*
10816                          * XXX - add a setup word filterable field?
10817                          */
10818                         proto_tree_add_text(tree, s_tvb, offset, 2,
10819                             "Setup Word %d: 0x%04x", i,
10820                             tvb_get_letohs(s_tvb, offset));
10821                 }
10822         }
10823
10824         /*
10825          * Show the parameters, if any.
10826          */
10827         if (p_tvb != NULL) {
10828                 length = tvb_reported_length(p_tvb);
10829                 if (length != 0) {
10830                         proto_tree_add_text(tree, p_tvb, 0, length,
10831                             "Parameters: %s",
10832                             tvb_bytes_to_str(p_tvb, 0, length));
10833                 }
10834         }
10835
10836         /*
10837          * Show the data, if any.
10838          */
10839         if (d_tvb != NULL) {
10840                 length = tvb_reported_length(d_tvb);
10841                 if (length != 0) {
10842                         proto_tree_add_text(tree, d_tvb, 0, length,
10843                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10844                 }
10845         }
10846 }
10847
10848 /* This routine handles the following 4 calls
10849    Transaction  0x25
10850    Transaction Secondary 0x26
10851    Transaction2 0x32
10852    Transaction2 Secondary 0x33
10853 */
10854 static int
10855 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
10856 {
10857         guint8 wc, sc=0;
10858         int so=offset;
10859         int sl=0;
10860         int spo=offset;
10861         int spc=0;
10862         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10863         int subcmd = -1;
10864         guint32 to;
10865         int an_len;
10866         const char *an = NULL;
10867         smb_info_t *si;
10868         smb_transact2_info_t *t2i;
10869         smb_transact_info_t *tri;
10870         guint16 bc;
10871         int padcnt;
10872         gboolean dissected_trans;
10873
10874         si = (smb_info_t *)pinfo->private_data;
10875
10876         WORD_COUNT;
10877
10878         if(wc==8){
10879                 /*secondary client request*/
10880
10881                 /* total param count, only a 16bit integer here*/
10882                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10883                 offset += 2;
10884         
10885                 /* total data count , only 16bit integer here*/
10886                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10887                 offset += 2;
10888
10889                 /* param count */
10890                 pc = tvb_get_letohs(tvb, offset);
10891                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10892                 offset += 2;
10893
10894                 /* param offset */
10895                 po = tvb_get_letohs(tvb, offset);
10896                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10897                 offset += 2;
10898
10899                 /* param disp */
10900                 pd = tvb_get_letohs(tvb, offset);
10901                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10902                 offset += 2;
10903         
10904                 /* data count */
10905                 dc = tvb_get_letohs(tvb, offset);
10906                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10907                 offset += 2;
10908
10909                 /* data offset */
10910                 od = tvb_get_letohs(tvb, offset);
10911                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10912                 offset += 2;
10913         
10914                 /* data disp */
10915                 dd = tvb_get_letohs(tvb, offset);
10916                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10917                 offset += 2;
10918
10919                 if(si->cmd==SMB_COM_TRANSACTION2){
10920                         guint16 fid;
10921
10922                         /* fid */
10923                         fid = tvb_get_letohs(tvb, offset);
10924                         add_fid(tvb, pinfo, tree, offset, 2, fid);
10925
10926                         offset += 2;
10927                 }
10928
10929                 /* There are no setup words. */
10930                 so = offset;
10931                 sc = 0;
10932                 sl = 0;
10933         } else {
10934                 /* it is not a secondary request */
10935
10936                 /* total param count , only a 16 bit integer here*/
10937                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10938                 offset += 2;
10939
10940                 /* total data count , only 16bit integer here*/
10941                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10942                 offset += 2;
10943
10944                 /* max param count , only 16bit integer here*/
10945                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10946                 offset += 2;
10947
10948                 /* max data count, only 16bit integer here*/
10949                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10950                 offset += 2;
10951
10952                 /* max setup count, only 16bit integer here*/
10953                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10954                 offset += 1;
10955
10956                 /* reserved byte */
10957                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10958                 offset += 1;
10959
10960                 /* transaction flags */
10961                 tf = dissect_transaction_flags(tvb, tree, offset);
10962                 offset += 2;
10963
10964                 /* timeout */
10965                 to = tvb_get_letohl(tvb, offset);
10966                 if (to == 0)
10967                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
10968                 else if (to == 0xffffffff)
10969                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
10970                 else
10971                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
10972                 offset += 4;
10973
10974                 /* 2 reserved bytes */
10975                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10976                 offset += 2;
10977
10978                 /* param count */
10979                 pc = tvb_get_letohs(tvb, offset);
10980                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10981                 offset += 2;
10982         
10983                 /* param offset */
10984                 po = tvb_get_letohs(tvb, offset);
10985                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10986                 offset += 2;
10987
10988                 /* param displacement is zero here */
10989                 pd = 0;
10990
10991                 /* data count */
10992                 dc = tvb_get_letohs(tvb, offset);
10993                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10994                 offset += 2;
10995
10996                 /* data offset */
10997                 od = tvb_get_letohs(tvb, offset);
10998                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10999                 offset += 2;
11000
11001                 /* data displacement is zero here */
11002                 dd = 0;
11003
11004                 /* setup count */
11005                 sc = tvb_get_guint8(tvb, offset);
11006                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11007                 offset += 1;
11008
11009                 /* reserved byte */
11010                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11011                 offset += 1;
11012                 
11013                 /* this is where the setup bytes, if any start */       
11014                 so = offset;
11015                 sl = sc*2;
11016
11017                 /* if there were any setup bytes, decode them */
11018                 if(sc){
11019                         switch(si->cmd){
11020
11021                         case SMB_COM_TRANSACTION2:
11022                                 /* TRANSACTION2 only has one setup word and
11023                                    that is the subcommand code.
11024
11025                                    XXX - except for TRANS2_FSCTL
11026                                    and TRANS2_IOCTL. */
11027                                 subcmd = tvb_get_letohs(tvb, offset);
11028                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11029                                     tvb, offset, 2, subcmd);
11030                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11031                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11032                                             val_to_str(subcmd, trans2_cmd_vals, 
11033                                                 "Unknown (0x%02x)"));
11034                                 }
11035                                 if (!si->unidir) {
11036                                         if(!pinfo->fd->flags.visited){
11037                                                 /* 
11038                                                  * Allocate a new
11039                                                  * smb_transact2_info_t
11040                                                  * structure.
11041                                                  */
11042                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11043                                                 t2i->subcmd = subcmd;
11044                                                 t2i->info_level = -1;
11045                                                 t2i->resume_keys = FALSE;
11046                                                 si->sip->extra_info = t2i;
11047                                         }
11048                                 }
11049
11050                                 /*
11051                                  * XXX - process TRANS2_FSCTL and
11052                                  * TRANS2_IOCTL setup words here.
11053                                  */
11054                                 break;
11055
11056                         case SMB_COM_TRANSACTION:
11057                                 /* TRANSACTION setup words processed below */
11058                                 break;
11059                         }
11060
11061                         offset += sl;
11062                 }
11063         }
11064
11065         BYTE_COUNT;
11066         
11067         if(wc!=8){
11068                 /* primary request */
11069                 /* name is NULL if transaction2 */
11070                 if(si->cmd == SMB_COM_TRANSACTION){
11071                         /* Transaction Name */
11072                         an = get_unicode_or_ascii_string(tvb, &offset,
11073                                 pinfo, &an_len, FALSE, FALSE, &bc);
11074                         if (an == NULL)
11075                                 goto endofcommand;
11076                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11077                                 offset, an_len, an);
11078                         COUNT_BYTES(an_len);
11079                 }
11080         }
11081
11082         /*
11083          * The pipe or mailslot arguments for Transaction start with
11084          * the first setup word (or where the first setup word would
11085          * be if there were any setup words), and run to the current
11086          * offset (which could mean that there aren't any).
11087          */
11088         spo = so;
11089         spc = offset - spo;
11090
11091         /* parameters */
11092         if(po>offset){
11093                 /* We have some initial padding bytes.
11094                 */
11095                 padcnt = po-offset;
11096                 if (padcnt > bc)
11097                         padcnt = bc;
11098                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11099                 COUNT_BYTES(padcnt);
11100         }
11101         if(pc){
11102                 CHECK_BYTE_COUNT(pc);
11103                 switch(si->cmd) {
11104
11105                 case SMB_COM_TRANSACTION2:
11106                         /* TRANSACTION2 parameters*/
11107                         offset = dissect_transaction2_request_parameters(tvb,
11108                             pinfo, tree, offset, subcmd, pc);
11109                         bc -= pc;
11110                         break;
11111
11112                 case SMB_COM_TRANSACTION:
11113                         /* TRANSACTION parameters processed below */
11114                         COUNT_BYTES(pc);
11115                         break;
11116                 }
11117         }
11118
11119         /* data */
11120         if(od>offset){
11121                 /* We have some initial padding bytes.
11122                 */
11123                 padcnt = od-offset;
11124                 if (padcnt > bc)
11125                         padcnt = bc;
11126                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11127                 COUNT_BYTES(padcnt);
11128         }
11129         if(dc){
11130                 CHECK_BYTE_COUNT(dc);
11131                 switch(si->cmd){
11132
11133                 case SMB_COM_TRANSACTION2:
11134                         /* TRANSACTION2 data*/
11135                         offset = dissect_transaction2_request_data(tvb, pinfo,
11136                             tree, offset, subcmd, dc);
11137                         bc -= dc;
11138                         break;
11139
11140                 case SMB_COM_TRANSACTION:
11141                         /* TRANSACTION data processed below */
11142                         COUNT_BYTES(dc);
11143                         break;
11144                 }
11145         }
11146
11147         /*TRANSACTION request parameters */
11148         if(si->cmd==SMB_COM_TRANSACTION){
11149                 /*XXX replace this block with a function and use that one 
11150                      for both requests/responses*/
11151                 if(dd==0){
11152                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11153                         tvbuff_t *sp_tvb, *pd_tvb;
11154
11155                         if(pc>0){
11156                                 if(pc>tvb_length_remaining(tvb, po)){
11157                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11158                                 } else {
11159                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11160                                 }
11161                         } else {
11162                                 p_tvb = NULL;
11163                         }
11164                         if(dc>0){
11165                                 if(dc>tvb_length_remaining(tvb, od)){
11166                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11167                                 } else {
11168                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11169                                 }
11170                         } else {
11171                                 d_tvb = NULL;
11172                         }
11173                         if(sl){
11174                                 if(sl>tvb_length_remaining(tvb, so)){
11175                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11176                                 } else {
11177                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11178                                 }
11179                         } else {
11180                                 s_tvb = NULL;
11181                         }
11182
11183                         if (!si->unidir) {
11184                                 if(!pinfo->fd->flags.visited){
11185                                         /* 
11186                                          * Allocate a new smb_transact_info_t
11187                                          * structure.
11188                                          */
11189                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11190                                         tri->subcmd = -1;
11191                                         tri->trans_subcmd = -1;
11192                                         tri->function = -1;
11193                                         tri->fid = -1;
11194                                         tri->lanman_cmd = 0;
11195                                         tri->param_descrip = NULL;
11196                                         tri->data_descrip = NULL;
11197                                         tri->aux_data_descrip = NULL;
11198                                         tri->info_level = -1;
11199                                         si->sip->extra_info = tri;
11200                                 } else {
11201                                         /*
11202                                          * We already filled the structure
11203                                          * in; don't bother doing so again.
11204                                          */
11205                                         tri = NULL;
11206                                 }
11207                         } else {
11208                                 /*
11209                                  * This is a unidirectional message, for
11210                                  * which there will be no reply; don't
11211                                  * bother allocating an "smb_transact_info_t"
11212                                  * structure for it.
11213                                  */
11214                                 tri = NULL;
11215                         }
11216                         dissected_trans = FALSE;
11217                         if(strncmp("\\PIPE\\", an, 6) == 0){
11218                                 if (tri != NULL)
11219                                         tri->subcmd=TRANSACTION_PIPE;
11220
11221                                 /*
11222                                  * A tvbuff containing the setup words and
11223                                  * the pipe path.
11224                                  */
11225                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11226
11227                                 /*
11228                                  * A tvbuff containing the parameters and the
11229                                  * data.
11230                                  */
11231                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11232
11233                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11234                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11235                                     top_tree);
11236                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11237                                 if (tri != NULL)
11238                                         tri->subcmd=TRANSACTION_MAILSLOT;
11239
11240                                 /*
11241                                  * A tvbuff containing the setup words and
11242                                  * the mailslot path.
11243                                  */
11244                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11245                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11246                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11247                         }
11248                         if (!dissected_trans)
11249                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11250                 } else {
11251                         if(check_col(pinfo->cinfo, COL_INFO)){
11252                                 col_append_str(pinfo->cinfo, COL_INFO,
11253                                         "[transact continuation]");
11254                         }
11255                 }
11256         }
11257
11258         END_OF_SMB
11259
11260         return offset;
11261 }
11262
11263  
11264
11265 static int
11266 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11267     int offset, guint16 *bcp, gboolean *trunc)
11268 {
11269         int fn_len;
11270         const char *fn;
11271         int old_offset = offset;
11272         proto_item *item = NULL;
11273         proto_tree *tree = NULL;
11274         smb_info_t *si;
11275         smb_transact2_info_t *t2i;
11276         gboolean resume_keys = FALSE;
11277
11278         si = (smb_info_t *)pinfo->private_data;
11279         if (si->sip != NULL) {
11280                 t2i = si->sip->extra_info;
11281                 if (t2i != NULL)
11282                         resume_keys = t2i->resume_keys;
11283         }
11284
11285         if(parent_tree){
11286                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11287                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11288                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11289         }
11290
11291         if (resume_keys) {
11292                 /* resume key */
11293                 CHECK_BYTE_COUNT_SUBR(4);
11294                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11295                 COUNT_BYTES_SUBR(4);
11296         }
11297
11298         /* create time */
11299         CHECK_BYTE_COUNT_SUBR(4);
11300         offset = dissect_smb_datetime(tvb, tree, offset,
11301                 hf_smb_create_time,
11302                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11303         *bcp -= 4;
11304
11305         /* access time */
11306         CHECK_BYTE_COUNT_SUBR(4);
11307         offset = dissect_smb_datetime(tvb, tree, offset,
11308                 hf_smb_access_time,
11309                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11310         *bcp -= 4;
11311
11312         /* last write time */
11313         CHECK_BYTE_COUNT_SUBR(4);
11314         offset = dissect_smb_datetime(tvb, tree, offset,
11315                 hf_smb_last_write_time,
11316                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11317         *bcp -= 4;
11318
11319         /* data size */
11320         CHECK_BYTE_COUNT_SUBR(4);
11321         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11322         COUNT_BYTES_SUBR(4);
11323
11324         /* allocation size */
11325         CHECK_BYTE_COUNT_SUBR(4);
11326         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11327         COUNT_BYTES_SUBR(4);
11328
11329         /* File Attributes */
11330         CHECK_BYTE_COUNT_SUBR(2);
11331         offset = dissect_file_attributes(tvb, tree, offset);
11332         *bcp -= 2;
11333
11334         /* file name len */
11335         CHECK_BYTE_COUNT_SUBR(1);
11336         fn_len = tvb_get_guint8(tvb, offset);
11337         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11338         COUNT_BYTES_SUBR(1);
11339         if (si->unicode)
11340                 fn_len += 2;    /* include terminating '\0' */
11341         else
11342                 fn_len++;       /* include terminating '\0' */
11343
11344         /* file name */
11345         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11346         CHECK_STRING_SUBR(fn);
11347         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11348                 fn);
11349         COUNT_BYTES_SUBR(fn_len);
11350
11351         if (check_col(pinfo->cinfo, COL_INFO)) {
11352                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11353                 fn);
11354         }
11355  
11356         proto_item_append_text(item, " File: %s", fn);
11357         proto_item_set_len(item, offset-old_offset);
11358
11359         *trunc = FALSE;
11360         return offset;
11361 }
11362
11363 static int
11364 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11365     int offset, guint16 *bcp, gboolean *trunc)
11366 {
11367         int fn_len;
11368         const char *fn;
11369         int old_offset = offset;
11370         proto_item *item = NULL;
11371         proto_tree *tree = NULL;
11372         smb_info_t *si;
11373         smb_transact2_info_t *t2i;
11374         gboolean resume_keys = FALSE;
11375
11376         si = (smb_info_t *)pinfo->private_data;
11377         if (si->sip != NULL) {
11378                 t2i = si->sip->extra_info;
11379                 if (t2i != NULL)
11380                         resume_keys = t2i->resume_keys;
11381         }
11382
11383         if(parent_tree){
11384                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11385                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11386                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11387         }
11388
11389         if (resume_keys) {
11390                 /* resume key */
11391                 CHECK_BYTE_COUNT_SUBR(4);
11392                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11393                 COUNT_BYTES_SUBR(4);
11394         }
11395  
11396         /* create time */
11397         CHECK_BYTE_COUNT_SUBR(4);
11398         offset = dissect_smb_datetime(tvb, tree, offset,
11399                 hf_smb_create_time,
11400                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11401         *bcp -= 4;
11402
11403         /* access time */
11404         CHECK_BYTE_COUNT_SUBR(4);
11405         offset = dissect_smb_datetime(tvb, tree, offset,
11406                 hf_smb_access_time,
11407                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11408         *bcp -= 4;
11409
11410         /* last write time */
11411         CHECK_BYTE_COUNT_SUBR(4);
11412         offset = dissect_smb_datetime(tvb, tree, offset,
11413                 hf_smb_last_write_time,
11414                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11415         *bcp -= 4;
11416
11417         /* data size */
11418         CHECK_BYTE_COUNT_SUBR(4);
11419         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11420         COUNT_BYTES_SUBR(4);
11421
11422         /* allocation size */
11423         CHECK_BYTE_COUNT_SUBR(4);
11424         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11425         COUNT_BYTES_SUBR(4);
11426
11427         /* File Attributes */
11428         CHECK_BYTE_COUNT_SUBR(2);
11429         offset = dissect_file_attributes(tvb, tree, offset);
11430         *bcp -= 2;
11431
11432         /* ea size */
11433         CHECK_BYTE_COUNT_SUBR(4);
11434         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11435         COUNT_BYTES_SUBR(4);
11436
11437         /* file name len */
11438         CHECK_BYTE_COUNT_SUBR(1);
11439         fn_len = tvb_get_guint8(tvb, offset);
11440         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11441         COUNT_BYTES_SUBR(1);
11442
11443         /* file name */
11444         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11445         CHECK_STRING_SUBR(fn);
11446         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11447                 fn);
11448         COUNT_BYTES_SUBR(fn_len);
11449         if (si->unicode)
11450                 fn_len += 2;    /* include terminating '\0' */
11451         else
11452                 fn_len++;       /* include terminating '\0' */
11453
11454         if (check_col(pinfo->cinfo, COL_INFO)) {
11455                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11456                 fn);
11457         }
11458
11459         proto_item_append_text(item, " File: %s", fn);
11460         proto_item_set_len(item, offset-old_offset);
11461
11462         *trunc = FALSE;
11463         return offset;
11464 }
11465
11466 static int
11467 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11468     int offset, guint16 *bcp, gboolean *trunc)
11469 {
11470         int fn_len;
11471         const char *fn;
11472         int old_offset = offset;
11473         proto_item *item = NULL;
11474         proto_tree *tree = NULL;
11475         smb_info_t *si;
11476         guint32 neo;
11477         int padcnt;
11478
11479         si = (smb_info_t *)pinfo->private_data;
11480
11481         if(parent_tree){
11482                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11483                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11484                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11485         }
11486
11487         /*
11488          * We assume that the presence of a next entry offset implies the
11489          * absence of a resume key, as appears to be the case for 4.3.4.6.
11490          */
11491
11492         /* next entry offset */
11493         CHECK_BYTE_COUNT_SUBR(4);
11494         neo = tvb_get_letohl(tvb, offset);
11495         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11496         COUNT_BYTES_SUBR(4);
11497         
11498         /* file index */
11499         CHECK_BYTE_COUNT_SUBR(4);
11500         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11501         COUNT_BYTES_SUBR(4);
11502
11503         /* create time */
11504         CHECK_BYTE_COUNT_SUBR(8);
11505         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11506         *bcp -= 8;
11507         
11508         /* access time */
11509         CHECK_BYTE_COUNT_SUBR(8);
11510         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11511         *bcp -= 8;
11512         
11513         /* last write time */
11514         CHECK_BYTE_COUNT_SUBR(8);
11515         offset = dissect_smb_64bit_time(tvb, tree, offset,
11516                 hf_smb_last_write_time);
11517         *bcp -= 8;
11518         
11519         /* last change time */
11520         CHECK_BYTE_COUNT_SUBR(8);
11521         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11522         *bcp -= 8;
11523         
11524         /* end of file */
11525         CHECK_BYTE_COUNT_SUBR(8);
11526         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11527         COUNT_BYTES_SUBR(8);
11528
11529         /* allocation size */
11530         CHECK_BYTE_COUNT_SUBR(8);
11531         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11532         COUNT_BYTES_SUBR(8);
11533
11534         /* Extended File Attributes */
11535         CHECK_BYTE_COUNT_SUBR(4);
11536         offset = dissect_file_ext_attr(tvb, tree, offset);
11537         *bcp -= 4;
11538
11539         /* file name len */
11540         CHECK_BYTE_COUNT_SUBR(4);
11541         fn_len = tvb_get_letohl(tvb, offset);
11542         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11543         COUNT_BYTES_SUBR(4);
11544
11545         /* file name */
11546         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11547         CHECK_STRING_SUBR(fn);
11548         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11549                 fn);
11550         COUNT_BYTES_SUBR(fn_len);
11551
11552         if (check_col(pinfo->cinfo, COL_INFO)) {
11553                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11554                 fn);
11555         }
11556
11557         /* skip to next structure */
11558         if(neo){
11559                 padcnt = (old_offset + neo) - offset;
11560                 if (padcnt < 0) {
11561                         /*
11562                          * XXX - this is bogus; flag it?
11563                          */
11564                         padcnt = 0;
11565                 }
11566                 if (padcnt != 0) {
11567                         CHECK_BYTE_COUNT_SUBR(padcnt);
11568                         COUNT_BYTES_SUBR(padcnt);
11569                 }
11570         }
11571
11572         proto_item_append_text(item, " File: %s", fn);
11573         proto_item_set_len(item, offset-old_offset);
11574
11575         *trunc = FALSE;
11576         return offset;
11577 }
11578
11579 static int
11580 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11581     int offset, guint16 *bcp, gboolean *trunc)
11582 {
11583         int fn_len;
11584         const char *fn;
11585         int old_offset = offset;
11586         proto_item *item = NULL;
11587         proto_tree *tree = NULL;
11588         smb_info_t *si;
11589         guint32 neo;
11590         int padcnt;
11591
11592         si = (smb_info_t *)pinfo->private_data;
11593
11594         if(parent_tree){
11595                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11596                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11597                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11598         }
11599
11600         /*
11601          * We assume that the presence of a next entry offset implies the
11602          * absence of a resume key, as appears to be the case for 4.3.4.6.
11603          */
11604
11605         /* next entry offset */
11606         CHECK_BYTE_COUNT_SUBR(4);
11607         neo = tvb_get_letohl(tvb, offset);
11608         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11609         COUNT_BYTES_SUBR(4);
11610         
11611         /* file index */
11612         CHECK_BYTE_COUNT_SUBR(4);
11613         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11614         COUNT_BYTES_SUBR(4);
11615
11616         /* create time */
11617         CHECK_BYTE_COUNT_SUBR(8);
11618         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11619         *bcp -= 8;
11620         
11621         /* access time */
11622         CHECK_BYTE_COUNT_SUBR(8);
11623         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11624         *bcp -= 8;
11625         
11626         /* last write time */
11627         CHECK_BYTE_COUNT_SUBR(8);
11628         offset = dissect_smb_64bit_time(tvb, tree, offset,
11629                 hf_smb_last_write_time);
11630         *bcp -= 8;
11631         
11632         /* last change time */
11633         CHECK_BYTE_COUNT_SUBR(8);
11634         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11635         *bcp -= 8;
11636         
11637         /* end of file */
11638         CHECK_BYTE_COUNT_SUBR(8);
11639         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11640         COUNT_BYTES_SUBR(8);
11641
11642         /* allocation size */
11643         CHECK_BYTE_COUNT_SUBR(8);
11644         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11645         COUNT_BYTES_SUBR(8);
11646
11647         /* Extended File Attributes */
11648         CHECK_BYTE_COUNT_SUBR(4);
11649         offset = dissect_file_ext_attr(tvb, tree, offset);
11650         *bcp -= 4;
11651
11652         /* file name len */
11653         CHECK_BYTE_COUNT_SUBR(4);
11654         fn_len = tvb_get_letohl(tvb, offset);
11655         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11656         COUNT_BYTES_SUBR(4);
11657
11658         /* ea size */
11659         CHECK_BYTE_COUNT_SUBR(4);
11660         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11661         COUNT_BYTES_SUBR(4);
11662
11663         /* file name */
11664         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11665         CHECK_STRING_SUBR(fn);
11666         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11667                 fn);
11668         COUNT_BYTES_SUBR(fn_len);
11669
11670         if (check_col(pinfo->cinfo, COL_INFO)) {
11671                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11672                 fn);
11673         }
11674
11675         /* skip to next structure */
11676         if(neo){
11677                 padcnt = (old_offset + neo) - offset;
11678                 if (padcnt < 0) {
11679                         /*
11680                          * XXX - this is bogus; flag it?
11681                          */
11682                         padcnt = 0;
11683                 }
11684                 if (padcnt != 0) {
11685                         CHECK_BYTE_COUNT_SUBR(padcnt);
11686                         COUNT_BYTES_SUBR(padcnt);
11687                 }
11688         }
11689
11690         proto_item_append_text(item, " File: %s", fn);
11691         proto_item_set_len(item, offset-old_offset);
11692
11693         *trunc = FALSE;
11694         return offset;
11695 }
11696
11697 static int
11698 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11699     int offset, guint16 *bcp, gboolean *trunc)
11700 {
11701         int fn_len, sfn_len;
11702         const char *fn, *sfn;
11703         int old_offset = offset;
11704         proto_item *item = NULL;
11705         proto_tree *tree = NULL;
11706         smb_info_t *si;
11707         guint32 neo;
11708         int padcnt;
11709
11710         si = (smb_info_t *)pinfo->private_data;
11711
11712         if(parent_tree){
11713                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11714                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11715                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11716         }
11717
11718         /*
11719          * XXX - I have not seen any of these that contain a resume
11720          * key, even though some of the requests had the "return resume
11721          * key" flag set.
11722          */
11723
11724         /* next entry offset */
11725         CHECK_BYTE_COUNT_SUBR(4);
11726         neo = tvb_get_letohl(tvb, offset);
11727         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11728         COUNT_BYTES_SUBR(4);
11729         
11730         /* file index */
11731         CHECK_BYTE_COUNT_SUBR(4);
11732         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11733         COUNT_BYTES_SUBR(4);
11734
11735         /* create time */
11736         CHECK_BYTE_COUNT_SUBR(8);
11737         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11738         *bcp -= 8;
11739         
11740         /* access time */
11741         CHECK_BYTE_COUNT_SUBR(8);
11742         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11743         *bcp -= 8;
11744         
11745         /* last write time */
11746         CHECK_BYTE_COUNT_SUBR(8);
11747         offset = dissect_smb_64bit_time(tvb, tree, offset,
11748                 hf_smb_last_write_time);
11749         *bcp -= 8;
11750         
11751         /* last change time */
11752         CHECK_BYTE_COUNT_SUBR(8);
11753         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11754         *bcp -= 8;
11755         
11756         /* end of file */
11757         CHECK_BYTE_COUNT_SUBR(8);
11758         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11759         COUNT_BYTES_SUBR(8);
11760
11761         /* allocation size */
11762         CHECK_BYTE_COUNT_SUBR(8);
11763         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11764         COUNT_BYTES_SUBR(8);
11765
11766         /* Extended File Attributes */
11767         CHECK_BYTE_COUNT_SUBR(4);
11768         offset = dissect_file_ext_attr(tvb, tree, offset);
11769         *bcp -= 4;
11770
11771         /* file name len */
11772         CHECK_BYTE_COUNT_SUBR(4);
11773         fn_len = tvb_get_letohl(tvb, offset);
11774         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11775         COUNT_BYTES_SUBR(4);
11776
11777         /* ea size */
11778         CHECK_BYTE_COUNT_SUBR(4);
11779         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11780         COUNT_BYTES_SUBR(4);
11781
11782         /* short file name len */
11783         CHECK_BYTE_COUNT_SUBR(1);
11784         sfn_len = tvb_get_guint8(tvb, offset);
11785         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11786         COUNT_BYTES_SUBR(1);
11787
11788         /* reserved byte */
11789         CHECK_BYTE_COUNT_SUBR(1);
11790         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11791         COUNT_BYTES_SUBR(1);
11792  
11793         /* short file name */
11794         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
11795         CHECK_STRING_SUBR(sfn);
11796         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11797                 sfn);
11798         COUNT_BYTES_SUBR(24);
11799
11800         /* file name */
11801         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11802         CHECK_STRING_SUBR(fn);
11803         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11804                 fn);
11805         COUNT_BYTES_SUBR(fn_len);
11806
11807         if (check_col(pinfo->cinfo, COL_INFO)) {
11808                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11809                 fn);
11810         }
11811
11812         /* skip to next structure */
11813         if(neo){
11814                 padcnt = (old_offset + neo) - offset;
11815                 if (padcnt < 0) {
11816                         /*
11817                          * XXX - this is bogus; flag it?
11818                          */
11819                         padcnt = 0;
11820                 }
11821                 if (padcnt != 0) {
11822                         CHECK_BYTE_COUNT_SUBR(padcnt);
11823                         COUNT_BYTES_SUBR(padcnt);
11824                 }
11825         }
11826
11827         proto_item_append_text(item, " File: %s", fn);
11828         proto_item_set_len(item, offset-old_offset);
11829
11830         *trunc = FALSE;
11831         return offset;
11832 }
11833
11834 static int
11835 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11836     int offset, guint16 *bcp, gboolean *trunc)
11837 {
11838         int fn_len;
11839         const char *fn;
11840         int old_offset = offset;
11841         proto_item *item = NULL;
11842         proto_tree *tree = NULL;
11843         smb_info_t *si;
11844         guint32 neo;
11845         int padcnt;
11846
11847         si = (smb_info_t *)pinfo->private_data;
11848
11849         if(parent_tree){
11850                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11851                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11852                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11853         }
11854
11855         /*
11856          * We assume that the presence of a next entry offset implies the
11857          * absence of a resume key, as appears to be the case for 4.3.4.6.
11858          */
11859
11860         /* next entry offset */
11861         CHECK_BYTE_COUNT_SUBR(4);
11862         neo = tvb_get_letohl(tvb, offset);
11863         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11864         COUNT_BYTES_SUBR(4);
11865         
11866         /* file index */
11867         CHECK_BYTE_COUNT_SUBR(4);
11868         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11869         COUNT_BYTES_SUBR(4);
11870
11871         /* file name len */
11872         CHECK_BYTE_COUNT_SUBR(4);
11873         fn_len = tvb_get_letohl(tvb, offset);
11874         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11875         COUNT_BYTES_SUBR(4);
11876
11877         /* file name */
11878         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11879         CHECK_STRING_SUBR(fn);
11880         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11881                 fn);
11882         COUNT_BYTES_SUBR(fn_len);
11883
11884         if (check_col(pinfo->cinfo, COL_INFO)) {
11885                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11886                 fn);
11887         }
11888
11889         /* skip to next structure */
11890         if(neo){
11891                 padcnt = (old_offset + neo) - offset;
11892                 if (padcnt < 0) {
11893                         /*
11894                          * XXX - this is bogus; flag it?
11895                          */
11896                         padcnt = 0;
11897                 }
11898                 if (padcnt != 0) {
11899                         CHECK_BYTE_COUNT_SUBR(padcnt);
11900                         COUNT_BYTES_SUBR(padcnt);
11901                 }
11902         }
11903
11904         proto_item_append_text(item, " File: %s", fn);
11905         proto_item_set_len(item, offset-old_offset);
11906
11907         *trunc = FALSE;
11908         return offset;
11909 }
11910  
11911 static int
11912 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11913     int offset, guint16 *bcp, gboolean *trunc)
11914 {
11915 /*XXX im lazy. i havnt implemented this */
11916         offset += *bcp;
11917         *bcp = 0;
11918         *trunc = FALSE;
11919         return offset;
11920 }
11921
11922 /*dissect the data block for TRANS2_FIND_FIRST2*/
11923 static int
11924 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
11925     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
11926 {
11927         smb_info_t *si;
11928
11929         if(!*bcp){
11930                 return offset;
11931         }
11932         
11933         si = (smb_info_t *)pinfo->private_data;
11934         switch(si->info_level){
11935         case 1:         /*Info Standard*/
11936                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
11937                     trunc);
11938                 break;
11939         case 2:         /*Info Query EA Size*/
11940                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11941                     trunc);
11942                 break;
11943         case 3:         /*Info Query EAs From List same as 
11944                                 InfoQueryEASize*/
11945                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11946                     trunc);
11947                 break;
11948         case 0x0101:    /*Find File Directory Info*/
11949                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
11950                     trunc);
11951                 break;
11952         case 0x0102:    /*Find File Full Directory Info*/
11953                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
11954                     trunc);
11955                 break;
11956         case 0x0103:    /*Find File Names Info*/
11957                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
11958                     trunc);
11959                 break;
11960         case 0x0104:    /*Find File Both Directory Info*/
11961                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
11962                     trunc);
11963                 break;
11964         case 0x0202:    /*Find File UNIX*/
11965                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
11966                     trunc);
11967                 break;
11968         default:        /* unknown info level */
11969                 *trunc = FALSE;
11970                 break;
11971         }
11972         return offset;
11973 }
11974
11975
11976 static int
11977 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11978 {
11979         guint32 mask;
11980         proto_item *item = NULL;
11981         proto_tree *tree = NULL;
11982
11983         mask = tvb_get_letohl(tvb, offset);
11984
11985         if(parent_tree){
11986                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11987                         "FS Attributes: 0x%08x", mask);
11988                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
11989         }
11990
11991         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
11992                 tvb, offset, 4, mask);
11993         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
11994                 tvb, offset, 4, mask);
11995         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
11996                 tvb, offset, 4, mask);
11997         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
11998                 tvb, offset, 4, mask);
11999         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12000                 tvb, offset, 4, mask);
12001         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12002                 tvb, offset, 4, mask);
12003         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12004                 tvb, offset, 4, mask);
12005
12006         offset += 4;
12007         return offset;
12008 }
12009  
12010
12011 static int
12012 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12013 {
12014         guint32 mask;
12015         proto_item *item = NULL;
12016         proto_tree *tree = NULL;
12017
12018         mask = tvb_get_letohl(tvb, offset);
12019
12020         if(parent_tree){
12021                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12022                         "Device Characteristics: 0x%08x", mask);
12023                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12024         }
12025
12026         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12027                 tvb, offset, 4, mask);
12028         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12029                 tvb, offset, 4, mask);
12030         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12031                 tvb, offset, 4, mask);
12032         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12033                 tvb, offset, 4, mask);
12034         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12035                 tvb, offset, 4, mask);
12036         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12037                 tvb, offset, 4, mask);
12038         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12039                 tvb, offset, 4, mask);
12040
12041         offset += 4;
12042         return offset;
12043 }
12044
12045 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12046 static int
12047 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12048     int offset, guint16 *bcp)
12049 {
12050         smb_info_t *si;
12051         int fn_len, vll, fnl;
12052         const char *fn;
12053
12054         if(!*bcp){
12055                 return offset;
12056         }
12057         
12058         si = (smb_info_t *)pinfo->private_data;
12059         switch(si->info_level){
12060         case 1:         /* SMB_INFO_ALLOCATION */
12061                 /* filesystem id */
12062                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12063                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12064                 COUNT_BYTES_TRANS_SUBR(4);
12065
12066                 /* sectors per unit */
12067                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12068                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12069                 COUNT_BYTES_TRANS_SUBR(4);
12070
12071                 /* units */
12072                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12073                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12074                 COUNT_BYTES_TRANS_SUBR(4);
12075
12076                 /* avail units */
12077                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12078                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12079                 COUNT_BYTES_TRANS_SUBR(4);
12080
12081                 /* bytes per sector, only 16bit integer here */
12082                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12083                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12084                 COUNT_BYTES_TRANS_SUBR(2);
12085
12086                 break;
12087         case 2:         /* SMB_INFO_VOLUME */
12088                 /* volume serial number */
12089                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12090                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12091                 COUNT_BYTES_TRANS_SUBR(4);
12092
12093                 /* volume label length, only one byte here */
12094                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12095                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12096                 COUNT_BYTES_TRANS_SUBR(1);
12097
12098                 /* label */
12099                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
12100                 CHECK_STRING_TRANS_SUBR(fn);
12101                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12102                         fn);
12103                 COUNT_BYTES_TRANS_SUBR(fn_len);
12104
12105                 break;
12106         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12107         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12108                 /* volume label length */
12109                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12110                 vll = tvb_get_letohl(tvb, offset);
12111                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12112                 COUNT_BYTES_TRANS_SUBR(4);
12113
12114                 /* label */
12115                 fn_len = vll;
12116                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12117                 CHECK_STRING_TRANS_SUBR(fn);
12118                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12119                         fn);
12120                 COUNT_BYTES_TRANS_SUBR(fn_len);
12121
12122                 break;
12123         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12124         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12125                 /* create time */
12126                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12127                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12128                         hf_smb_create_time);
12129                 *bcp -= 8;
12130         
12131                 /* volume serial number */
12132                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12133                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12134                 COUNT_BYTES_TRANS_SUBR(4);
12135
12136                 /* volume label length */
12137                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12138                 vll = tvb_get_letohl(tvb, offset);
12139                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12140                 COUNT_BYTES_TRANS_SUBR(4);
12141
12142                 /* 2 reserved bytes */
12143                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12144                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12145                 COUNT_BYTES_TRANS_SUBR(2);
12146
12147                 /* label */
12148                 fn_len = vll;
12149                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12150                 CHECK_STRING_TRANS_SUBR(fn);
12151                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12152                         fn);
12153                 COUNT_BYTES_TRANS_SUBR(fn_len);
12154
12155                 break;
12156         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12157         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12158                 /* allocation size */
12159                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12160                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12161                 COUNT_BYTES_TRANS_SUBR(8);
12162
12163                 /* free allocation units */
12164                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12165                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12166                 COUNT_BYTES_TRANS_SUBR(8);
12167
12168                 /* sectors per unit */
12169                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12170                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12171                 COUNT_BYTES_TRANS_SUBR(4);
12172
12173                 /* bytes per sector */
12174                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12175                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12176                 COUNT_BYTES_TRANS_SUBR(4);
12177
12178                 break;
12179         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12180         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12181                 /* device type */
12182                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12183                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12184                 COUNT_BYTES_TRANS_SUBR(4);
12185  
12186                 /* device characteristics */
12187                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12188                 offset = dissect_device_characteristics(tvb, tree, offset);
12189                 *bcp -= 4;
12190         
12191                 break;
12192         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12193         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12194                 /* FS attributes */
12195                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12196                 offset = dissect_fs_attributes(tvb, tree, offset);
12197                 *bcp -= 4;
12198         
12199                 /* max name len */
12200                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12201                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12202                 COUNT_BYTES_TRANS_SUBR(4);
12203
12204                 /* fs name length */
12205                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12206                 fnl = tvb_get_letohl(tvb, offset);
12207                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12208                 COUNT_BYTES_TRANS_SUBR(4);
12209
12210                 /* label */
12211                 fn_len = fnl;
12212                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12213                 CHECK_STRING_TRANS_SUBR(fn);
12214                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12215                         fn);
12216                 COUNT_BYTES_TRANS_SUBR(fn_len);
12217
12218                 break;
12219         case 1006:      /* QUERY_FS_QUOTA_INFO */
12220                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12221                 break;
12222         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12223                 /* allocation size */
12224                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12225                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12226                 COUNT_BYTES_TRANS_SUBR(8);
12227
12228                 /* caller free allocation units */
12229                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12230                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12231                 COUNT_BYTES_TRANS_SUBR(8);
12232
12233                 /* actual free allocation units */
12234                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12235                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12236                 COUNT_BYTES_TRANS_SUBR(8);
12237
12238                 /* sectors per unit */
12239                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12240                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12241                 COUNT_BYTES_TRANS_SUBR(4);
12242
12243                 /* bytes per sector */
12244                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12245                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12246                 COUNT_BYTES_TRANS_SUBR(4);
12247                 break;
12248         }
12249  
12250         return offset;
12251 }
12252  
12253 static int
12254 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12255     proto_tree *parent_tree)
12256 {
12257         proto_item *item = NULL;
12258         proto_tree *tree = NULL;
12259         smb_info_t *si;
12260         smb_transact2_info_t *t2i;
12261         int count;
12262         gboolean trunc;
12263         int offset = 0;
12264         guint16 dc;
12265
12266         dc = tvb_reported_length(tvb);
12267
12268         si = (smb_info_t *)pinfo->private_data;
12269         if (si->sip != NULL)
12270                 t2i = si->sip->extra_info;
12271         else
12272                 t2i = NULL;
12273
12274         if(parent_tree){
12275                 if (t2i != NULL && t2i->subcmd != -1) {
12276                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12277                                 "%s Data",
12278                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
12279                                         "Unknown (0x%02x)"));
12280                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12281                 } else {
12282                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12283                                 "Unknown Transaction2 Data");
12284                 }
12285         }
12286
12287         if (t2i == NULL) {
12288                 offset += dc;
12289                 return offset;
12290         }
12291         switch(t2i->subcmd){
12292         case 0x00:      /*TRANS2_OPEN2*/
12293                 /* XXX not implemented yet. See SNIA doc */
12294                 break;
12295         case 0x01:      /*TRANS2_FIND_FIRST2*/
12296                 /* returned data */
12297                 count = si->info_count;
12298
12299                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12300                         col_append_fstr(pinfo->cinfo, COL_INFO,
12301                         ", Files:");
12302                 }
12303
12304                 while(count--){
12305                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12306                                 offset, &dc, &trunc);
12307                         if (trunc)
12308                                 break;
12309                 }
12310                 break;
12311         case 0x02:      /*TRANS2_FIND_NEXT2*/
12312                 /* returned data */
12313                 count = si->info_count;
12314
12315                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12316                         col_append_fstr(pinfo->cinfo, COL_INFO,
12317                         ", Files:");
12318                 }
12319
12320                 while(count--){
12321                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12322                                 offset, &dc, &trunc);
12323                         if (trunc)
12324                                 break;
12325                 }
12326                 break;
12327         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12328                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12329                 break;
12330         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12331                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12332                 break;
12333         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12334                 /* no data in this response */
12335                 break;
12336         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12337                 /* identical to QUERY_PATH_INFO */
12338                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12339                 break;
12340         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12341                 /* no data in this response */
12342                 break;
12343         case 0x09:      /*TRANS2_FSCTL*/
12344                 /* XXX dont know how to dissect this one (yet)*/
12345
12346                 /*
12347                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12348                  * Extensions Version 3.0, Document Version 1.11,
12349                  * July 19, 1990" says this this contains a
12350                  * "File system specific return data block".
12351                  * (That means we may not be able to dissect it in any
12352                  * case.)
12353                  */
12354                 break;
12355         case 0x0a:      /*TRANS2_IOCTL2*/
12356                 /* XXX dont know how to dissect this one (yet)*/
12357
12358                 /*
12359                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12360                  * Extensions Version 3.0, Document Version 1.11,
12361                  * July 19, 1990" says this this contains a
12362                  * "Device/function specific return data block".
12363                  * (That means we may not be able to dissect it in any
12364                  * case.)
12365                  */
12366                 break;
12367         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12368                 /* XXX dont know how to dissect this one (yet)*/
12369
12370                 /*
12371                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12372                  * Extensions Version 3.0, Document Version 1.11,
12373                  * July 19, 1990" says this this contains "the level
12374                  * dependent information about the changes which
12375                  * occurred".
12376                  */
12377                 break;
12378         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12379                 /* XXX dont know how to dissect this one (yet)*/
12380
12381                 /*
12382                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12383                  * Extensions Version 3.0, Document Version 1.11,
12384                  * July 19, 1990" says this this contains "the level
12385                  * dependent information about the changes which
12386                  * occurred".
12387                  */
12388                 break;
12389         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12390                 /* no data in this response */
12391                 break;
12392         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12393                 /* XXX dont know how to dissect this one (yet)*/
12394                 break;
12395         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12396                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12397                 break;
12398         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12399                 /* the SNIA spec appears to say the response has no data */
12400                 break;
12401         case -1:
12402                 /*
12403                  * We don't know what the matching request was; don't
12404                  * bother putting anything else into the tree for the data.
12405                  */
12406                 offset += dc;
12407                 dc = 0;
12408                 break;
12409         }
12410
12411         /* ooops there were data we didnt know how to process */
12412         if(dc != 0){
12413                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12414                 offset += dc;
12415         }
12416
12417         return offset;
12418 }
12419
12420
12421 static void
12422 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12423 {
12424         proto_item *item = NULL;
12425         proto_tree *tree = NULL;
12426         smb_info_t *si;
12427         smb_transact2_info_t *t2i;
12428         guint16 fid;
12429         int lno;
12430         int offset = 0;
12431         int pc;
12432
12433         pc = tvb_reported_length(tvb);
12434
12435         si = (smb_info_t *)pinfo->private_data;
12436         if (si->sip != NULL)
12437                 t2i = si->sip->extra_info;
12438         else
12439                 t2i = NULL;
12440
12441         if(parent_tree){
12442                 if (t2i != NULL && t2i->subcmd != -1) {
12443                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12444                                 "%s Parameters",
12445                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
12446                                                 "Unknown (0x%02x)"));
12447                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
12448                 } else {
12449                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12450                                 "Unknown Transaction2 Parameters");
12451                 }
12452         }
12453
12454         if (t2i == NULL) {
12455                 offset += pc;
12456                 return;
12457         }
12458         switch(t2i->subcmd){
12459         case 0x00:      /*TRANS2_OPEN2*/
12460                 /* fid */
12461                 fid = tvb_get_letohs(tvb, offset);
12462                 add_fid(tvb, pinfo, tree, offset, 2, fid);
12463                 offset += 2;
12464
12465                 /*
12466                  * XXX - Microsoft Networks SMB File Sharing Protocol
12467                  * Extensions Version 3.0, Document Version 1.11,
12468                  * July 19, 1990 says that the file attributes, create
12469                  * time (which it says is the last modification time),
12470                  * data size, granted access, file type, and IPC state
12471                  * are returned only if bit 0 is set in the open flags,
12472                  * and that the EA length is returned only if bit 3
12473                  * is set in the open flags.  Does that mean that,
12474                  * at least in that SMB dialect, those fields are not
12475                  * present in the reply parameters if the bits in
12476                  * question aren't set?
12477                  */
12478
12479                 /* File Attributes */
12480                 offset = dissect_file_attributes(tvb, tree, offset);
12481
12482                 /* create time */
12483                 offset = dissect_smb_datetime(tvb, tree, offset,
12484                         hf_smb_create_time, 
12485                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
12486
12487                 /* data size */
12488                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12489                 offset += 4;
12490
12491                 /* granted access */
12492                 offset = dissect_access(tvb, tree, offset, "Granted");
12493
12494                 /* File Type */
12495                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
12496                 offset += 2;
12497
12498                 /* IPC State */
12499                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
12500
12501                 /* open_action */
12502                 offset = dissect_open_action(tvb, tree, offset);
12503
12504                 /* server unique file ID */
12505                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
12506                 offset += 4;
12507
12508                 /* ea error offset, only a 16 bit integer here */
12509                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12510                 offset += 2;
12511
12512                 /* ea length */
12513                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
12514                 offset += 4;
12515
12516                 break;
12517         case 0x01:      /*TRANS2_FIND_FIRST2*/
12518                 /* Find First2 information level */
12519                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
12520
12521                 /* sid */
12522                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
12523                 offset += 2;
12524
12525                 /* search count */
12526                 si->info_count = tvb_get_letohs(tvb, offset);
12527                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12528                 offset += 2;
12529
12530                 /* end of search */
12531                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12532                 offset += 2;
12533
12534                 /* ea error offset, only a 16 bit integer here */
12535                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12536                 offset += 2;
12537
12538                 /* last name offset */
12539                 lno = tvb_get_letohs(tvb, offset);
12540                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12541                 offset += 2;
12542
12543                 break;
12544         case 0x02:      /*TRANS2_FIND_NEXT2*/
12545                 /* search count */
12546                 si->info_count = tvb_get_letohs(tvb, offset);
12547                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12548                 offset += 2;
12549
12550                 /* end of search */
12551                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12552                 offset += 2;
12553
12554                 /* ea_error_offset, only a 16 bit integer here*/
12555                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12556                 offset += 2;
12557
12558                 /* last name offset */
12559                 lno = tvb_get_letohs(tvb, offset);
12560                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12561                 offset += 2;
12562
12563                 break;
12564         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12565                 /* no parameter block here */
12566                 break;
12567         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12568                 /* ea_error_offset, only a 16 bit integer here*/
12569                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12570                 offset += 2;
12571
12572                 break;
12573         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12574                 /* ea_error_offset, only a 16 bit integer here*/
12575                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12576                 offset += 2;
12577
12578                 break;
12579         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12580                 /* ea_error_offset, only a 16 bit integer here*/
12581                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12582                 offset += 2;
12583
12584                 break;
12585         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12586                 /* ea_error_offset, only a 16 bit integer here*/
12587                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12588                 offset += 2;
12589
12590                 break;
12591         case 0x09:      /*TRANS2_FSCTL*/
12592                 /* XXX dont know how to dissect this one (yet)*/
12593
12594                 /*
12595                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12596                  * Extensions Version 3.0, Document Version 1.11,
12597                  * July 19, 1990" says this this contains a
12598                  * "File system specific return parameter block".
12599                  * (That means we may not be able to dissect it in any
12600                  * case.)
12601                  */
12602                 break;
12603         case 0x0a:      /*TRANS2_IOCTL2*/
12604                 /* XXX dont know how to dissect this one (yet)*/
12605
12606                 /*
12607                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12608                  * Extensions Version 3.0, Document Version 1.11,
12609                  * July 19, 1990" says this this contains a
12610                  * "Device/function specific return parameter block".
12611                  * (That means we may not be able to dissect it in any
12612                  * case.)
12613                  */
12614                 break;
12615         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12616                 /* Find Notify information level */
12617                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12618
12619                 /* Monitor handle */
12620                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
12621                 offset += 2;
12622
12623                 /* Change count */
12624                 si->info_count = tvb_get_letohs(tvb, offset);
12625                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12626                 offset += 2;
12627
12628                 /* ea_error_offset, only a 16 bit integer here*/
12629                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12630                 offset += 2;
12631
12632                 break;
12633         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12634                 /* Find Notify information level */
12635                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12636
12637                 /* Change count */
12638                 si->info_count = tvb_get_letohs(tvb, offset);
12639                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12640                 offset += 2;
12641
12642                 /* ea_error_offset, only a 16 bit integer here*/
12643                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12644                 offset += 2;
12645
12646                 break;
12647         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12648                 /* ea error offset, only a 16 bit integer here */
12649                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12650                 offset += 2;
12651
12652                 break;
12653         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12654                 /* XXX dont know how to dissect this one (yet)*/
12655                 break;
12656         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12657                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12658                 break;
12659         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12660                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12661                 break;
12662         case -1:
12663                 /*
12664                  * We don't know what the matching request was; don't
12665                  * bother putting anything else into the tree for the data.
12666                  */
12667                 offset += pc;
12668                 break;
12669         }
12670
12671         /* ooops there were data we didnt know how to process */
12672         if(offset<pc){
12673                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
12674                 offset += pc-offset;
12675         }
12676 }
12677
12678
12679 static int
12680 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12681 {
12682         guint8 sc, wc;
12683         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
12684         smb_info_t *si;
12685         smb_transact2_info_t *t2i = NULL;
12686         guint16 bc;
12687         int padcnt;
12688         gboolean dissected_trans;
12689         fragment_data *r_fd = NULL;
12690         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
12691         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
12692         gboolean save_fragmented;
12693
12694         si = (smb_info_t *)pinfo->private_data;
12695
12696         switch(si->cmd){
12697         case SMB_COM_TRANSACTION2:
12698                 /* transaction2 */
12699                 if (si->sip != NULL) {
12700                         t2i = si->sip->extra_info;
12701                 } else
12702                         t2i = NULL;
12703                 if (t2i == NULL) {
12704                         /*
12705                          * We didn't see the matching request, so we don't
12706                          * know what type of transaction this is.
12707                          */
12708                         proto_tree_add_text(tree, tvb, 0, 0,
12709                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
12710                         if (check_col(pinfo->cinfo, COL_INFO)) {
12711                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12712                         }
12713                 } else {
12714                         si->info_level = t2i->info_level;
12715                         if (t2i->subcmd == -1) {
12716                                 /*
12717                                  * We didn't manage to extract the subcommand
12718                                  * from the matching request (perhaps because
12719                                  * the frame was short), so we don't know what
12720                                  * type of transaction this is.
12721                                  */
12722                                 proto_tree_add_text(tree, tvb, 0, 0,
12723                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
12724                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12725                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12726                                 }
12727                         } else {
12728                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
12729                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12730                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12731                                                 val_to_str(t2i->subcmd,
12732                                                         trans2_cmd_vals, 
12733                                                         "<unknown (0x%02x)>"));
12734                                 }
12735                         }
12736                 }
12737                 break;
12738         }
12739
12740         WORD_COUNT;
12741
12742         /* total param count, only a 16bit integer here */
12743         tp = tvb_get_letohs(tvb, offset);
12744         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
12745         offset += 2;
12746
12747         /* total data count, only a 16 bit integer here */
12748         td = tvb_get_letohs(tvb, offset);
12749         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
12750         offset += 2;
12751
12752         /* 2 reserved bytes */
12753         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12754         offset += 2;
12755
12756         /* param count */
12757         pc = tvb_get_letohs(tvb, offset);
12758         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12759         offset += 2;
12760
12761         /* param offset */
12762         po = tvb_get_letohs(tvb, offset);
12763         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12764         offset += 2;
12765
12766         /* param disp */
12767         pd = tvb_get_letohs(tvb, offset);
12768         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12769         offset += 2;
12770
12771         /* data count */
12772         dc = tvb_get_letohs(tvb, offset);
12773         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12774         offset += 2;
12775
12776         /* data offset */
12777         od = tvb_get_letohs(tvb, offset);
12778         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12779         offset += 2;
12780
12781         /* data disp */
12782         dd = tvb_get_letohs(tvb, offset);
12783         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12784         offset += 2;
12785
12786         /* setup count */
12787         sc = tvb_get_guint8(tvb, offset);
12788         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12789         offset += 1;
12790
12791         /* reserved byte */
12792         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12793         offset += 1;
12794
12795
12796         /* if there were any setup bytes, put them in a tvb for later */
12797         if(sc){
12798                 if((2*sc)>tvb_length_remaining(tvb, offset)){
12799                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
12800                 } else {
12801                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
12802                 }
12803                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
12804         } else {
12805                 s_tvb = NULL;
12806                 sp_tvb=NULL;
12807         }
12808         offset += 2*sc;
12809
12810
12811         BYTE_COUNT;
12812
12813
12814         /* reassembly of SMB Transaction data payload.
12815            In this section we do reassembly of both the data and parameters
12816            blocks of the SMB transaction command.
12817         */
12818         save_fragmented = pinfo->fragmented;
12819         /* do we need reassembly? */
12820         if( (td!=dc) || (tp!=pc) ){
12821                 /* oh yeah, either data or parameter section needs 
12822                    reassembly
12823                 */
12824                 pinfo->fragmented = TRUE;
12825                 if(smb_trans_reassembly){
12826                         /* ...and we were told to do reassembly */
12827                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
12828                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12829                                                              po, pc, pd, td+tp);
12830                                 
12831                         }
12832                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
12833                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12834                                                              od, dc, dd+tp, td+tp);
12835                         }
12836                 }
12837         }
12838
12839         /* if we got a reassembled fd structure from the reassembly routine we must
12840            create pd_tvb from it 
12841         */
12842         if(r_fd){
12843                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
12844                                              r_fd->datalen);
12845                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
12846                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
12847                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
12848         }
12849
12850
12851         if(pd_tvb){
12852                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
12853                 if(tp){
12854                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
12855                 }
12856                 if(td){
12857                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
12858                 }
12859         } else {
12860                 /* It was not reassembled. Do as best as we can.
12861                  * in this case we always try to dissect the stuff if 
12862                  * data and param displacement is 0. i.e. for the first
12863                  * (and maybe only) packet.
12864                  */
12865                 if( (pd==0) && (dd==0) ){
12866                         int min;
12867                         int reported_min;
12868                         min = MIN(pc,tvb_length_remaining(tvb,po));
12869                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
12870                         if(min && reported_min) {
12871                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
12872                         }
12873                         min = MIN(dc,tvb_length_remaining(tvb,od));
12874                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
12875                         if(min && reported_min) {
12876                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
12877                         }
12878                         /*
12879                          * A tvbuff containing the parameters
12880                          * and the data.
12881                          * XXX - check pc and dc as well?
12882                          */
12883                         if (tvb_length_remaining(tvb, po)){
12884                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12885                         }
12886                 }
12887         }
12888
12889
12890
12891         /* parameters */
12892         if(po>offset){
12893                 /* We have some padding bytes.
12894                 */
12895                 padcnt = po-offset;
12896                 if (padcnt > bc)
12897                         padcnt = bc;
12898                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12899                 COUNT_BYTES(padcnt);
12900         }
12901         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
12902                 /* TRANSACTION2 parameters*/
12903                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
12904         }
12905         COUNT_BYTES(pc);
12906
12907
12908         /* data */
12909         if(od>offset){
12910                 /* We have some initial padding bytes.
12911                 */
12912                 padcnt = od-offset;
12913                 if (padcnt > bc)
12914                         padcnt = bc;
12915                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12916                 COUNT_BYTES(padcnt);
12917         }
12918         /*
12919          * If the data count is bigger than the count of bytes
12920          * remaining, clamp it so that the count of bytes remaining
12921          * doesn't go negative.
12922          */
12923         if (dc > bc)
12924                 dc = bc;
12925         COUNT_BYTES(dc);
12926
12927
12928
12929         /* from now on, everything is in separate tvbuffs so we dont count
12930            the bytes with COUNT_BYTES any more.
12931            neither do we reference offset any more (which by now points to the
12932            first byte AFTER this PDU */
12933
12934
12935         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
12936                 /* TRANSACTION2 parameters*/
12937                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
12938         }
12939
12940
12941         if(si->cmd==SMB_COM_TRANSACTION){
12942                 smb_transact_info_t *tri;
12943
12944                 dissected_trans = FALSE;
12945                 if (si->sip != NULL)
12946                         tri = si->sip->extra_info;
12947                 else
12948                         tri = NULL;
12949                 if (tri != NULL) {
12950                         switch(tri->subcmd){
12951
12952                         case TRANSACTION_PIPE:
12953                                 /* This function is safe to call for 
12954                                    s_tvb==sp_tvb==NULL, i.e. if we don't
12955                                    know them at this point.
12956                                    It's also safe to call if "p_tvb"
12957                                    or "d_tvb" are null.
12958                                 */
12959                                 if( pd_tvb) {
12960                                         dissected_trans = dissect_pipe_smb(
12961                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
12962                                                 d_tvb, NULL, pinfo, top_tree);
12963                                 }
12964                                 break;
12965                                 
12966                         case TRANSACTION_MAILSLOT:
12967                                 /* This one should be safe to call
12968                                    even if s_tvb and sp_tvb is NULL
12969                                 */
12970                                 if(d_tvb){
12971                                         dissected_trans = dissect_mailslot_smb(
12972                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
12973                                                 top_tree);
12974                                 }
12975                                 break;
12976                         }
12977                 }
12978                 if (!dissected_trans) {
12979                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
12980                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12981                 }
12982         }
12983
12984
12985         if( (p_tvb==0) && (d_tvb==0) ){
12986                 if(check_col(pinfo->cinfo, COL_INFO)){
12987                         col_append_str(pinfo->cinfo, COL_INFO,
12988                                        "[transact continuation]");
12989                 }
12990         }
12991
12992         pinfo->fragmented = save_fragmented;
12993         END_OF_SMB
12994
12995         return offset;
12996 }
12997
12998
12999 static int
13000 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13001 {
13002         guint8 wc;
13003         guint16 bc;
13004
13005         WORD_COUNT;
13006
13007         /* Monitor handle */
13008         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13009         offset += 2;
13010
13011         BYTE_COUNT;
13012
13013         END_OF_SMB
13014
13015         return offset;
13016 }
13017
13018 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13019    END Transaction/Transaction2 Primary and secondary requests
13020    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13021
13022
13023 static int
13024 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13025 {
13026         guint8 wc;
13027         guint16 bc;
13028
13029         WORD_COUNT;
13030  
13031         if (wc != 0) {
13032                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13033                 offset += wc*2;
13034         }
13035
13036         BYTE_COUNT;
13037
13038         if (bc != 0) {
13039                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13040                 offset += bc;
13041                 bc = 0;
13042         }
13043
13044         END_OF_SMB
13045
13046         return offset;
13047 }
13048
13049 typedef struct _smb_function {
13050        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13051        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13052 } smb_function;
13053
13054 static smb_function smb_dissector[256] = {
13055   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13056   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13057   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13058   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13059   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13060   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13061   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13062   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13063   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13064   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13065   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13066   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13067   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13068   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13069   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13070   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13071
13072   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13073   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13074   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13075   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13076   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13077   /* 0x15 */  {dissect_unknown, dissect_unknown},
13078   /* 0x16 */  {dissect_unknown, dissect_unknown},
13079   /* 0x17 */  {dissect_unknown, dissect_unknown},
13080   /* 0x18 */  {dissect_unknown, dissect_unknown},
13081   /* 0x19 */  {dissect_unknown, dissect_unknown},
13082   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13083   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13084   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13085   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13086   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13087   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13088
13089   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13090   /* 0x21 */  {dissect_unknown, dissect_unknown},
13091   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13092   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13093   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13094   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13095   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13096   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13097   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13098   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13099   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13100   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13101   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13102   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13103   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13104   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13105
13106   /* 0x30 */  {dissect_unknown, dissect_unknown},
13107   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13108   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13109   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13110   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13111   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13112   /* 0x36 */  {dissect_unknown, dissect_unknown},
13113   /* 0x37 */  {dissect_unknown, dissect_unknown},
13114   /* 0x38 */  {dissect_unknown, dissect_unknown},
13115   /* 0x39 */  {dissect_unknown, dissect_unknown},
13116   /* 0x3a */  {dissect_unknown, dissect_unknown},
13117   /* 0x3b */  {dissect_unknown, dissect_unknown},
13118   /* 0x3c */  {dissect_unknown, dissect_unknown},
13119   /* 0x3d */  {dissect_unknown, dissect_unknown},
13120   /* 0x3e */  {dissect_unknown, dissect_unknown},
13121   /* 0x3f */  {dissect_unknown, dissect_unknown},
13122
13123   /* 0x40 */  {dissect_unknown, dissect_unknown},
13124   /* 0x41 */  {dissect_unknown, dissect_unknown},
13125   /* 0x42 */  {dissect_unknown, dissect_unknown},
13126   /* 0x43 */  {dissect_unknown, dissect_unknown},
13127   /* 0x44 */  {dissect_unknown, dissect_unknown},
13128   /* 0x45 */  {dissect_unknown, dissect_unknown},
13129   /* 0x46 */  {dissect_unknown, dissect_unknown},
13130   /* 0x47 */  {dissect_unknown, dissect_unknown},
13131   /* 0x48 */  {dissect_unknown, dissect_unknown},
13132   /* 0x49 */  {dissect_unknown, dissect_unknown},
13133   /* 0x4a */  {dissect_unknown, dissect_unknown},
13134   /* 0x4b */  {dissect_unknown, dissect_unknown},
13135   /* 0x4c */  {dissect_unknown, dissect_unknown},
13136   /* 0x4d */  {dissect_unknown, dissect_unknown},
13137   /* 0x4e */  {dissect_unknown, dissect_unknown},
13138   /* 0x4f */  {dissect_unknown, dissect_unknown},
13139
13140   /* 0x50 */  {dissect_unknown, dissect_unknown},
13141   /* 0x51 */  {dissect_unknown, dissect_unknown},
13142   /* 0x52 */  {dissect_unknown, dissect_unknown},
13143   /* 0x53 */  {dissect_unknown, dissect_unknown},
13144   /* 0x54 */  {dissect_unknown, dissect_unknown},
13145   /* 0x55 */  {dissect_unknown, dissect_unknown},
13146   /* 0x56 */  {dissect_unknown, dissect_unknown},
13147   /* 0x57 */  {dissect_unknown, dissect_unknown},
13148   /* 0x58 */  {dissect_unknown, dissect_unknown},
13149   /* 0x59 */  {dissect_unknown, dissect_unknown},
13150   /* 0x5a */  {dissect_unknown, dissect_unknown},
13151   /* 0x5b */  {dissect_unknown, dissect_unknown},
13152   /* 0x5c */  {dissect_unknown, dissect_unknown},
13153   /* 0x5d */  {dissect_unknown, dissect_unknown},
13154   /* 0x5e */  {dissect_unknown, dissect_unknown},
13155   /* 0x5f */  {dissect_unknown, dissect_unknown},
13156
13157   /* 0x60 */  {dissect_unknown, dissect_unknown},
13158   /* 0x61 */  {dissect_unknown, dissect_unknown},
13159   /* 0x62 */  {dissect_unknown, dissect_unknown},
13160   /* 0x63 */  {dissect_unknown, dissect_unknown},
13161   /* 0x64 */  {dissect_unknown, dissect_unknown},
13162   /* 0x65 */  {dissect_unknown, dissect_unknown},
13163   /* 0x66 */  {dissect_unknown, dissect_unknown},
13164   /* 0x67 */  {dissect_unknown, dissect_unknown},
13165   /* 0x68 */  {dissect_unknown, dissect_unknown},
13166   /* 0x69 */  {dissect_unknown, dissect_unknown},
13167   /* 0x6a */  {dissect_unknown, dissect_unknown},
13168   /* 0x6b */  {dissect_unknown, dissect_unknown},
13169   /* 0x6c */  {dissect_unknown, dissect_unknown},
13170   /* 0x6d */  {dissect_unknown, dissect_unknown},
13171   /* 0x6e */  {dissect_unknown, dissect_unknown},
13172   /* 0x6f */  {dissect_unknown, dissect_unknown},
13173
13174   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13175   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13176   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13177   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13178   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13179   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13180   /* 0x76 */  {dissect_unknown, dissect_unknown},
13181   /* 0x77 */  {dissect_unknown, dissect_unknown},
13182   /* 0x78 */  {dissect_unknown, dissect_unknown},
13183   /* 0x79 */  {dissect_unknown, dissect_unknown},
13184   /* 0x7a */  {dissect_unknown, dissect_unknown},
13185   /* 0x7b */  {dissect_unknown, dissect_unknown},
13186   /* 0x7c */  {dissect_unknown, dissect_unknown},
13187   /* 0x7d */  {dissect_unknown, dissect_unknown},
13188   /* 0x7e */  {dissect_unknown, dissect_unknown},
13189   /* 0x7f */  {dissect_unknown, dissect_unknown},
13190
13191   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13192   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13193   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13194   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13195   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13196   /* 0x85 */  {dissect_unknown, dissect_unknown},
13197   /* 0x86 */  {dissect_unknown, dissect_unknown},
13198   /* 0x87 */  {dissect_unknown, dissect_unknown},
13199   /* 0x88 */  {dissect_unknown, dissect_unknown},
13200   /* 0x89 */  {dissect_unknown, dissect_unknown},
13201   /* 0x8a */  {dissect_unknown, dissect_unknown},
13202   /* 0x8b */  {dissect_unknown, dissect_unknown},
13203   /* 0x8c */  {dissect_unknown, dissect_unknown},
13204   /* 0x8d */  {dissect_unknown, dissect_unknown},
13205   /* 0x8e */  {dissect_unknown, dissect_unknown},
13206   /* 0x8f */  {dissect_unknown, dissect_unknown},
13207
13208   /* 0x90 */  {dissect_unknown, dissect_unknown},
13209   /* 0x91 */  {dissect_unknown, dissect_unknown},
13210   /* 0x92 */  {dissect_unknown, dissect_unknown},
13211   /* 0x93 */  {dissect_unknown, dissect_unknown},
13212   /* 0x94 */  {dissect_unknown, dissect_unknown},
13213   /* 0x95 */  {dissect_unknown, dissect_unknown},
13214   /* 0x96 */  {dissect_unknown, dissect_unknown},
13215   /* 0x97 */  {dissect_unknown, dissect_unknown},
13216   /* 0x98 */  {dissect_unknown, dissect_unknown},
13217   /* 0x99 */  {dissect_unknown, dissect_unknown},
13218   /* 0x9a */  {dissect_unknown, dissect_unknown},
13219   /* 0x9b */  {dissect_unknown, dissect_unknown},
13220   /* 0x9c */  {dissect_unknown, dissect_unknown},
13221   /* 0x9d */  {dissect_unknown, dissect_unknown},
13222   /* 0x9e */  {dissect_unknown, dissect_unknown},
13223   /* 0x9f */  {dissect_unknown, dissect_unknown},
13224
13225   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13226   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13227   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13228   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13229   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13230   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13231   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13232   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13233   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13234   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13235   /* 0xaa */  {dissect_unknown, dissect_unknown},
13236   /* 0xab */  {dissect_unknown, dissect_unknown},
13237   /* 0xac */  {dissect_unknown, dissect_unknown},
13238   /* 0xad */  {dissect_unknown, dissect_unknown},
13239   /* 0xae */  {dissect_unknown, dissect_unknown},
13240   /* 0xaf */  {dissect_unknown, dissect_unknown},
13241
13242   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13243   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13244   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13245   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13246   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13247   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13248   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13249   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13250   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13251   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13252   /* 0xba */  {dissect_unknown, dissect_unknown},
13253   /* 0xbb */  {dissect_unknown, dissect_unknown},
13254   /* 0xbc */  {dissect_unknown, dissect_unknown},
13255   /* 0xbd */  {dissect_unknown, dissect_unknown},
13256   /* 0xbe */  {dissect_unknown, dissect_unknown},
13257   /* 0xbf */  {dissect_unknown, dissect_unknown},
13258
13259   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13260   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13261   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13262   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13263   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13264   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13265   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13266   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13267   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13268   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13269   /* 0xca */  {dissect_unknown, dissect_unknown},
13270   /* 0xcb */  {dissect_unknown, dissect_unknown},
13271   /* 0xcc */  {dissect_unknown, dissect_unknown},
13272   /* 0xcd */  {dissect_unknown, dissect_unknown},
13273   /* 0xce */  {dissect_unknown, dissect_unknown},
13274   /* 0xcf */  {dissect_unknown, dissect_unknown},
13275
13276   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13277   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13278   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13279   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13280   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13281   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13282   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13283   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13284   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13285   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13286   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13287   /* 0xdb */  {dissect_unknown, dissect_unknown},
13288   /* 0xdc */  {dissect_unknown, dissect_unknown},
13289   /* 0xdd */  {dissect_unknown, dissect_unknown},
13290   /* 0xde */  {dissect_unknown, dissect_unknown},
13291   /* 0xdf */  {dissect_unknown, dissect_unknown},
13292
13293   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13294   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13295   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13296   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13297   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13298   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13299   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13300   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13301   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13302   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13303   /* 0xea */  {dissect_unknown, dissect_unknown},
13304   /* 0xeb */  {dissect_unknown, dissect_unknown},
13305   /* 0xec */  {dissect_unknown, dissect_unknown},
13306   /* 0xed */  {dissect_unknown, dissect_unknown},
13307   /* 0xee */  {dissect_unknown, dissect_unknown},
13308   /* 0xef */  {dissect_unknown, dissect_unknown},
13309
13310   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13311   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13312   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13313   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13314   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13315   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13316   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13317   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13318   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13319   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13320   /* 0xfa */  {dissect_unknown, dissect_unknown},
13321   /* 0xfb */  {dissect_unknown, dissect_unknown},
13322   /* 0xfc */  {dissect_unknown, dissect_unknown},
13323   /* 0xfd */  {dissect_unknown, dissect_unknown},
13324   /* 0xfe */  {dissect_unknown, dissect_unknown},
13325   /* 0xff */  {dissect_unknown, dissect_unknown},
13326 };
13327
13328 static int
13329 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd)
13330 {
13331         int old_offset = offset;
13332         smb_info_t *si;
13333  
13334         si = pinfo->private_data;
13335         if(cmd!=0xff){
13336                 proto_item *cmd_item;
13337                 proto_tree *cmd_tree;
13338                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13339
13340                 if (check_col(pinfo->cinfo, COL_INFO)) {
13341                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
13342                                 decode_smb_name(cmd),
13343                                 (si->request)? "Request" : "Response");
13344                 }
13345
13346                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13347                         "%s %s (0x%02x)",
13348                         decode_smb_name(cmd), 
13349                         (si->request)?"Request":"Response",
13350                         cmd);
13351
13352                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13353
13354                 dissector = (si->request)?
13355                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13356
13357                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13358                 proto_item_set_len(cmd_item, offset-old_offset);
13359         }
13360         return offset;
13361 }
13362
13363
13364 /* NOTE: this value_string array will also be used to access data directly by
13365  * index instead of val_to_str() since 
13366  * 1, the array will always span every value from 0x00 to 0xff and
13367  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13368  * This means that this value_string array MUST always
13369  * 1, contain all entries 0x00 to 0xff
13370  * 2, all entries must be in order.
13371  */
13372 static const value_string smb_cmd_vals[] = {
13373   { 0x00, "Create Directory" },
13374   { 0x01, "Delete Directory" },
13375   { 0x02, "Open" },
13376   { 0x03, "Create" },
13377   { 0x04, "Close" },
13378   { 0x05, "Flush" },
13379   { 0x06, "Delete" },
13380   { 0x07, "Rename" },
13381   { 0x08, "Query Information" },
13382   { 0x09, "Set Information" },
13383   { 0x0A, "Read" },
13384   { 0x0B, "Write" },
13385   { 0x0C, "Lock Byte Range" },
13386   { 0x0D, "Unlock Byte Range" },
13387   { 0x0E, "Create Temp" },
13388   { 0x0F, "Create New" },
13389   { 0x10, "Check Directory" },
13390   { 0x11, "Process Exit" },
13391   { 0x12, "Seek" },
13392   { 0x13, "Lock And Read" },
13393   { 0x14, "Write And Unlock" },
13394   { 0x15, "unknown-0x15" },
13395   { 0x16, "unknown-0x16" },
13396   { 0x17, "unknown-0x17" },
13397   { 0x18, "unknown-0x18" },
13398   { 0x19, "unknown-0x19" },
13399   { 0x1A, "Read Raw" },
13400   { 0x1B, "Read MPX" },
13401   { 0x1C, "Read MPX Secondary" },
13402   { 0x1D, "Write Raw" },
13403   { 0x1E, "Write MPX" },
13404   { 0x1F, "Write MPX Secondary" },
13405   { 0x20, "Write Complete" },
13406   { 0x21, "unknown-0x21" },
13407   { 0x22, "Set Information2" },
13408   { 0x23, "Query Information2" },
13409   { 0x24, "Locking AndX" },
13410   { 0x25, "Transaction" },
13411   { 0x26, "Transaction Secondary" },
13412   { 0x27, "IOCTL" },
13413   { 0x28, "IOCTL Secondary" },
13414   { 0x29, "Copy" },
13415   { 0x2A, "Move" },
13416   { 0x2B, "Echo" },
13417   { 0x2C, "Write And Close" },
13418   { 0x2D, "Open AndX" },
13419   { 0x2E, "Read AndX" },
13420   { 0x2F, "Write AndX" },
13421   { 0x30, "unknown-0x30" },
13422   { 0x31, "Close And Tree Disconnect" },
13423   { 0x32, "Transaction2" },
13424   { 0x33, "Transaction2 Secondary" },
13425   { 0x34, "Find Close2" },
13426   { 0x35, "Find Notify Close" },
13427   { 0x36, "unknown-0x36" },
13428   { 0x37, "unknown-0x37" },
13429   { 0x38, "unknown-0x38" },
13430   { 0x39, "unknown-0x39" },
13431   { 0x3A, "unknown-0x3A" },
13432   { 0x3B, "unknown-0x3B" },
13433   { 0x3C, "unknown-0x3C" },
13434   { 0x3D, "unknown-0x3D" },
13435   { 0x3E, "unknown-0x3E" },
13436   { 0x3F, "unknown-0x3F" },
13437   { 0x40, "unknown-0x40" },
13438   { 0x41, "unknown-0x41" },
13439   { 0x42, "unknown-0x42" },
13440   { 0x43, "unknown-0x43" },
13441   { 0x44, "unknown-0x44" },
13442   { 0x45, "unknown-0x45" },
13443   { 0x46, "unknown-0x46" },
13444   { 0x47, "unknown-0x47" },
13445   { 0x48, "unknown-0x48" },
13446   { 0x49, "unknown-0x49" },
13447   { 0x4A, "unknown-0x4A" },
13448   { 0x4B, "unknown-0x4B" },
13449   { 0x4C, "unknown-0x4C" },
13450   { 0x4D, "unknown-0x4D" },
13451   { 0x4E, "unknown-0x4E" },
13452   { 0x4F, "unknown-0x4F" },
13453   { 0x50, "unknown-0x50" },
13454   { 0x51, "unknown-0x51" },
13455   { 0x52, "unknown-0x52" },
13456   { 0x53, "unknown-0x53" },
13457   { 0x54, "unknown-0x54" },
13458   { 0x55, "unknown-0x55" },
13459   { 0x56, "unknown-0x56" },
13460   { 0x57, "unknown-0x57" },
13461   { 0x58, "unknown-0x58" },
13462   { 0x59, "unknown-0x59" },
13463   { 0x5A, "unknown-0x5A" },
13464   { 0x5B, "unknown-0x5B" },
13465   { 0x5C, "unknown-0x5C" },
13466   { 0x5D, "unknown-0x5D" },
13467   { 0x5E, "unknown-0x5E" },
13468   { 0x5F, "unknown-0x5F" },
13469   { 0x60, "unknown-0x60" },
13470   { 0x61, "unknown-0x61" },
13471   { 0x62, "unknown-0x62" },
13472   { 0x63, "unknown-0x63" },
13473   { 0x64, "unknown-0x64" },
13474   { 0x65, "unknown-0x65" },
13475   { 0x66, "unknown-0x66" },
13476   { 0x67, "unknown-0x67" },
13477   { 0x68, "unknown-0x68" },
13478   { 0x69, "unknown-0x69" },
13479   { 0x6A, "unknown-0x6A" },
13480   { 0x6B, "unknown-0x6B" },
13481   { 0x6C, "unknown-0x6C" },
13482   { 0x6D, "unknown-0x6D" },
13483   { 0x6E, "unknown-0x6E" },
13484   { 0x6F, "unknown-0x6F" },
13485   { 0x70, "Tree Connect" },
13486   { 0x71, "Tree Disconnect" },
13487   { 0x72, "Negotiate Protocol" },
13488   { 0x73, "Session Setup AndX" },
13489   { 0x74, "Logoff AndX" },
13490   { 0x75, "Tree Connect AndX" },
13491   { 0x76, "unknown-0x76" },
13492   { 0x77, "unknown-0x77" },
13493   { 0x78, "unknown-0x78" },
13494   { 0x79, "unknown-0x79" },
13495   { 0x7A, "unknown-0x7A" },
13496   { 0x7B, "unknown-0x7B" },
13497   { 0x7C, "unknown-0x7C" },
13498   { 0x7D, "unknown-0x7D" },
13499   { 0x7E, "unknown-0x7E" },
13500   { 0x7F, "unknown-0x7F" },
13501   { 0x80, "Query Information Disk" },
13502   { 0x81, "Search" },
13503   { 0x82, "Find" },
13504   { 0x83, "Find Unique" },
13505   { 0x84, "Find Close" },
13506   { 0x85, "unknown-0x85" },
13507   { 0x86, "unknown-0x86" },
13508   { 0x87, "unknown-0x87" },
13509   { 0x88, "unknown-0x88" },
13510   { 0x89, "unknown-0x89" },
13511   { 0x8A, "unknown-0x8A" },
13512   { 0x8B, "unknown-0x8B" },
13513   { 0x8C, "unknown-0x8C" },
13514   { 0x8D, "unknown-0x8D" },
13515   { 0x8E, "unknown-0x8E" },
13516   { 0x8F, "unknown-0x8F" },
13517   { 0x90, "unknown-0x90" },
13518   { 0x91, "unknown-0x91" },
13519   { 0x92, "unknown-0x92" },
13520   { 0x93, "unknown-0x93" },
13521   { 0x94, "unknown-0x94" },
13522   { 0x95, "unknown-0x95" },
13523   { 0x96, "unknown-0x96" },
13524   { 0x97, "unknown-0x97" },
13525   { 0x98, "unknown-0x98" },
13526   { 0x99, "unknown-0x99" },
13527   { 0x9A, "unknown-0x9A" },
13528   { 0x9B, "unknown-0x9B" },
13529   { 0x9C, "unknown-0x9C" },
13530   { 0x9D, "unknown-0x9D" },
13531   { 0x9E, "unknown-0x9E" },
13532   { 0x9F, "unknown-0x9F" },
13533   { 0xA0, "NT Transact" },
13534   { 0xA1, "NT Transact Secondary" },
13535   { 0xA2, "NT Create AndX" },
13536   { 0xA3, "unknown-0xA3" },
13537   { 0xA4, "NT Cancel" },
13538   { 0xA5, "NT Rename" },
13539   { 0xA6, "unknown-0xA6" },
13540   { 0xA7, "unknown-0xA7" },
13541   { 0xA8, "unknown-0xA8" },
13542   { 0xA9, "unknown-0xA9" },
13543   { 0xAA, "unknown-0xAA" },
13544   { 0xAB, "unknown-0xAB" },
13545   { 0xAC, "unknown-0xAC" },
13546   { 0xAD, "unknown-0xAD" },
13547   { 0xAE, "unknown-0xAE" },
13548   { 0xAF, "unknown-0xAF" },
13549   { 0xB0, "unknown-0xB0" },
13550   { 0xB1, "unknown-0xB1" },
13551   { 0xB2, "unknown-0xB2" },
13552   { 0xB3, "unknown-0xB3" },
13553   { 0xB4, "unknown-0xB4" },
13554   { 0xB5, "unknown-0xB5" },
13555   { 0xB6, "unknown-0xB6" },
13556   { 0xB7, "unknown-0xB7" },
13557   { 0xB8, "unknown-0xB8" },
13558   { 0xB9, "unknown-0xB9" },
13559   { 0xBA, "unknown-0xBA" },
13560   { 0xBB, "unknown-0xBB" },
13561   { 0xBC, "unknown-0xBC" },
13562   { 0xBD, "unknown-0xBD" },
13563   { 0xBE, "unknown-0xBE" },
13564   { 0xBF, "unknown-0xBF" },
13565   { 0xC0, "Open Print File" },
13566   { 0xC1, "Write Print File" },
13567   { 0xC2, "Close Print File" },
13568   { 0xC3, "Get Print Queue" },
13569   { 0xC4, "unknown-0xC4" },
13570   { 0xC5, "unknown-0xC5" },
13571   { 0xC6, "unknown-0xC6" },
13572   { 0xC7, "unknown-0xC7" },
13573   { 0xC8, "unknown-0xC8" },
13574   { 0xC9, "unknown-0xC9" },
13575   { 0xCA, "unknown-0xCA" },
13576   { 0xCB, "unknown-0xCB" },
13577   { 0xCC, "unknown-0xCC" },
13578   { 0xCD, "unknown-0xCD" },
13579   { 0xCE, "unknown-0xCE" },
13580   { 0xCF, "unknown-0xCF" },
13581   { 0xD0, "Send Single Block Message" },
13582   { 0xD1, "Send Broadcast Message" },
13583   { 0xD2, "Forward User Name" },
13584   { 0xD3, "Cancel Forward" },
13585   { 0xD4, "Get Machine Name" },
13586   { 0xD5, "Send Start of Multi-block Message" },
13587   { 0xD6, "Send End of Multi-block Message" },
13588   { 0xD7, "Send Text of Multi-block Message" },
13589   { 0xD8, "SMBreadbulk" },
13590   { 0xD9, "SMBwritebulk" },
13591   { 0xDA, "SMBwritebulkdata" },
13592   { 0xDB, "unknown-0xDB" },
13593   { 0xDC, "unknown-0xDC" },
13594   { 0xDD, "unknown-0xDD" },
13595   { 0xDE, "unknown-0xDE" },
13596   { 0xDF, "unknown-0xDF" },
13597   { 0xE0, "unknown-0xE0" },
13598   { 0xE1, "unknown-0xE1" },
13599   { 0xE2, "unknown-0xE2" },
13600   { 0xE3, "unknown-0xE3" },
13601   { 0xE4, "unknown-0xE4" },
13602   { 0xE5, "unknown-0xE5" },
13603   { 0xE6, "unknown-0xE6" },
13604   { 0xE7, "unknown-0xE7" },
13605   { 0xE8, "unknown-0xE8" },
13606   { 0xE9, "unknown-0xE9" },
13607   { 0xEA, "unknown-0xEA" },
13608   { 0xEB, "unknown-0xEB" },
13609   { 0xEC, "unknown-0xEC" },
13610   { 0xED, "unknown-0xED" },
13611   { 0xEE, "unknown-0xEE" },
13612   { 0xEF, "unknown-0xEF" },
13613   { 0xF0, "unknown-0xF0" },
13614   { 0xF1, "unknown-0xF1" },
13615   { 0xF2, "unknown-0xF2" },
13616   { 0xF3, "unknown-0xF3" },
13617   { 0xF4, "unknown-0xF4" },
13618   { 0xF5, "unknown-0xF5" },
13619   { 0xF6, "unknown-0xF6" },
13620   { 0xF7, "unknown-0xF7" },
13621   { 0xF8, "unknown-0xF8" },
13622   { 0xF9, "unknown-0xF9" },
13623   { 0xFA, "unknown-0xFA" },
13624   { 0xFB, "unknown-0xFB" },
13625   { 0xFC, "unknown-0xFC" },
13626   { 0xFD, "unknown-0xFD" },
13627   { 0xFE, "SMBinvalid" },
13628   { 0xFF, "unknown-0xFF" },
13629   { 0x00, NULL },
13630 };
13631
13632 static char *decode_smb_name(unsigned char cmd)
13633 {
13634   return(smb_cmd_vals[cmd].strptr);
13635 }
13636  
13637
13638
13639 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13640  * Everything TVBUFFIFIED above this line
13641  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13642
13643
13644 static void
13645 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
13646 {
13647         conv_tables_t *ct = ctarg;
13648
13649         if (ct->unmatched)
13650                 g_hash_table_destroy(ct->unmatched);
13651         if (ct->matched)
13652                 g_hash_table_destroy(ct->matched);
13653         if (ct->dcerpc_fid_to_frame)
13654                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
13655         if (ct->tid_service)
13656                 g_hash_table_destroy(ct->tid_service);
13657 }
13658
13659 static void
13660 smb_init_protocol(void)
13661 {
13662         if (smb_saved_info_key_chunk)
13663                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
13664         if (smb_saved_info_chunk)
13665                 g_mem_chunk_destroy(smb_saved_info_chunk);
13666         if (smb_nt_transact_info_chunk)
13667                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
13668         if (smb_transact2_info_chunk)
13669                 g_mem_chunk_destroy(smb_transact2_info_chunk);
13670         if (smb_transact_info_chunk)
13671                 g_mem_chunk_destroy(smb_transact_info_chunk);
13672
13673         /*
13674          * Free the hash tables attached to the conversation table
13675          * structures, and then free the list of conversation table
13676          * data structures (which doesn't free the data structures
13677          * themselves; that's done by destroying the chunk from
13678          * which they were allocated).
13679          */
13680         if (conv_tables) {
13681                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
13682                 g_slist_free(conv_tables);
13683                 conv_tables = NULL;
13684         }
13685
13686         /*
13687          * Now destroy the chunk from which the conversation table
13688          * structures were allocated.
13689          */
13690         if (conv_tables_chunk)
13691                 g_mem_chunk_destroy(conv_tables_chunk);
13692
13693         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
13694             sizeof(smb_saved_info_t),
13695             smb_saved_info_init_count * sizeof(smb_saved_info_t),
13696             G_ALLOC_ONLY);
13697         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
13698             sizeof(smb_saved_info_key_t),
13699             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
13700             G_ALLOC_ONLY);
13701         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
13702             sizeof(smb_nt_transact_info_t),
13703             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
13704             G_ALLOC_ONLY);
13705         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
13706             sizeof(smb_transact2_info_t),
13707             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
13708             G_ALLOC_ONLY);
13709         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
13710             sizeof(smb_transact_info_t),
13711             smb_transact_info_init_count * sizeof(smb_transact_info_t),
13712             G_ALLOC_ONLY);
13713         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
13714             sizeof(conv_tables_t),
13715             conv_tables_count * sizeof(conv_tables_t),
13716             G_ALLOC_ONLY);
13717 }
13718
13719 /* Max string length for displaying Unicode strings.  */
13720 #define MAX_UNICODE_STR_LEN     256
13721
13722
13723 /* Turn a little-endian Unicode '\0'-terminated string into a string we
13724    can display.
13725    XXX - for now, we just handle the ISO 8859-1 characters.
13726    If exactlen==TRUE then us_lenp contains the exact len of the string in
13727    bytes. It might not be null terminated !
13728    bc specifies the number of bytes in the byte parameters; Windows 2000,
13729    at least, appears, in some cases, to put only 1 byte of 0 at the end
13730    of a Unicode string if the byte count
13731 */
13732 static gchar *
13733 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
13734                    guint16 bc)
13735 {
13736   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
13737   static gchar *cur;
13738   gchar        *p;
13739   guint16       uchar;
13740   int           len;
13741   int           us_len;
13742   int           overflow = 0;
13743
13744   if (cur == &str[0][0]) {
13745     cur = &str[1][0];
13746   } else if (cur == &str[1][0]) {  
13747     cur = &str[2][0];
13748   } else {  
13749     cur = &str[0][0];
13750   }
13751   p = cur;
13752   len = MAX_UNICODE_STR_LEN;
13753   us_len = 0;
13754   for (;;) {
13755     if (bc == 0)
13756       break;
13757     if (bc == 1) {
13758       /* XXX - explain this */
13759       if (!exactlen)
13760         us_len += 1;    /* this is a one-byte null terminator */
13761       break;
13762     }
13763     uchar = tvb_get_letohs(tvb, offset);
13764     if (uchar == 0) {
13765       us_len += 2;      /* this is a two-byte null terminator */
13766       break;
13767     }
13768     if (len > 0) {
13769       if ((uchar & 0xFF00) == 0)
13770         *p++ = uchar;   /* ISO 8859-1 */
13771       else
13772         *p++ = '?';     /* not 8859-1 */
13773       len--;
13774     } else
13775       overflow = 1;
13776     offset += 2;
13777     bc -= 2;
13778     us_len += 2;
13779     if(exactlen){
13780       if(us_len>= *us_lenp){
13781         break;
13782       }
13783     }
13784   }
13785   if (overflow) {
13786     /* Note that we're not showing the full string.  */
13787     *p++ = '.';
13788     *p++ = '.';
13789     *p++ = '.';
13790   }
13791   *p = '\0';
13792   *us_lenp = us_len;
13793   return cur;
13794 }
13795  
13796
13797 /* nopad == TRUE : Do not add any padding before this string
13798  * exactlen == TRUE : len contains the exact len of the string in bytes.
13799  * bc: pointer to variable with amount of data left in the byte parameters
13800  *   region
13801  */
13802 static const gchar *
13803 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
13804     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
13805     guint16 *bcp)
13806 {
13807   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
13808   static gchar *cur;
13809   const gchar *string;
13810   int string_len;
13811   smb_info_t *si;
13812   unsigned int copylen;
13813
13814   if (*bcp == 0) {
13815     /* Not enough data in buffer */
13816     return NULL;
13817   }
13818   si = pinfo->private_data;
13819   if (si->unicode) {
13820     if ((!nopad) && (*offsetp % 2)) {
13821       /*
13822        * XXX - this should be an offset relative to the beginning of the SMB,
13823        * not an offset relative to the beginning of the frame; if the stuff
13824        * before the SMB has an odd number of bytes, an offset relative to
13825        * the beginning of the frame will give the wrong answer.
13826        */
13827       (*offsetp)++;   /* Looks like a pad byte there sometimes */
13828       (*bcp)--;
13829       if (*bcp == 0) {
13830         /* Not enough data in buffer */
13831         return NULL;
13832       }
13833     }
13834     if(exactlen){
13835       string_len = *len;
13836     }
13837     string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
13838   } else {
13839     if(exactlen){
13840       /*
13841        * The string we return must be null-terminated.
13842        */
13843       if (cur == &str[0][0]) {
13844         cur = &str[1][0];
13845       } else if (cur == &str[1][0]) {  
13846         cur = &str[2][0];
13847       } else {  
13848         cur = &str[0][0];
13849       }
13850       copylen = *len;
13851       if (copylen > MAX_UNICODE_STR_LEN)
13852         copylen = MAX_UNICODE_STR_LEN;
13853       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
13854       cur[copylen] = '\0';
13855       if (copylen > MAX_UNICODE_STR_LEN)
13856         strcat(cur, "...");
13857       string_len = *len;
13858       string = cur;
13859     } else {
13860       string_len = tvb_strsize(tvb, *offsetp);
13861       string = tvb_get_ptr(tvb, *offsetp, string_len);
13862     }
13863   }
13864   *len = string_len;
13865   return string;
13866 }
13867
13868
13869
13870 static const value_string errcls_types[] = {
13871   { SMB_SUCCESS, "Success"},
13872   { SMB_ERRDOS, "DOS Error"},
13873   { SMB_ERRSRV, "Server Error"},
13874   { SMB_ERRHRD, "Hardware Error"},
13875   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
13876   { 0, NULL }
13877 };
13878
13879 const value_string DOS_errors[] = {
13880   {0, "Success"},
13881   {SMBE_insufficientbuffer, "Insufficient buffer"},
13882   {SMBE_badfunc, "Invalid function (or system call)"},
13883   {SMBE_badfile, "File not found (pathname error)"},
13884   {SMBE_badpath, "Directory not found"},
13885   {SMBE_nofids, "Too many open files"},
13886   {SMBE_noaccess, "Access denied"},
13887   {SMBE_badfid, "Invalid fid"},
13888   {SMBE_nomem,  "Out of memory"},
13889   {SMBE_badmem, "Invalid memory block address"},
13890   {SMBE_badenv, "Invalid environment"},
13891   {SMBE_badaccess, "Invalid open mode"},
13892   {SMBE_baddata, "Invalid data (only from ioctl call)"},
13893   {SMBE_res, "Reserved error code?"}, 
13894   {SMBE_baddrive, "Invalid drive"},
13895   {SMBE_remcd, "Attempt to delete current directory"},
13896   {SMBE_diffdevice, "Rename/move across different filesystems"},
13897   {SMBE_nofiles, "No more files found in file search"},
13898   {SMBE_badshare, "Share mode on file conflict with open mode"},
13899   {SMBE_lock, "Lock request conflicts with existing lock"},
13900   {SMBE_unsup, "Request unsupported, returned by Win 95"},
13901   {SMBE_nosuchshare, "Requested share does not exist"},
13902   {SMBE_filexists, "File in operation already exists"},
13903   {SMBE_cannotopen, "Cannot open the file specified"},
13904   {SMBE_unknownlevel, "Unknown info level"},
13905   {SMBE_invalidname, "Invalid name"},
13906   {SMBE_badpipe, "Named pipe invalid"},
13907   {SMBE_pipebusy, "All instances of pipe are busy"},
13908   {SMBE_pipeclosing, "Named pipe close in progress"},
13909   {SMBE_notconnected, "No process on other end of named pipe"},
13910   {SMBE_moredata, "More data to be returned"},
13911   {SMBE_baddirectory,  "Invalid directory name in a path."},
13912   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
13913   {SMBE_eas_nsup, "Extended attributes not supported"},
13914   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
13915   {SMBE_unknownipc, "Unknown IPC Operation"},
13916   {SMBE_noipc, "Don't support ipc"},
13917   {SMBE_alreadyexists, "File already exists"},
13918   {SMBE_unknownprinterdriver, "Unknown printer driver"},
13919   {SMBE_invalidprintername, "Invalid printer name"},
13920   {SMBE_printeralreadyexists, "Printer already exists"},
13921   {SMBE_invaliddatatype, "Invalid data type"},
13922   {SMBE_invalidenvironment, "Invalid environment"},
13923   {SMBE_printerdriverinuse, "Printer driver in use"},
13924   {SMBE_invalidparam, "Invalid parameter"},
13925   {SMBE_invalidformsize, "Invalid form size"},
13926   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
13927   {SMBE_invalidowner, "Invalid owner"},
13928   {0, NULL}
13929   };
13930
13931 /* Error codes for the ERRSRV class */
13932
13933 static const value_string SRV_errors[] = {
13934   {SMBE_error, "Non specific error code"},
13935   {SMBE_badpw, "Bad password"},
13936   {SMBE_badtype, "Reserved"},
13937   {SMBE_access, "No permissions to perform the requested operation"},
13938   {SMBE_invnid, "TID invalid"},
13939   {SMBE_invnetname, "Invalid network name. Service not found"},
13940   {SMBE_invdevice, "Invalid device"},
13941   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
13942   {SMBE_qfull, "Print queue full"},
13943   {SMBE_qtoobig, "Queued item too big"},
13944   {SMBE_qeof, "EOF on print queue dump"},
13945   {SMBE_invpfid, "Invalid print file in smb_fid"},
13946   {SMBE_smbcmd, "Unrecognised command"},
13947   {SMBE_srverror, "SMB server internal error"},
13948   {SMBE_filespecs, "Fid and pathname invalid combination"},
13949   {SMBE_badlink, "Bad link in request ???"},
13950   {SMBE_badpermits, "Access specified for a file is not valid"},
13951   {SMBE_badpid, "Bad process id in request"},
13952   {SMBE_setattrmode, "Attribute mode invalid"},
13953   {SMBE_paused, "Message server paused"},
13954   {SMBE_msgoff, "Not receiving messages"},
13955   {SMBE_noroom, "No room for message"},
13956   {SMBE_rmuns, "Too many remote usernames"},
13957   {SMBE_timeout, "Operation timed out"},
13958   {SMBE_noresource, "No resources currently available for request."},
13959   {SMBE_toomanyuids, "Too many userids"},
13960   {SMBE_baduid, "Bad userid"},
13961   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
13962   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
13963   {SMBE_contMPX, "Resume MPX mode"},
13964   {SMBE_badPW, "Bad Password???"},
13965   {SMBE_nosupport, "Operation not supported"},
13966   { 0, NULL}
13967 };
13968
13969 /* Error codes for the ERRHRD class */
13970
13971 static const value_string HRD_errors[] = {
13972   {SMBE_nowrite, "Read only media"},
13973   {SMBE_badunit, "Unknown device"},
13974   {SMBE_notready, "Drive not ready"},
13975   {SMBE_badcmd, "Unknown command"},
13976   {SMBE_data, "Data (CRC) error"},
13977   {SMBE_badreq, "Bad request structure length"},
13978   {SMBE_seek, "Seek error"},
13979   {SMBE_badmedia, "Unknown media type"},
13980   {SMBE_badsector, "Sector not found"},
13981   {SMBE_nopaper, "Printer out of paper"},
13982   {SMBE_write, "Write fault"},
13983   {SMBE_read, "Read fault"},
13984   {SMBE_general, "General failure"},
13985   {SMBE_badshare, "A open conflicts with an existing open"},
13986   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
13987   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
13988   {SMBE_FCBunavail, "No FCBs are available to process request"},
13989   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
13990   {SMBE_diskfull, "Disk full???"},
13991   {0, NULL}
13992 };
13993
13994 static char *decode_smb_error(guint8 errcls, guint16 errcode)
13995 {
13996
13997   switch (errcls) {
13998
13999   case SMB_SUCCESS:
14000
14001     return("No Error");   /* No error ??? */
14002     break;
14003
14004   case SMB_ERRDOS:
14005
14006     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14007     break;
14008
14009   case SMB_ERRSRV:
14010
14011     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14012     break;
14013
14014   case SMB_ERRHRD:
14015
14016     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14017     break;
14018
14019   default:
14020
14021     return("Unknown error class!");
14022
14023   }
14024
14025 }
14026
14027
14028 /* These are the MS country codes from
14029
14030         http://www.unicode.org/unicode/onlinedat/countries.html
14031
14032    For countries that share the same number, I choose to use only the
14033    name of the largest country. Apologies for this. If this offends you,
14034    here is the table to change that.
14035
14036    This also includes the code of 0 for "Default", which isn't in
14037    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14038    header file.  Presumably it means "don't override the setting
14039    on the user's machine".
14040
14041    Future versions of Microsoft's "winnls.h" header file might include
14042    additional codes; the current version matches the Unicode Consortium's
14043    table.
14044 */
14045 const value_string ms_country_codes[] = {
14046         {  0,   "Default"},
14047         {  1,   "USA"},
14048         {  2,   "Canada"},
14049         {  7,   "Russia"},
14050         { 20,   "Egypt"},
14051         { 27,   "South Africa"},
14052         { 30,   "Greece"},
14053         { 31,   "Netherlands"},
14054         { 32,   "Belgium"},
14055         { 33,   "France"},
14056         { 34,   "Spain"},
14057         { 36,   "Hungary"},
14058         { 39,   "Italy"},
14059         { 40,   "Romania"},
14060         { 41,   "Switzerland"},
14061         { 43,   "Austria"},
14062         { 44,   "United Kingdom"},
14063         { 45,   "Denmark"},
14064         { 46,   "Sweden"},
14065         { 47,   "Norway"},
14066         { 48,   "Poland"},
14067         { 49,   "Germany"},
14068         { 51,   "Peru"},
14069         { 52,   "Mexico"},
14070         { 54,   "Argentina"},
14071         { 55,   "Brazil"},
14072         { 56,   "Chile"},
14073         { 57,   "Colombia"},
14074         { 58,   "Venezuela"},
14075         { 60,   "Malaysia"},
14076         { 61,   "Australia"},
14077         { 62,   "Indonesia"},
14078         { 63,   "Philippines"},
14079         { 64,   "New Zealand"},
14080         { 65,   "Singapore"},
14081         { 66,   "Thailand"},
14082         { 81,   "Japan"},
14083         { 82,   "South Korea"},
14084         { 84,   "Viet Nam"},
14085         { 86,   "China"},
14086         { 90,   "Turkey"},
14087         { 91,   "India"},
14088         { 92,   "Pakistan"},
14089         {212,   "Morocco"},
14090         {213,   "Algeria"},
14091         {216,   "Tunisia"},
14092         {218,   "Libya"},
14093         {254,   "Kenya"},
14094         {263,   "Zimbabwe"},
14095         {298,   "Faroe Islands"},
14096         {351,   "Portugal"},
14097         {352,   "Luxembourg"},
14098         {353,   "Ireland"},
14099         {354,   "Iceland"},
14100         {355,   "Albania"},
14101         {358,   "Finland"},
14102         {359,   "Bulgaria"},
14103         {370,   "Lithuania"},
14104         {371,   "Latvia"},
14105         {372,   "Estonia"},
14106         {374,   "Armenia"},
14107         {375,   "Belarus"},
14108         {380,   "Ukraine"},
14109         {381,   "Serbia"},
14110         {385,   "Croatia"},
14111         {386,   "Slovenia"},
14112         {389,   "Macedonia"},
14113         {420,   "Czech Republic"},
14114         {421,   "Slovak Republic"},
14115         {501,   "Belize"},
14116         {502,   "Guatemala"},
14117         {503,   "El Salvador"},
14118         {504,   "Honduras"},
14119         {505,   "Nicaragua"},
14120         {506,   "Costa Rica"},
14121         {507,   "Panama"},
14122         {591,   "Bolivia"},
14123         {593,   "Ecuador"},
14124         {595,   "Paraguay"},
14125         {598,   "Uruguay"},
14126         {673,   "Brunei Darussalam"},
14127         {852,   "Hong Kong"},
14128         {853,   "Macau"},
14129         {886,   "Taiwan"},
14130         {960,   "Maldives"},
14131         {961,   "Lebanon"},
14132         {962,   "Jordan"},
14133         {963,   "Syria"},
14134         {964,   "Iraq"},
14135         {965,   "Kuwait"},
14136         {966,   "Saudi Arabia"},
14137         {967,   "Yemen"},
14138         {968,   "Oman"},
14139         {971,   "United Arab Emirates"},
14140         {972,   "Israel"},
14141         {973,   "Bahrain"},
14142         {974,   "Qatar"},
14143         {976,   "Mongolia"},
14144         {981,   "Iran"},
14145         {994,   "Azerbaijan"},
14146         {995,   "Georgia"},
14147         {996,   "Kyrgyzstan"},
14148
14149         {0,     NULL}
14150 };
14151
14152 /*
14153  * NT error codes.
14154  *
14155  * From
14156  *
14157  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14158  */
14159 const value_string NT_errors[] = {
14160   { 0x00000000, "STATUS_SUCCESS" },
14161   { 0x00000000, "STATUS_WAIT_0" },
14162   { 0x00000001, "STATUS_WAIT_1" },
14163   { 0x00000002, "STATUS_WAIT_2" },
14164   { 0x00000003, "STATUS_WAIT_3" },
14165   { 0x0000003F, "STATUS_WAIT_63" },
14166   { 0x00000080, "STATUS_ABANDONED" },
14167   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14168   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14169   { 0x000000C0, "STATUS_USER_APC" },
14170   { 0x00000100, "STATUS_KERNEL_APC" },
14171   { 0x00000101, "STATUS_ALERTED" },
14172   { 0x00000102, "STATUS_TIMEOUT" },
14173   { 0x00000103, "STATUS_PENDING" },
14174   { 0x00000104, "STATUS_REPARSE" },
14175   { 0x00000105, "STATUS_MORE_ENTRIES" },
14176   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14177   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14178   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14179   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14180   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14181   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14182   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14183   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14184   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14185   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14186   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14187   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14188   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14189   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14190   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14191   { 0x00000116, "STATUS_CRASH_DUMP" },
14192   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14193   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14194   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14195   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14196   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14197   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14198   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14199   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14200   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14201   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14202   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14203   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14204   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14205   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14206   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14207   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14208   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14209   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14210   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14211   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14212   { 0x40000012, "STATUS_EVENT_DONE" },
14213   { 0x40000013, "STATUS_EVENT_PENDING" },
14214   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14215   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14216   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14217   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14218   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14219   { 0x40000019, "STATUS_WAS_LOCKED" },
14220   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14221   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14222   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14223   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14224   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14225   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14226   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14227   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14228   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14229   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14230   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14231   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14232   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14233   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14234   { 0x80000003, "STATUS_BREAKPOINT" },
14235   { 0x80000004, "STATUS_SINGLE_STEP" },
14236   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14237   { 0x80000006, "STATUS_NO_MORE_FILES" },
14238   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14239   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14240   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14241   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14242   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14243   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14244   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14245   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14246   { 0x80000011, "STATUS_DEVICE_BUSY" },
14247   { 0x80000012, "STATUS_NO_MORE_EAS" },
14248   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14249   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14250   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14251   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14252   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14253   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14254   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14255   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14256   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14257   { 0x8000001D, "STATUS_BUS_RESET" },
14258   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14259   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14260   { 0x80000020, "STATUS_MEDIA_CHECK" },
14261   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14262   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14263   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14264   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14265   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14266   { 0x80000026, "STATUS_LONGJUMP" },
14267   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14268   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14269   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14270   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14271   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14272   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14273   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14274   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14275   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14276   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14277   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14278   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14279   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14280   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14281   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14282   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14283   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14284   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14285   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14286   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14287   { 0xC000000B, "STATUS_INVALID_CID" },
14288   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14289   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14290   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14291   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14292   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14293   { 0xC0000011, "STATUS_END_OF_FILE" },
14294   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14295   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14296   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14297   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14298   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14299   { 0xC0000017, "STATUS_NO_MEMORY" },
14300   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14301   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14302   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14303   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14304   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14305   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14306   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14307   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14308   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14309   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14310   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14311   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14312   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14313   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14314   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14315   { 0xC0000027, "STATUS_UNWIND" },
14316   { 0xC0000028, "STATUS_BAD_STACK" },
14317   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14318   { 0xC000002A, "STATUS_NOT_LOCKED" },
14319   { 0xC000002B, "STATUS_PARITY_ERROR" },
14320   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14321   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14322   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14323   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14324   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14325   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14326   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14327   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14328   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14329   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14330   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14331   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14332   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14333   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14334   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14335   { 0xC000003C, "STATUS_DATA_OVERRUN" },
14336   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
14337   { 0xC000003E, "STATUS_DATA_ERROR" },
14338   { 0xC000003F, "STATUS_CRC_ERROR" },
14339   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
14340   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
14341   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
14342   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
14343   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
14344   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
14345   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
14346   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
14347   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
14348   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
14349   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
14350   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
14351   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
14352   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
14353   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
14354   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
14355   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
14356   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
14357   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
14358   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
14359   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
14360   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
14361   { 0xC0000056, "STATUS_DELETE_PENDING" },
14362   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
14363   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
14364   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
14365   { 0xC000005A, "STATUS_INVALID_OWNER" },
14366   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
14367   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
14368   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
14369   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
14370   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
14371   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
14372   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
14373   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
14374   { 0xC0000063, "STATUS_USER_EXISTS" },
14375   { 0xC0000064, "STATUS_NO_SUCH_USER" },
14376   { 0xC0000065, "STATUS_GROUP_EXISTS" },
14377   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
14378   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
14379   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
14380   { 0xC0000069, "STATUS_LAST_ADMIN" },
14381   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
14382   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
14383   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
14384   { 0xC000006D, "STATUS_LOGON_FAILURE" },
14385   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
14386   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
14387   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
14388   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
14389   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
14390   { 0xC0000073, "STATUS_NONE_MAPPED" },
14391   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
14392   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
14393   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
14394   { 0xC0000077, "STATUS_INVALID_ACL" },
14395   { 0xC0000078, "STATUS_INVALID_SID" },
14396   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
14397   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
14398   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
14399   { 0xC000007C, "STATUS_NO_TOKEN" },
14400   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
14401   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
14402   { 0xC000007F, "STATUS_DISK_FULL" },
14403   { 0xC0000080, "STATUS_SERVER_DISABLED" },
14404   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
14405   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
14406   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
14407   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
14408   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
14409   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
14410   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
14411   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
14412   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
14413   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
14414   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
14415   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
14416   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
14417   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
14418   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
14419   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
14420   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
14421   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
14422   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
14423   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
14424   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
14425   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
14426   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
14427   { 0xC0000098, "STATUS_FILE_INVALID" },
14428   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
14429   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
14430   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
14431   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
14432   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
14433   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
14434   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
14435   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
14436   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
14437   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
14438   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
14439   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
14440   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
14441   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
14442   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
14443   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
14444   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
14445   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
14446   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
14447   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
14448   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
14449   { 0xC00000AE, "STATUS_PIPE_BUSY" },
14450   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
14451   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
14452   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
14453   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
14454   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
14455   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
14456   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
14457   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
14458   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
14459   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
14460   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
14461   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
14462   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
14463   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
14464   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
14465   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
14466   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
14467   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
14468   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
14469   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
14470   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
14471   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
14472   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
14473   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
14474   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
14475   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
14476   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
14477   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
14478   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
14479   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
14480   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
14481   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
14482   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
14483   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
14484   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
14485   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
14486   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
14487   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
14488   { 0xC00000D5, "STATUS_FILE_RENAMED" },
14489   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
14490   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
14491   { 0xC00000D8, "STATUS_CANT_WAIT" },
14492   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
14493   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
14494   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
14495   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
14496   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
14497   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
14498   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
14499   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
14500   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
14501   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
14502   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
14503   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
14504   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
14505   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
14506   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
14507   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
14508   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
14509   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
14510   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
14511   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
14512   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
14513   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
14514   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
14515   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
14516   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
14517   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
14518   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
14519   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
14520   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
14521   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
14522   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
14523   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
14524   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
14525   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
14526   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
14527   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
14528   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
14529   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
14530   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
14531   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
14532   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
14533   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
14534   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
14535   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
14536   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
14537   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
14538   { 0xC0000107, "STATUS_FILES_OPEN" },
14539   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
14540   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
14541   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
14542   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
14543   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
14544   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
14545   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
14546   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
14547   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
14548   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
14549   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
14550   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
14551   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
14552   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
14553   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
14554   { 0xC0000117, "STATUS_NO_LDT" },
14555   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
14556   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
14557   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
14558   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
14559   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
14560   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
14561   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
14562   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
14563   { 0xC0000120, "STATUS_CANCELLED" },
14564   { 0xC0000121, "STATUS_CANNOT_DELETE" },
14565   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
14566   { 0xC0000123, "STATUS_FILE_DELETED" },
14567   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
14568   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
14569   { 0xC0000126, "STATUS_SPECIAL_USER" },
14570   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
14571   { 0xC0000128, "STATUS_FILE_CLOSED" },
14572   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
14573   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
14574   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
14575   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
14576   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
14577   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
14578   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
14579   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
14580   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
14581   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
14582   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
14583   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
14584   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
14585   { 0xC0000136, "STATUS_OPEN_FAILED" },
14586   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
14587   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
14588   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
14589   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
14590   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
14591   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
14592   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
14593   { 0xC000013E, "STATUS_LINK_FAILED" },
14594   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
14595   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
14596   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
14597   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
14598   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
14599   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
14600   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
14601   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
14602   { 0xC0000147, "STATUS_NO_PAGEFILE" },
14603   { 0xC0000148, "STATUS_INVALID_LEVEL" },
14604   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
14605   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
14606   { 0xC000014B, "STATUS_PIPE_BROKEN" },
14607   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
14608   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
14609   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
14610   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
14611   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
14612   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
14613   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
14614   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
14615   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
14616   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
14617   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
14618   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
14619   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
14620   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
14621   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
14622   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
14623   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
14624   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
14625   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
14626   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
14627   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
14628   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
14629   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
14630   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
14631   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
14632   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
14633   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
14634   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
14635   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
14636   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
14637   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
14638   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
14639   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
14640   { 0xC000016D, "STATUS_FT_ORPHANING" },
14641   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
14642   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
14643   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
14644   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
14645   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
14646   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
14647   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
14648   { 0xC0000178, "STATUS_NO_MEDIA" },
14649   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
14650   { 0xC000017B, "STATUS_INVALID_MEMBER" },
14651   { 0xC000017C, "STATUS_KEY_DELETED" },
14652   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
14653   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
14654   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
14655   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
14656   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
14657   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
14658   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
14659   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
14660   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
14661   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
14662   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
14663   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
14664   { 0xC0000189, "STATUS_TOO_LATE" },
14665   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
14666   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
14667   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
14668   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
14669   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
14670   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
14671   { 0xC0000190, "STATUS_TRUST_FAILURE" },
14672   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
14673   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
14674   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
14675   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
14676   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
14677   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
14678   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
14679   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
14680   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
14681   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
14682   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
14683   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
14684   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
14685   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
14686   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
14687   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
14688   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
14689   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
14690   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
14691   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
14692   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
14693   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
14694   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
14695   { 0xC000020D, "STATUS_CONNECTION_RESET" },
14696   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
14697   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
14698   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
14699   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
14700   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
14701   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
14702   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
14703   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
14704   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
14705   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
14706   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
14707   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
14708   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
14709   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
14710   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
14711   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
14712   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
14713   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
14714   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
14715   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
14716   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
14717   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
14718   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
14719   { 0xC0000225, "STATUS_NOT_FOUND" },
14720   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
14721   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
14722   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
14723   { 0xC0000229, "STATUS_FAIL_CHECK" },
14724   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
14725   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
14726   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
14727   { 0xC000022D, "STATUS_RETRY" },
14728   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
14729   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
14730   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
14731   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
14732   { 0xC0000232, "STATUS_INVALID_VARIANT" },
14733   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
14734   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
14735   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
14736   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
14737   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
14738   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
14739   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
14740   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
14741   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
14742   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
14743   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
14744   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
14745   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
14746   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
14747   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
14748   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
14749   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
14750   { 0xC0000244, "STATUS_AUDIT_FAILED" },
14751   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
14752   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
14753   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
14754   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
14755   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
14756   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
14757   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
14758   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
14759   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
14760   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
14761   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
14762   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
14763   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
14764   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
14765   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
14766   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
14767   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
14768   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
14769   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
14770   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
14771   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
14772   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
14773   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
14774   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
14775   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
14776   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
14777   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
14778   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
14779   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
14780   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
14781   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
14782   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
14783   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
14784   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
14785   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
14786   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
14787   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
14788   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
14789   { 0xC0000272, "STATUS_NO_MATCH" },
14790   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
14791   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
14792   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
14793   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
14794   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
14795   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
14796   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
14797   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
14798   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
14799   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
14800   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
14801   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
14802   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
14803   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
14804   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
14805   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
14806   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
14807   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
14808   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
14809   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
14810   { 0xC000028E, "STATUS_NO_EFS" },
14811   { 0xC000028F, "STATUS_WRONG_EFS" },
14812   { 0xC0000290, "STATUS_NO_USER_KEYS" },
14813   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
14814   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
14815   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
14816   { 0x40000294, "STATUS_WAKE_SYSTEM" },
14817   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
14818   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
14819   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
14820   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
14821   { 0xC0000299, "STATUS_SHARED_POLICY" },
14822   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
14823   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
14824   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
14825   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
14826   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
14827   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
14828   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
14829   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
14830   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
14831   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
14832   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
14833   { 0xC00002A5, "STATUS_DS_BUSY" },
14834   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
14835   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
14836   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
14837   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
14838   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
14839   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
14840   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
14841   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
14842   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
14843   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
14844   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
14845   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
14846   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
14847   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
14848   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
14849   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
14850   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
14851   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
14852   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
14853   { 0xC00002B9, "STATUS_NOINTERFACE" },
14854   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
14855   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
14856   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
14857   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
14858   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
14859   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
14860   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
14861   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
14862   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
14863   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
14864   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
14865   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
14866   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
14867   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
14868   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
14869   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
14870   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
14871   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
14872   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
14873   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
14874   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
14875   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
14876   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
14877   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
14878   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
14879   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
14880   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
14881   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
14882   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
14883   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
14884   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
14885   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
14886   { 0xC00002E1, "STATUS_DS_CANT_START" },
14887   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
14888   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
14889   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
14890   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
14891   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
14892   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
14893   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
14894   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
14895   { 0xC0009898, "STATUS_WOW_ASSERTION" },
14896   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
14897   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
14898   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
14899   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
14900   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
14901   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
14902   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
14903   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
14904   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
14905   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
14906   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
14907   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
14908   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
14909   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
14910   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
14911   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
14912   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
14913   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
14914   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
14915   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
14916   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
14917   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
14918   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
14919   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
14920   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
14921   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
14922   { 0xC002001B, "RPC_NT_CALL_FAILED" },
14923   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
14924   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
14925   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
14926   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
14927   { 0xC0020022, "RPC_NT_INVALID_TAG" },
14928   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
14929   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
14930   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
14931   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
14932   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
14933   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
14934   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
14935   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
14936   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
14937   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
14938   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
14939   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
14940   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
14941   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
14942   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
14943   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
14944   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
14945   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
14946   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
14947   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
14948   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
14949   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
14950   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
14951   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
14952   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
14953   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
14954   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
14955   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
14956   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
14957   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
14958   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
14959   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
14960   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
14961   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
14962   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
14963   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
14964   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
14965   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
14966   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
14967   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
14968   { 0xC002100A, "RPC_P_SEND_FAILED" },
14969   { 0xC002100B, "RPC_P_TIMEOUT" },
14970   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
14971   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
14972   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
14973   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
14974   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
14975   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
14976   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
14977   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
14978   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
14979   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
14980   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
14981   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
14982   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
14983   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
14984   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
14985   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
14986   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
14987   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
14988   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
14989   { 0xC002004C, "EPT_NT_CANT_CREATE" },
14990   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
14991   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
14992   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
14993   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
14994   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
14995   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
14996   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
14997   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
14998   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
14999   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15000   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15001   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15002   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15003   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15004   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15005   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15006   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15007   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15008   { 0,          NULL }
15009 };
15010
15011
15012
15013 static const true_false_string tfs_smb_flags_lock = {
15014         "Lock&Read, Write&Unlock are supported",
15015         "Lock&Read, Write&Unlock are not supported"
15016 };
15017 static const true_false_string tfs_smb_flags_receive_buffer = {
15018         "Receive buffer has been posted",
15019         "Receive buffer has not been posted"
15020 };
15021 static const true_false_string tfs_smb_flags_caseless = {
15022         "Path names are caseless",
15023         "Path names are case sensitive"
15024 };
15025 static const true_false_string tfs_smb_flags_canon = {
15026         "Pathnames are canonicalized",
15027         "Pathnames are not canonicalized"
15028 };
15029 static const true_false_string tfs_smb_flags_oplock = {
15030         "OpLock requested/granted",
15031         "OpLock not requested/granted"
15032 };
15033 static const true_false_string tfs_smb_flags_notify = {
15034         "Notify client on all modifications",
15035         "Notify client only on open"
15036 };
15037 static const true_false_string tfs_smb_flags_response = {
15038         "Message is a response to the client/redirector",
15039         "Message is a request to the server"
15040 };
15041
15042 static int
15043 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15044 {
15045         guint8 mask;
15046         proto_item *item = NULL;
15047         proto_tree *tree = NULL;
15048
15049         mask = tvb_get_guint8(tvb, offset);
15050
15051         if(parent_tree){
15052                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15053                         "Flags: 0x%02x", mask);
15054                 tree = proto_item_add_subtree(item, ett_smb_flags);
15055         }
15056         proto_tree_add_boolean(tree, hf_smb_flags_response,
15057                 tvb, offset, 1, mask);
15058         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15059                 tvb, offset, 1, mask);
15060         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15061                 tvb, offset, 1, mask);
15062         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15063                 tvb, offset, 1, mask);
15064         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15065                 tvb, offset, 1, mask);
15066         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15067                 tvb, offset, 1, mask);
15068         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15069                 tvb, offset, 1, mask);
15070         offset += 1;
15071         return offset;
15072 }
15073
15074
15075  
15076 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15077         "Long file names are allowed in the response",
15078         "Long file names are not allowed in the response"
15079 };
15080 static const true_false_string tfs_smb_flags2_ea = {
15081         "Extended attributes are supported",
15082         "Extended attributes are not supported"
15083 };
15084 static const true_false_string tfs_smb_flags2_sec_sig = {
15085         "Security signatures are supported",
15086         "Security signatures are not supported"
15087 };
15088 static const true_false_string tfs_smb_flags2_long_names_used = {
15089         "Path names in request are long file names",
15090         "Path names in request are not long file names"
15091 };
15092 static const true_false_string tfs_smb_flags2_esn = {
15093         "Extended security negotiation is supported",
15094         "Extended security negotiation is not supported"
15095 };
15096 static const true_false_string tfs_smb_flags2_dfs = {
15097         "Resolve pathnames with Dfs",
15098         "Don't resolve pathnames with Dfs"
15099 };
15100 static const true_false_string tfs_smb_flags2_roe = {
15101         "Permit reads if execute-only",
15102         "Don't permit reads if execute-only"
15103 };
15104 static const true_false_string tfs_smb_flags2_nt_error = {
15105         "Error codes are NT error codes",
15106         "Error codes are DOS error codes"
15107 };
15108 static const true_false_string tfs_smb_flags2_string = {
15109         "Strings are Unicode",
15110         "Strings are ASCII"
15111 };
15112 static int
15113 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15114 {
15115         guint16 mask;
15116         proto_item *item = NULL;
15117         proto_tree *tree = NULL;
15118
15119         mask = tvb_get_letohs(tvb, offset);
15120
15121         if(parent_tree){
15122                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15123                         "Flags2: 0x%04x", mask);
15124                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15125         }
15126
15127         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15128                 tvb, offset, 2, mask);
15129         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15130                 tvb, offset, 2, mask);
15131         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15132                 tvb, offset, 2, mask);
15133         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15134                 tvb, offset, 2, mask);
15135         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15136                 tvb, offset, 2, mask);
15137         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15138                 tvb, offset, 2, mask);
15139         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15140                 tvb, offset, 2, mask);
15141         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15142                 tvb, offset, 2, mask);
15143         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15144                 tvb, offset, 2, mask);
15145
15146         offset += 2;
15147         return offset;
15148 }
15149
15150
15151
15152 #define SMB_FLAGS_DIRN 0x80
15153
15154
15155 static gboolean
15156 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15157 {
15158         int offset = 0;
15159         proto_item *item = NULL, *hitem = NULL;
15160         proto_tree *tree = NULL, *htree = NULL;
15161         guint8          flags;
15162         guint16         flags2;
15163         smb_info_t      si;
15164         smb_saved_info_t *sip = NULL;
15165         smb_saved_info_key_t key;
15166         smb_saved_info_key_t *new_key;
15167         guint32 nt_status = 0;
15168         guint8 errclass = 0;
15169         guint16 errcode = 0;
15170         guint32 pid_mid;
15171         conversation_t *conversation;
15172
15173         top_tree=parent_tree;
15174
15175         /* must check that this really is a smb packet */
15176         if (!tvb_bytes_exist(tvb, 0, 4))
15177                 return FALSE;
15178
15179         if( (tvb_get_guint8(tvb, 0) != 0xff)
15180             || (tvb_get_guint8(tvb, 1) != 'S')
15181             || (tvb_get_guint8(tvb, 2) != 'M')
15182             || (tvb_get_guint8(tvb, 3) != 'B') ){
15183                 return FALSE;
15184         }
15185          
15186         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15187                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15188         }
15189         if (check_col(pinfo->cinfo, COL_INFO)){
15190                 col_clear(pinfo->cinfo, COL_INFO);
15191         }
15192
15193         /* start off using the local variable, we will allocate a new one if we
15194            need to*/
15195         si.cmd = tvb_get_guint8(tvb, offset+4);
15196         flags = tvb_get_guint8(tvb, offset+9);
15197         si.request = !(flags&SMB_FLAGS_DIRN);
15198         flags2 = tvb_get_letohs(tvb, offset+10);
15199         if(flags2 & 0x8000){
15200                 si.unicode = TRUE; /* Mark them as Unicode */
15201         } else {
15202                 si.unicode = FALSE;
15203         }
15204         si.tid = tvb_get_letohs(tvb, offset+24);
15205         si.pid = tvb_get_letohs(tvb, offset+26);
15206         si.uid = tvb_get_letohs(tvb, offset+28);
15207         si.mid = tvb_get_letohs(tvb, offset+30);
15208         pid_mid = (si.pid << 16) | si.mid;
15209         si.info_level = -1;
15210         si.info_count = -1;
15211
15212         if (parent_tree) {
15213                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
15214                         -1, FALSE);
15215                 tree = proto_item_add_subtree(item, ett_smb);
15216
15217                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
15218                         "SMB Header");
15219
15220                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15221         }
15222
15223         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15224         offset += 4;  /* Skip the marker */
15225
15226         /* find which conversation we are part of and get the tables for that 
15227            conversation*/
15228         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15229                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15230         if(conversation){
15231                 si.ct=conversation_get_proto_data(conversation, proto_smb);
15232         } else {
15233                 /* OK this is a new conversation, we must create it
15234                    and attach appropriate data (matched and unmatched 
15235                    table for this conversation)
15236                 */
15237                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
15238                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15239                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
15240                 conv_tables = g_slist_prepend(conv_tables, si.ct);
15241                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
15242                         smb_saved_info_equal_matched);
15243                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
15244                         smb_saved_info_equal_unmatched);
15245                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
15246                         smb_saved_info_hash_unmatched, 
15247                         smb_saved_info_equal_unmatched);
15248                 si.ct->tid_service=g_hash_table_new(
15249                         smb_saved_info_hash_unmatched, 
15250                         smb_saved_info_equal_unmatched);
15251                 conversation_add_proto_data(conversation, proto_smb, si.ct);
15252         }
15253
15254         if( (si.request)
15255             &&  (si.mid==0)
15256             &&  (si.uid==0)
15257             &&  (si.pid==0)
15258             &&  (si.tid==0) ){
15259                 /* this is a broadcast SMB packet, there will not be a reply.
15260                    We dont need to do anything 
15261                 */
15262                 si.unidir = TRUE;
15263         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15264                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15265                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15266                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15267                 /* Ok, we got a special request type. This request is either
15268                    an NT Cancel or a continuation relative to a real request
15269                    in an earlier packet.  In either case, we don't expect any
15270                    responses to this packet.  For continuations, any later
15271                    responses we see really just belong to the original request.
15272                    Anyway, we want to remember this packet somehow and
15273                    remember which original request it is associated with so
15274                    we can say nice things such as "This is a Cancellation to
15275                    the request in frame x", but we don't want the
15276                    request/response matching to get messed up.
15277
15278                    The only thing we do in this case is trying to find which original
15279                    request we match with and insert an entry for this "special" 
15280                    request for later reference. We continue to reference the original
15281                    requests smb_saved_info_t but we dont touch it or change anything
15282                    in it.
15283                 */
15284
15285                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
15286
15287                 if(!pinfo->fd->flags.visited){
15288                         /* try to find which original call we match and if we 
15289                            find it add us to the matched table. Dont touch
15290                            anything else since we dont want this one to mess
15291                            up the request/response matching. We still consider
15292                            the initial call the real request and this is only
15293                            some sort of continuation.
15294                         */
15295                         /* we only check the unmatched table and assume that the
15296                            last seen MID matching ours is the right one.
15297                            This can fail but is better than nothing
15298                         */
15299                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15300                         if(sip!=NULL){
15301                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15302                                 new_key->frame = pinfo->fd->num;
15303                                 new_key->pid_mid = pid_mid;
15304                                 g_hash_table_insert(si.ct->matched, new_key,
15305                                     sip);
15306                         }
15307                 } else {
15308                         /* we have seen this packet before; check the
15309                            matching table
15310                         */
15311                         key.frame = pinfo->fd->num;
15312                         key.pid_mid = pid_mid;
15313                         sip=g_hash_table_lookup(si.ct->matched, &key);
15314                         if(sip==NULL){
15315                         /*
15316                           We didn't find it.
15317                           Too bad, unfortunately there is not really much we can
15318                           do now since this means that we never saw the initial
15319                           request.
15320                          */
15321                         }
15322                 }
15323
15324
15325                 if(sip && sip->frame_req){
15326                         switch(si.cmd){
15327                         case SMB_COM_NT_CANCEL:
15328                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
15329                                                     tvb, 0, 0, sip->frame_req);
15330                                 break;
15331                         case SMB_COM_TRANSACTION_SECONDARY:
15332                         case SMB_COM_TRANSACTION2_SECONDARY:
15333                         case SMB_COM_NT_TRANSACT_SECONDARY:
15334                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
15335                                                     tvb, 0, 0, sip->frame_req);
15336                                 break;
15337                         }
15338                 } else {
15339                         switch(si.cmd){
15340                         case SMB_COM_NT_CANCEL:
15341                                 proto_tree_add_text(htree, tvb, 0, 0,
15342                                                     "Cancellation to: <unknown frame>");
15343                                 break;
15344                         case SMB_COM_TRANSACTION_SECONDARY:
15345                         case SMB_COM_TRANSACTION2_SECONDARY:
15346                         case SMB_COM_NT_TRANSACT_SECONDARY:
15347                                 proto_tree_add_text(htree, tvb, 0, 0,
15348                                                     "Continuation to: <unknown frame>");
15349                                 break;
15350                         }
15351                 }
15352         } else { /* normal bidirectional request or response */
15353                 si.unidir = FALSE;
15354
15355                 if(!pinfo->fd->flags.visited){
15356                         /* first see if we find an unmatched smb "equal" to 
15357                            the current one 
15358                         */
15359                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15360                         if(sip!=NULL){
15361                                 gboolean cmd_match=FALSE;
15362
15363                                 /*
15364                                  * Make sure the SMB we found was the
15365                                  * same command, or a different command
15366                                  * that's another valid type of reply
15367                                  * to that command.
15368                                  */
15369                                 if(si.cmd==sip->cmd){
15370                                         cmd_match=TRUE;
15371                                 }
15372                                 else if(si.cmd==SMB_COM_NT_CANCEL){
15373                                         cmd_match=TRUE;
15374                                 }
15375                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
15376                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15377                                         cmd_match=TRUE;
15378                                 }
15379                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
15380                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15381                                         cmd_match=TRUE;
15382                                 }
15383                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
15384                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15385                                         cmd_match=TRUE;
15386                                 }
15387
15388                                 if( (si.request) || (!cmd_match) ) {
15389                                         /* If we are processing an SMB request but there was already
15390                                            another "identical" smb resuest we had not matched yet.
15391                                            This must mean that either we have a retransmission or that the
15392                                            response to the previous one was lost and the client has reused
15393                                            the MID for this conversation. In either case it's not much more
15394                                            we can do than forget the old request and concentrate on the 
15395                                            present one instead.
15396
15397                                            We also do this cleanup if we see that the cmd in the original
15398                                            request in sip->cmd is not compatible with the current cmd.
15399                                            This is to prevent matching errors such as if there were two
15400                                            SMBs of different cmds but with identical MID and PID values and
15401                                            if ethereal lost the first reply and the second request.
15402                                         */
15403                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
15404                                         sip=NULL; /* XXX should free it as well */
15405                                 } else {
15406                                         /* we have found a response to some request we have seen earlier.
15407                                            What we do now depends on whether this is the first response
15408                                            to that request we see (id frame_res==0) or not. 
15409                                         */
15410                                         if(sip->frame_res==0){
15411                                                 /* ok it is the first response we have seen to this packet */
15412                                                 sip->frame_res = pinfo->fd->num;
15413                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15414                                                 new_key->frame = sip->frame_res;
15415                                                 new_key->pid_mid = pid_mid;
15416                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15417                                         } else {
15418                                                 /* we have already seen another response to this one, but
15419                                                    register it anyway so we see which request it matches 
15420                                                 */
15421                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15422                                                 new_key->frame = pinfo->fd->num;
15423                                                 new_key->pid_mid = pid_mid;
15424                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15425                                         }
15426                                 }
15427                         }
15428                         if(si.request){
15429                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
15430                                 sip->frame_req = pinfo->fd->num;
15431                                 sip->frame_res = 0;
15432                                 sip->flags = 0;
15433                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
15434                                     == (void *)TID_IPC) {
15435                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15436                                 }
15437                                 sip->cmd = si.cmd;
15438                                 sip->extra_info = NULL;
15439                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
15440                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15441                                 new_key->frame = sip->frame_req;
15442                                 new_key->pid_mid = pid_mid;
15443                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15444                         }
15445                 } else {
15446                         /* we have seen this packet before; check the
15447                            matching table.
15448                            If we haven't yet seen the reply, we won't
15449                            find the info for it; we don't need it, as
15450                            we only use it to save information, and, as
15451                            we've seen this packet before, we've already
15452                            saved the information.
15453                         */
15454                         key.frame = pinfo->fd->num;
15455                         key.pid_mid = pid_mid;
15456                         sip=g_hash_table_lookup(si.ct->matched, &key);
15457                 }
15458         }
15459
15460         /*
15461          * Pass the "sip" on to subdissectors through "si".
15462          */
15463         si.sip = sip;
15464
15465         if (sip != NULL) {
15466                 /*
15467                  * Put in fields for the frame number of the frame to which
15468                  * this is a response or the frame with the response to this
15469                  * frame - if we know the frame number (i.e., it's not 0).
15470                  */
15471                 if(si.request){
15472                         if (sip->frame_res != 0)
15473                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15474                 } else {
15475                         if (sip->frame_req != 0)
15476                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
15477                 }
15478         }
15479
15480         /* smb command */
15481         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);
15482         offset += 1;
15483
15484         if(flags2 & 0x4000){
15485                 /* handle NT 32 bit error code */
15486
15487                 nt_status = tvb_get_letohl(tvb, offset);
15488
15489                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
15490                         TRUE);
15491                 offset += 4;
15492
15493         } else {
15494                 /* handle DOS error code & class */
15495                 errclass = tvb_get_guint8(tvb, offset);
15496                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
15497                         errclass);
15498                 offset += 1;
15499
15500                 /* reserved byte */
15501                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
15502                 offset += 1;
15503
15504                 /* error code */
15505                 /* XXX - the type of this field depends on the value of
15506                  * "errcls", so there is isn't a single value_string array
15507                  * fo it, so there can't be a single field for it.
15508                  */
15509                 errcode = tvb_get_letohs(tvb, offset);
15510                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
15511                         offset, 2, errcode, "Error Code: %s",
15512                         decode_smb_error(errclass, errcode));
15513                 offset += 2;
15514         }
15515
15516         /* flags */
15517         offset = dissect_smb_flags(tvb, htree, offset);
15518
15519         /* flags2 */
15520         offset = dissect_smb_flags2(tvb, htree, offset);
15521
15522         /*
15523          * The document at
15524          *
15525          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
15526          *
15527          * (a text version of "Microsoft Networks SMB FILE SHARING
15528          * PROTOCOL, Document Version 6.0p") says that:
15529          *
15530          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
15531          *      the "High Part of PID";
15532          *
15533          *      the next four bytes are reserved;
15534          *
15535          *      the next four bytes are, for SMB-over-IPX (with no
15536          *      NetBIOS involved) two bytes of Session ID and two bytes
15537          *      of SequenceNumber.
15538          *
15539          * If we ever implement SMB-over-IPX (which I suspect goes over
15540          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
15541          * document in question), we'd probably want to have some way
15542          * to determine whether this is SMB-over-IPX or not (which could
15543          * be done by adding a PT_IPXSOCKET port type, having the
15544          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
15545          * and having the SMB dissector check for a port type of
15546          * PT_IPXSOCKET and for "pinfo->match_port" being either
15547          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
15548          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
15549          */
15550
15551         /* 12 reserved bytes */
15552         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
15553         offset += 12;
15554
15555         /* TID */
15556         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
15557         offset += 2;
15558
15559         /* PID */
15560         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
15561         offset += 2;
15562
15563         /* UID */
15564         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
15565         offset += 2;
15566
15567         /* MID */
15568         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
15569         offset += 2;
15570
15571         pinfo->private_data = &si;
15572         dissect_smb_command(tvb, pinfo, offset, tree, si.cmd);
15573
15574         /* Append error info from this packet to info string. */
15575         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
15576                 if (flags2 & 0x4000) {
15577                         /*
15578                          * The status is an NT status code; was there
15579                          * an error?
15580                          */
15581                         if (nt_status != 0) {
15582                                 /*
15583                                  * Yes.
15584                                  */
15585                                 col_append_fstr(
15586                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15587                                         val_to_str(nt_status, NT_errors,
15588                                             "Unknown (0x%08X)"));
15589                         }
15590                 } else {
15591                         /*
15592                          * The status is a DOS error class and code; was
15593                          * there an error?
15594                          */
15595                         if (errclass != SMB_SUCCESS) {
15596                                 /*
15597                                  * Yes.
15598                                  */
15599                                 col_append_fstr(
15600                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15601                                         decode_smb_error(errclass, errcode));
15602                         }
15603                 }
15604         }
15605
15606         return TRUE;
15607 }
15608
15609 void
15610 proto_register_smb(void)
15611 {
15612         static hf_register_info hf[] = {
15613         { &hf_smb_cmd,
15614                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
15615                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
15616
15617         { &hf_smb_word_count,
15618                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
15619                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
15620
15621         { &hf_smb_byte_count,
15622                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
15623                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
15624
15625         { &hf_smb_response_to,
15626                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
15627                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
15628
15629         { &hf_smb_response_in,
15630                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
15631                 NULL, 0, "The response to this packet is in this packet", HFILL }},
15632
15633         { &hf_smb_continuation_to,
15634                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
15635                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
15636
15637         { &hf_smb_nt_status,
15638                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
15639                 VALS(NT_errors), 0, "NT Status code", HFILL }},
15640
15641         { &hf_smb_error_class,
15642                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
15643                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
15644
15645         { &hf_smb_error_code,
15646                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
15647                 NULL, 0, "DOS Error Code", HFILL }},
15648
15649         { &hf_smb_reserved,
15650                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
15651                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
15652
15653         { &hf_smb_pid,
15654                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
15655                 NULL, 0, "Process ID", HFILL }},
15656
15657         { &hf_smb_tid,
15658                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
15659                 NULL, 0, "Tree ID", HFILL }},
15660
15661         { &hf_smb_uid,
15662                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
15663                 NULL, 0, "User ID", HFILL }},
15664
15665         { &hf_smb_mid,
15666                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
15667                 NULL, 0, "Multiplex ID", HFILL }},
15668
15669         { &hf_smb_flags_lock,
15670                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
15671                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
15672
15673         { &hf_smb_flags_receive_buffer,
15674                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
15675                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
15676
15677         { &hf_smb_flags_caseless,
15678                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
15679                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
15680
15681         { &hf_smb_flags_canon,
15682                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
15683                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
15684
15685         { &hf_smb_flags_oplock,
15686                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
15687                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
15688
15689         { &hf_smb_flags_notify,
15690                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
15691                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
15692
15693         { &hf_smb_flags_response,
15694                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
15695                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
15696
15697         { &hf_smb_flags2_long_names_allowed,
15698                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
15699                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
15700
15701         { &hf_smb_flags2_ea,
15702                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
15703                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
15704
15705         { &hf_smb_flags2_sec_sig,
15706                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
15707                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
15708
15709         { &hf_smb_flags2_long_names_used,
15710                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
15711                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
15712
15713         { &hf_smb_flags2_esn,
15714                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
15715                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
15716
15717         { &hf_smb_flags2_dfs,
15718                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
15719                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
15720
15721         { &hf_smb_flags2_roe,
15722                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
15723                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
15724
15725         { &hf_smb_flags2_nt_error,
15726                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
15727                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
15728
15729         { &hf_smb_flags2_string,
15730                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
15731                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
15732
15733         { &hf_smb_buffer_format,
15734                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
15735                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
15736
15737         { &hf_smb_dialect_name,
15738                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
15739                 NULL, 0, "Name of dialect", HFILL }},
15740
15741         { &hf_smb_dialect_index,
15742                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
15743                 NULL, 0, "Index of selected dialect", HFILL }},
15744
15745         { &hf_smb_max_trans_buf_size,
15746                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
15747                 NULL, 0, "Maximum transmit buffer size", HFILL }},
15748
15749         { &hf_smb_max_mpx_count,
15750                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
15751                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
15752
15753         { &hf_smb_max_vcs_num,
15754                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
15755                 NULL, 0, "Maximum VCs between client and server", HFILL }},
15756
15757         { &hf_smb_session_key,
15758                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
15759                 NULL, 0, "Unique token identifying this session", HFILL }},
15760
15761         { &hf_smb_server_timezone,
15762                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
15763                 NULL, 0, "Current timezone at server.", HFILL }},
15764
15765         { &hf_smb_encryption_key_length,
15766                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
15767                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
15768
15769         { &hf_smb_encryption_key,
15770                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
15771                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
15772
15773         { &hf_smb_primary_domain,
15774                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
15775                 NULL, 0, "The server's primary domain", HFILL }},
15776
15777         { &hf_smb_max_raw_buf_size,
15778                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
15779                 NULL, 0, "Maximum raw buffer size", HFILL }},
15780
15781         { &hf_smb_server_guid,
15782                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
15783                 NULL, 0, "Globally unique identifier for this server", HFILL }},
15784
15785         { &hf_smb_security_blob_len,
15786                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
15787                 NULL, 0, "Security blob length", HFILL }},
15788
15789         { &hf_smb_security_blob,
15790                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
15791                 NULL, 0, "Security blob", HFILL }},
15792
15793         { &hf_smb_sm_mode16,
15794                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
15795                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15796
15797         { &hf_smb_sm_password16,
15798                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
15799                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15800
15801         { &hf_smb_sm_mode,
15802                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
15803                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15804
15805         { &hf_smb_sm_password,
15806                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
15807                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15808
15809         { &hf_smb_sm_signatures,
15810                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
15811                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
15812
15813         { &hf_smb_sm_sig_required,
15814                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
15815                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
15816
15817         { &hf_smb_rm_read,
15818                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
15819                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
15820
15821         { &hf_smb_rm_write,
15822                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
15823                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
15824
15825         { &hf_smb_server_date_time,
15826                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
15827                 NULL, 0, "Current date and time at server", HFILL }},
15828
15829         { &hf_smb_server_smb_date,
15830                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
15831                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
15832
15833         { &hf_smb_server_smb_time,
15834                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
15835                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
15836
15837         { &hf_smb_server_cap_raw_mode,
15838                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
15839                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
15840
15841         { &hf_smb_server_cap_mpx_mode,
15842                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
15843                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
15844
15845         { &hf_smb_server_cap_unicode,
15846                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
15847                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
15848
15849         { &hf_smb_server_cap_large_files,
15850                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
15851                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
15852
15853         { &hf_smb_server_cap_nt_smbs,
15854                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
15855                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
15856
15857         { &hf_smb_server_cap_rpc_remote_apis,
15858                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
15859                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
15860
15861         { &hf_smb_server_cap_nt_status,
15862                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
15863                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
15864
15865         { &hf_smb_server_cap_level_ii_oplocks,
15866                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
15867                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
15868
15869         { &hf_smb_server_cap_lock_and_read,
15870                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
15871                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
15872
15873         { &hf_smb_server_cap_nt_find,
15874                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
15875                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15876
15877         { &hf_smb_server_cap_dfs,
15878                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15879                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15880
15881         { &hf_smb_server_cap_infolevel_passthru,
15882                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15883                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15884
15885         { &hf_smb_server_cap_large_readx,
15886                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15887                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15888
15889         { &hf_smb_server_cap_large_writex,
15890                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15891                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15892
15893         { &hf_smb_server_cap_unix,
15894                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15895                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15896
15897         { &hf_smb_server_cap_reserved,
15898                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15899                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15900
15901         { &hf_smb_server_cap_bulk_transfer,
15902                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15903                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15904
15905         { &hf_smb_server_cap_compressed_data,
15906                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15907                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15908
15909         { &hf_smb_server_cap_extended_security,
15910                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
15911                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
15912
15913         { &hf_smb_system_time,
15914                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
15915                 NULL, 0, "System Time", HFILL }},
15916
15917         { &hf_smb_unknown,
15918                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
15919                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
15920
15921         { &hf_smb_dir_name,
15922                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
15923                 NULL, 0, "SMB Directory Name", HFILL }},
15924
15925         { &hf_smb_echo_count,
15926                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
15927                 NULL, 0, "Number of times to echo data back", HFILL }},
15928
15929         { &hf_smb_echo_data,
15930                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
15931                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
15932
15933         { &hf_smb_echo_seq_num,
15934                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
15935                 NULL, 0, "Sequence number for this echo response", HFILL }},
15936
15937         { &hf_smb_max_buf_size,
15938                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
15939                 NULL, 0, "Max client buffer size", HFILL }},
15940
15941         { &hf_smb_path,
15942                 { "Path", "smb.path", FT_STRING, BASE_NONE,
15943                 NULL, 0, "Path. Server name and share name", HFILL }},
15944
15945         { &hf_smb_service,
15946                 { "Service", "smb.service", FT_STRING, BASE_NONE,
15947                 NULL, 0, "Service name", HFILL }},
15948
15949         { &hf_smb_password,
15950                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15951                 NULL, 0, "Password", HFILL }},
15952
15953         { &hf_smb_ansi_password,
15954                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15955                 NULL, 0, "ANSI Password", HFILL }},
15956
15957         { &hf_smb_unicode_password,
15958                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15959                 NULL, 0, "Unicode Password", HFILL }},
15960
15961         { &hf_smb_move_flags_file,
15962                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15963                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15964
15965         { &hf_smb_move_flags_dir,
15966                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15967                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15968
15969         { &hf_smb_move_flags_verify,
15970                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15971                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15972
15973         { &hf_smb_files_moved,
15974                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
15975                 NULL, 0, "Number of files moved", HFILL }},
15976
15977         { &hf_smb_copy_flags_file,
15978                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
15979                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15980
15981         { &hf_smb_copy_flags_dir,
15982                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
15983                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15984
15985         { &hf_smb_copy_flags_dest_mode,
15986                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
15987                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
15988
15989         { &hf_smb_copy_flags_source_mode,
15990                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
15991                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
15992
15993         { &hf_smb_copy_flags_verify,
15994                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
15995                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15996
15997         { &hf_smb_copy_flags_tree_copy,
15998                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
15999                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16000
16001         { &hf_smb_copy_flags_ea_action,
16002                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16003                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16004
16005         { &hf_smb_count,
16006                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16007                 NULL, 0, "Count number of items/bytes", HFILL }},
16008
16009         { &hf_smb_file_name,
16010                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16011                 NULL, 0, "File Name", HFILL }},
16012
16013         { &hf_smb_open_function_create,
16014                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16015                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16016
16017         { &hf_smb_open_function_open,
16018                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16019                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16020
16021         { &hf_smb_fid,
16022                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16023                 NULL, 0, "FID: File ID", HFILL }},
16024
16025         { &hf_smb_file_attr_read_only_16bit,
16026                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16027                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16028
16029         { &hf_smb_file_attr_read_only_8bit,
16030                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16031                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16032
16033         { &hf_smb_file_attr_hidden_16bit,
16034                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16035                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16036
16037         { &hf_smb_file_attr_hidden_8bit,
16038                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16039                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16040
16041         { &hf_smb_file_attr_system_16bit,
16042                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16043                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16044
16045         { &hf_smb_file_attr_system_8bit,
16046                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16047                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16048
16049         { &hf_smb_file_attr_volume_16bit,
16050                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16051                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16052
16053         { &hf_smb_file_attr_volume_8bit,
16054                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16055                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16056
16057         { &hf_smb_file_attr_directory_16bit,
16058                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16059                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16060
16061         { &hf_smb_file_attr_directory_8bit,
16062                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16063                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16064
16065         { &hf_smb_file_attr_archive_16bit,
16066                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16067                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16068
16069         { &hf_smb_file_attr_archive_8bit,
16070                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16071                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16072
16073         { &hf_smb_file_attr_device,
16074                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16075                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16076
16077         { &hf_smb_file_attr_normal,
16078                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16079                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16080
16081         { &hf_smb_file_attr_temporary,
16082                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16083                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16084
16085         { &hf_smb_file_attr_sparse,
16086                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16087                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16088
16089         { &hf_smb_file_attr_reparse,
16090                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16091                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16092
16093         { &hf_smb_file_attr_compressed,
16094                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16095                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16096
16097         { &hf_smb_file_attr_offline,
16098                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16099                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16100
16101         { &hf_smb_file_attr_not_content_indexed,
16102                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16103                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16104
16105         { &hf_smb_file_attr_encrypted,
16106                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16107                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16108
16109         { &hf_smb_file_size,
16110                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16111                 NULL, 0, "File Size", HFILL }},
16112
16113         { &hf_smb_search_attribute_read_only,
16114                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16115                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16116
16117         { &hf_smb_search_attribute_hidden,
16118                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16119                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16120
16121         { &hf_smb_search_attribute_system,
16122                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16123                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16124
16125         { &hf_smb_search_attribute_volume,
16126                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16127                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16128
16129         { &hf_smb_search_attribute_directory,
16130                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16131                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16132
16133         { &hf_smb_search_attribute_archive,
16134                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16135                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16136
16137         { &hf_smb_access_mode,
16138                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16139                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16140
16141         { &hf_smb_access_sharing,
16142                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16143                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16144
16145         { &hf_smb_access_locality,
16146                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16147                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16148
16149         { &hf_smb_access_caching,
16150                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16151                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16152
16153         { &hf_smb_access_writetru,
16154                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16155                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16156
16157         { &hf_smb_create_time,
16158                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16159                 NULL, 0, "Creation Time", HFILL }},
16160
16161         { &hf_smb_create_dos_date,
16162                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16163                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16164
16165         { &hf_smb_create_dos_time,
16166                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16167                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16168
16169         { &hf_smb_last_write_time,
16170                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16171                 NULL, 0, "Time this file was last written to", HFILL }},
16172
16173         { &hf_smb_last_write_dos_date,
16174                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16175                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16176
16177         { &hf_smb_last_write_dos_time,
16178                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16179                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16180
16181         { &hf_smb_old_file_name,
16182                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
16183                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16184
16185         { &hf_smb_offset,
16186                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16187                 NULL, 0, "Offset in file", HFILL }},
16188
16189         { &hf_smb_remaining,
16190                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16191                 NULL, 0, "Remaining number of bytes", HFILL }},
16192
16193         { &hf_smb_padding,
16194                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16195                 NULL, 0, "Padding or unknown data", HFILL }},
16196
16197         { &hf_smb_file_data,
16198                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16199                 NULL, 0, "Data read/written to the file", HFILL }},
16200
16201         { &hf_smb_total_data_len,
16202                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16203                 NULL, 0, "Total length of data", HFILL }},
16204
16205         { &hf_smb_data_len,
16206                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16207                 NULL, 0, "Length of data", HFILL }},
16208
16209         { &hf_smb_seek_mode,
16210                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16211                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16212
16213         { &hf_smb_access_time,
16214                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16215                 NULL, 0, "Last Access Time", HFILL }},
16216
16217         { &hf_smb_access_dos_date,
16218                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16219                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16220
16221         { &hf_smb_access_dos_time,
16222                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16223                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16224
16225         { &hf_smb_data_size,
16226                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16227                 NULL, 0, "Data Size", HFILL }},
16228
16229         { &hf_smb_alloc_size,
16230                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16231                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16232
16233         { &hf_smb_max_count,
16234                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16235                 NULL, 0, "Maximum Count", HFILL }},
16236
16237         { &hf_smb_min_count,
16238                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16239                 NULL, 0, "Minimum Count", HFILL }},
16240
16241         { &hf_smb_timeout,
16242                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16243                 NULL, 0, "Timeout in miliseconds", HFILL }},
16244
16245         { &hf_smb_high_offset,
16246                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16247                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16248
16249         { &hf_smb_units,
16250                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16251                 NULL, 0, "Total number of units at server", HFILL }},
16252
16253         { &hf_smb_bpu,
16254                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16255                 NULL, 0, "Blocks per unit at server", HFILL }},
16256
16257         { &hf_smb_blocksize,
16258                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16259                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16260
16261         { &hf_smb_freeunits,
16262                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16263                 NULL, 0, "Number of free units at server", HFILL }},
16264
16265         { &hf_smb_data_offset,
16266                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16267                 NULL, 0, "Data Offset", HFILL }},
16268
16269         { &hf_smb_dcm,
16270                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16271                 NULL, 0, "Data Compaction Mode", HFILL }},
16272
16273         { &hf_smb_request_mask,
16274                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
16275                 NULL, 0, "Connectionless mode mask", HFILL }},
16276
16277         { &hf_smb_response_mask,
16278                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
16279                 NULL, 0, "Connectionless mode mask", HFILL }},
16280
16281         { &hf_smb_sid,
16282                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
16283                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
16284
16285         { &hf_smb_write_mode_write_through,
16286                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
16287                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
16288
16289         { &hf_smb_write_mode_return_remaining,
16290                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
16291                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
16292
16293         { &hf_smb_write_mode_raw,
16294                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
16295                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
16296
16297         { &hf_smb_write_mode_message_start,
16298                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
16299                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
16300
16301         { &hf_smb_write_mode_connectionless,
16302                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
16303                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
16304
16305         { &hf_smb_resume_key_len,
16306                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
16307                 NULL, 0, "Resume Key length", HFILL }},
16308
16309         { &hf_smb_resume_find_id,
16310                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
16311                 NULL, 0, "Handle for Find operation", HFILL }},
16312
16313         { &hf_smb_resume_server_cookie,
16314                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
16315                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
16316
16317         { &hf_smb_resume_client_cookie,
16318                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
16319                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
16320
16321         { &hf_smb_andxoffset,
16322                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
16323                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
16324
16325         { &hf_smb_lock_type_large,
16326                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
16327                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
16328
16329         { &hf_smb_lock_type_cancel,
16330                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
16331                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
16332
16333         { &hf_smb_lock_type_change,
16334                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
16335                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
16336
16337         { &hf_smb_lock_type_oplock,
16338                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
16339                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
16340
16341         { &hf_smb_lock_type_shared,
16342                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
16343                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
16344
16345         { &hf_smb_locking_ol,
16346                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
16347                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
16348
16349         { &hf_smb_number_of_locks,
16350                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
16351                 NULL, 0, "Number of lock requests in this request", HFILL }},
16352
16353         { &hf_smb_number_of_unlocks,
16354                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
16355                 NULL, 0, "Number of unlock requests in this request", HFILL }},
16356
16357         { &hf_smb_lock_long_length,
16358                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
16359                 NULL, 0, "Length of lock/unlock region", HFILL }},
16360
16361         { &hf_smb_lock_long_offset,
16362                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
16363                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
16364
16365         { &hf_smb_file_type,
16366                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
16367                 VALS(filetype_vals), 0, "Type of file", HFILL }},
16368
16369         { &hf_smb_ipc_state_nonblocking,
16370                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
16371                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
16372
16373         { &hf_smb_ipc_state_endpoint,
16374                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
16375                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
16376
16377         { &hf_smb_ipc_state_pipe_type,
16378                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
16379                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
16380
16381         { &hf_smb_ipc_state_read_mode,
16382                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
16383                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
16384
16385         { &hf_smb_ipc_state_icount,
16386                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
16387                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
16388
16389         { &hf_smb_server_fid,
16390                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
16391                 NULL, 0, "Server unique File ID", HFILL }},
16392
16393         { &hf_smb_open_flags_add_info,
16394                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
16395                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
16396
16397         { &hf_smb_open_flags_ex_oplock,
16398                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
16399                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
16400
16401         { &hf_smb_open_flags_batch_oplock,
16402                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
16403                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
16404
16405         { &hf_smb_open_flags_ealen,
16406                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
16407                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
16408
16409         { &hf_smb_open_action_open,
16410                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
16411                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
16412
16413         { &hf_smb_open_action_lock,
16414                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
16415                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
16416
16417         { &hf_smb_vc_num,
16418                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
16419                 NULL, 0, "VC Number", HFILL }},
16420
16421         { &hf_smb_password_len,
16422                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
16423                 NULL, 0, "Length of password", HFILL }},
16424
16425         { &hf_smb_ansi_password_len,
16426                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
16427                 NULL, 0, "Length of ANSI password", HFILL }},
16428
16429         { &hf_smb_unicode_password_len,
16430                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
16431                 NULL, 0, "Length of Unicode password", HFILL }},
16432
16433         { &hf_smb_account,
16434                 { "Account", "smb.account", FT_STRING, BASE_NONE,
16435                 NULL, 0, "Account, username", HFILL }},
16436
16437         { &hf_smb_os,
16438                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
16439                 NULL, 0, "Which OS we are running", HFILL }},
16440
16441         { &hf_smb_lanman,
16442                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
16443                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
16444
16445         { &hf_smb_setup_action_guest,
16446                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
16447                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
16448
16449         { &hf_smb_fs,
16450                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
16451                 NULL, 0, "Native File System", HFILL }},
16452
16453         { &hf_smb_connect_flags_dtid,
16454                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
16455                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
16456
16457         { &hf_smb_connect_support_search,
16458                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
16459                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
16460
16461         { &hf_smb_connect_support_in_dfs,
16462                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
16463                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
16464
16465         { &hf_smb_max_setup_count,
16466                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
16467                 NULL, 0, "Maximum number of setup words to return", HFILL }},
16468
16469         { &hf_smb_total_param_count,
16470                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
16471                 NULL, 0, "Total number of parameter bytes", HFILL }},
16472
16473         { &hf_smb_total_data_count,
16474                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
16475                 NULL, 0, "Total number of data bytes", HFILL }},
16476
16477         { &hf_smb_max_param_count,
16478                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
16479                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
16480
16481         { &hf_smb_max_data_count,
16482                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
16483                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
16484
16485         { &hf_smb_param_disp16,
16486                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
16487                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16488
16489         { &hf_smb_param_count16,
16490                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
16491                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16492
16493         { &hf_smb_param_offset16,
16494                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
16495                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16496
16497         { &hf_smb_param_disp32,
16498                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
16499                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16500
16501         { &hf_smb_param_count32,
16502                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
16503                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16504
16505         { &hf_smb_param_offset32,
16506                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
16507                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16508
16509         { &hf_smb_data_count16,
16510                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
16511                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16512
16513         { &hf_smb_data_disp16,
16514                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
16515                 NULL, 0, "Data Displacement", HFILL }},
16516
16517         { &hf_smb_data_offset16,
16518                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16519                 NULL, 0, "Data Offset", HFILL }},
16520
16521         { &hf_smb_data_count32,
16522                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
16523                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16524
16525         { &hf_smb_data_disp32,
16526                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
16527                 NULL, 0, "Data Displacement", HFILL }},
16528
16529         { &hf_smb_data_offset32,
16530                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
16531                 NULL, 0, "Data Offset", HFILL }},
16532
16533         { &hf_smb_setup_count,
16534                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
16535                 NULL, 0, "Number of setup words in this buffer", HFILL }},
16536
16537         { &hf_smb_nt_trans_subcmd,
16538                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16539                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16540
16541         { &hf_smb_nt_ioctl_function_code,
16542                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
16543                 NULL, 0, "NT IOCTL function code", HFILL }},
16544
16545         { &hf_smb_nt_ioctl_isfsctl,
16546                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
16547                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
16548
16549         { &hf_smb_nt_ioctl_flags_root_handle,
16550                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
16551                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
16552
16553         { &hf_smb_nt_ioctl_data,
16554                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
16555                 NULL, 0, "Data for the IOCTL call", HFILL }},
16556
16557         { &hf_smb_nt_notify_action,
16558                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
16559                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
16560
16561         { &hf_smb_nt_notify_watch_tree,
16562                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
16563                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
16564
16565         { &hf_smb_nt_notify_stream_write,
16566                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
16567                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
16568
16569         { &hf_smb_nt_notify_stream_size,
16570                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
16571                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
16572
16573         { &hf_smb_nt_notify_stream_name,
16574                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
16575                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
16576
16577         { &hf_smb_nt_notify_security,
16578                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
16579                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
16580
16581         { &hf_smb_nt_notify_ea,
16582                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
16583                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
16584
16585         { &hf_smb_nt_notify_creation,
16586                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
16587                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
16588
16589         { &hf_smb_nt_notify_last_access,
16590                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
16591                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
16592
16593         { &hf_smb_nt_notify_last_write,
16594                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
16595                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
16596
16597         { &hf_smb_nt_notify_size,
16598                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
16599                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
16600
16601         { &hf_smb_nt_notify_attributes,
16602                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
16603                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
16604
16605         { &hf_smb_nt_notify_dir_name,
16606                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
16607                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
16608
16609         { &hf_smb_nt_notify_file_name,
16610                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
16611                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
16612
16613         { &hf_smb_root_dir_fid,
16614                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
16615                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
16616
16617         { &hf_smb_alloc_size64,
16618                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
16619                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16620
16621         { &hf_smb_nt_create_disposition,
16622                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
16623                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
16624
16625         { &hf_smb_sd_length,
16626                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
16627                 NULL, 0, "Total length of security descriptor", HFILL }},
16628
16629         { &hf_smb_ea_length,
16630                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
16631                 NULL, 0, "Total EA length for opened file", HFILL }},
16632
16633         { &hf_smb_file_name_len,
16634                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
16635                 NULL, 0, "Length of File Name", HFILL }},
16636
16637         { &hf_smb_nt_impersonation_level,
16638                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
16639                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
16640
16641         { &hf_smb_nt_security_flags_context_tracking,
16642                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
16643                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
16644
16645         { &hf_smb_nt_security_flags_effective_only,
16646                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
16647                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
16648
16649         { &hf_smb_nt_access_mask_generic_read,
16650                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
16651                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
16652
16653         { &hf_smb_nt_access_mask_generic_write,
16654                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
16655                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
16656
16657         { &hf_smb_nt_access_mask_generic_execute,
16658                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
16659                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
16660
16661         { &hf_smb_nt_access_mask_generic_all,
16662                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
16663                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
16664
16665         { &hf_smb_nt_access_mask_maximum_allowed,
16666                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
16667                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
16668
16669         { &hf_smb_nt_access_mask_system_security,
16670                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
16671                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
16672
16673         { &hf_smb_nt_access_mask_synchronize,
16674                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
16675                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
16676
16677         { &hf_smb_nt_access_mask_write_owner,
16678                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
16679                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
16680
16681         { &hf_smb_nt_access_mask_write_dac,
16682                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
16683                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
16684
16685         { &hf_smb_nt_access_mask_read_control,
16686                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
16687                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
16688
16689         { &hf_smb_nt_access_mask_delete,
16690                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
16691                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
16692
16693         { &hf_smb_nt_access_mask_write_attributes,
16694                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
16695                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
16696
16697         { &hf_smb_nt_access_mask_read_attributes,
16698                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
16699                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
16700
16701         { &hf_smb_nt_access_mask_delete_child,
16702                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
16703                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
16704
16705         /*
16706          * "Execute" for files, "traverse" for directories.
16707          */
16708         { &hf_smb_nt_access_mask_execute,
16709                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
16710                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
16711
16712         { &hf_smb_nt_access_mask_write_ea,
16713                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
16714                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
16715
16716         { &hf_smb_nt_access_mask_read_ea,
16717                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
16718                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
16719
16720         /*
16721          * "Append data" for files, "add subdirectory" for directories,
16722          * "create pipe instance" for named pipes.
16723          */
16724         { &hf_smb_nt_access_mask_append,
16725                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
16726                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
16727
16728         /*
16729          * "Write data" for files and pipes, "add file" for directory.
16730          */
16731         { &hf_smb_nt_access_mask_write,
16732                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
16733                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
16734
16735         /*
16736          * "Read data" for files and pipes, "list directory" for directory.
16737          */
16738         { &hf_smb_nt_access_mask_read,
16739                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
16740                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
16741
16742         { &hf_smb_nt_create_bits_oplock,
16743                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
16744                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
16745
16746         { &hf_smb_nt_create_bits_boplock,
16747                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
16748                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
16749
16750         { &hf_smb_nt_create_bits_dir,
16751                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
16752                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
16753
16754         { &hf_smb_nt_create_options_directory_file,
16755                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
16756                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
16757
16758         { &hf_smb_nt_create_options_write_through,
16759                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
16760                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
16761
16762         { &hf_smb_nt_create_options_sequential_only,
16763                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
16764                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
16765
16766         { &hf_smb_nt_create_options_sync_io_alert,
16767                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
16768                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
16769
16770         { &hf_smb_nt_create_options_sync_io_nonalert,
16771                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
16772                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
16773
16774         { &hf_smb_nt_create_options_non_directory_file,
16775                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
16776                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
16777
16778         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
16779            and "NtOpenFile()"; is that sent over the wire?  Network
16780            Monitor thinks so, but its author may just have grabbed
16781            the flag bits from a system header file. */
16782
16783         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
16784            and "NtOpenFile()"; is that sent over the wire?  NetMon
16785            thinks so, but see previous comment. */
16786
16787         { &hf_smb_nt_create_options_no_ea_knowledge,
16788                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
16789                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
16790
16791         { &hf_smb_nt_create_options_eight_dot_three_only,
16792                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
16793                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
16794
16795         { &hf_smb_nt_create_options_random_access,
16796                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
16797                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
16798
16799         { &hf_smb_nt_create_options_delete_on_close,
16800                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
16801                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
16802
16803         /* 0x00002000 is "open by FID", or something such as that (which
16804            I suspect is like "open by inumber" on UNIX), at least in
16805            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
16806            wire?  NetMon thinks so, but see previous comment. */
16807
16808         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
16809            and "NtOpenFile()"; is that sent over the wire?  NetMon
16810            thinks so, but see previous comment. */
16811
16812         { &hf_smb_nt_share_access_read,
16813                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
16814                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
16815
16816         { &hf_smb_nt_share_access_write,
16817                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
16818                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
16819
16820         { &hf_smb_nt_share_access_delete,
16821                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
16822                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
16823
16824         { &hf_smb_file_eattr_read_only,
16825                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
16826                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16827
16828         { &hf_smb_file_eattr_hidden,
16829                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
16830                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16831
16832         { &hf_smb_file_eattr_system,
16833                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
16834                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16835
16836         { &hf_smb_file_eattr_volume,
16837                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
16838                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16839
16840         { &hf_smb_file_eattr_directory,
16841                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
16842                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16843
16844         { &hf_smb_file_eattr_archive,
16845                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
16846                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16847
16848         { &hf_smb_file_eattr_device,
16849                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
16850                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16851
16852         { &hf_smb_file_eattr_normal,
16853                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
16854                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16855
16856         { &hf_smb_file_eattr_temporary,
16857                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
16858                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16859
16860         { &hf_smb_file_eattr_sparse,
16861                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
16862                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16863
16864         { &hf_smb_file_eattr_reparse,
16865                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
16866                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16867
16868         { &hf_smb_file_eattr_compressed,
16869                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
16870                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16871
16872         { &hf_smb_file_eattr_offline,
16873                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
16874                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16875
16876         { &hf_smb_file_eattr_not_content_indexed,
16877                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
16878                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16879
16880         { &hf_smb_file_eattr_encrypted,
16881                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
16882                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16883
16884         { &hf_smb_file_eattr_write_through,
16885                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
16886                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
16887
16888         { &hf_smb_file_eattr_no_buffering,
16889                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
16890                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
16891
16892         { &hf_smb_file_eattr_random_access,
16893                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
16894                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
16895
16896         { &hf_smb_file_eattr_sequential_scan,
16897                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
16898                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
16899
16900         { &hf_smb_file_eattr_delete_on_close,
16901                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
16902                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
16903
16904         { &hf_smb_file_eattr_backup_semantics,
16905                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
16906                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
16907
16908         { &hf_smb_file_eattr_posix_semantics,
16909                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
16910                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
16911
16912         { &hf_smb_sec_desc_len,
16913                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
16914                 NULL, 0, "Security Descriptor Length", HFILL }},
16915
16916         { &hf_smb_nt_qsd_owner,
16917                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
16918                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
16919
16920         { &hf_smb_nt_qsd_group,
16921                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
16922                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
16923
16924         { &hf_smb_nt_qsd_dacl,
16925                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
16926                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
16927
16928         { &hf_smb_nt_qsd_sacl,
16929                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
16930                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
16931
16932         { &hf_smb_extended_attributes,
16933                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
16934                 NULL, 0, "Extended Attributes", HFILL }},
16935
16936         { &hf_smb_oplock_level,
16937                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
16938                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
16939
16940         { &hf_smb_create_action,
16941                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
16942                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
16943
16944         { &hf_smb_file_id,
16945                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
16946                 NULL, 0, "Server unique file ID", HFILL }},
16947
16948         { &hf_smb_ea_error_offset,
16949                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
16950                 NULL, 0, "Offset into EA list if EA error", HFILL }},
16951
16952         { &hf_smb_end_of_file,
16953                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
16954                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
16955
16956         { &hf_smb_device_type,
16957                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
16958                 VALS(device_type_vals), 0, "Type of device", HFILL }},
16959
16960         { &hf_smb_is_directory,
16961                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
16962                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
16963
16964         { &hf_smb_next_entry_offset,
16965                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
16966                 NULL, 0, "Offset to next entry", HFILL }},
16967
16968         { &hf_smb_change_time,
16969                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
16970                 NULL, 0, "Last Change Time", HFILL }},
16971
16972         { &hf_smb_setup_len,
16973                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
16974                 NULL, 0, "Length of printer setup data", HFILL }},
16975
16976         { &hf_smb_print_mode,
16977                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
16978                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
16979
16980         { &hf_smb_print_identifier,
16981                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
16982                 NULL, 0, "Identifier string for this print job", HFILL }},
16983
16984         { &hf_smb_restart_index,
16985                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16986                 NULL, 0, "Index of entry after last returned", HFILL }},
16987
16988         { &hf_smb_print_queue_date,
16989                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16990                 NULL, 0, "Date when this entry was queued", HFILL }},
16991
16992         { &hf_smb_print_queue_dos_date,
16993                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16994                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16995
16996         { &hf_smb_print_queue_dos_time,
16997                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
16998                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
16999
17000         { &hf_smb_print_status,
17001                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17002                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17003
17004         { &hf_smb_print_spool_file_number,
17005                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17006                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17007
17008         { &hf_smb_print_spool_file_size,
17009                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17010                 NULL, 0, "Number of bytes in spool file", HFILL }},
17011
17012         { &hf_smb_print_spool_file_name,
17013                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17014                 NULL, 0, "Name of client that submitted this job", HFILL }},
17015
17016         { &hf_smb_start_index,
17017                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17018                 NULL, 0, "First queue entry to return", HFILL }},
17019
17020         { &hf_smb_originator_name,
17021                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17022                 NULL, 0, "Name of sender of message", HFILL }},
17023
17024         { &hf_smb_destination_name,
17025                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17026                 NULL, 0, "Name of recipient of message", HFILL }},
17027
17028         { &hf_smb_message_len,
17029                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17030                 NULL, 0, "Length of message", HFILL }},
17031
17032         { &hf_smb_message,
17033                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17034                 NULL, 0, "Message text", HFILL }},
17035
17036         { &hf_smb_mgid,
17037                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17038                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17039
17040         { &hf_smb_forwarded_name,
17041                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17042                 NULL, 0, "Recipient name being forwarded", HFILL }},
17043
17044         { &hf_smb_machine_name,
17045                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17046                 NULL, 0, "Name of target machine", HFILL }},
17047
17048         { &hf_smb_cancel_to,
17049                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
17050                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17051
17052         { &hf_smb_trans2_subcmd,
17053                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17054                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17055
17056         { &hf_smb_trans_name,
17057                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17058                 NULL, 0, "Name of transaction", HFILL }},
17059
17060         { &hf_smb_transaction_flags_dtid,
17061                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17062                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17063
17064         { &hf_smb_transaction_flags_owt,
17065                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17066                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17067
17068         { &hf_smb_search_count,
17069                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17070                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17071
17072         { &hf_smb_search_pattern,
17073                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17074                 NULL, 0, "Search Pattern", HFILL }},
17075
17076         { &hf_smb_ff2_backup,
17077                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17078                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17079
17080         { &hf_smb_ff2_continue,
17081                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17082                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17083
17084         { &hf_smb_ff2_resume,
17085                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17086                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17087
17088         { &hf_smb_ff2_close_eos,
17089                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17090                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17091
17092         { &hf_smb_ff2_close,
17093                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17094                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17095
17096         { &hf_smb_ff2_information_level,
17097                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17098                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17099
17100         { &hf_smb_qpi_loi,
17101                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
17102                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
17103
17104 #if 0
17105         { &hf_smb_sfi_writetru,
17106                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17107                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17108
17109         { &hf_smb_sfi_caching,
17110                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17111                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17112 #endif
17113
17114         { &hf_smb_storage_type,
17115                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17116                 NULL, 0, "Type of storage", HFILL }},
17117
17118         { &hf_smb_resume,
17119                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17120                 NULL, 0, "Resume Key", HFILL }},
17121
17122         { &hf_smb_max_referral_level,
17123                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17124                 NULL, 0, "Latest referral version number understood", HFILL }},
17125
17126         { &hf_smb_qfsi_information_level,
17127                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
17128                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17129
17130         { &hf_smb_nt_rename_level,
17131                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17132                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17133
17134         { &hf_smb_cluster_count,
17135                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17136                 NULL, 0, "Number of clusters", HFILL }},
17137
17138         { &hf_smb_ea_size,
17139                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
17140                 NULL, 0, "Size of file's EA information", HFILL }},
17141
17142         { &hf_smb_list_length,
17143                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
17144                 NULL, 0, "Length of the remaining data", HFILL }},
17145
17146         { &hf_smb_number_of_links,
17147                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17148                 NULL, 0, "Number of hard links to the file", HFILL }},
17149
17150         { &hf_smb_delete_pending,
17151                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17152                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17153
17154         { &hf_smb_index_number,
17155                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17156                 NULL, 0, "File system unique identifier", HFILL }},
17157
17158         { &hf_smb_current_offset,
17159                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17160                 NULL, 0, "Current offset in the file", HFILL }},
17161
17162         { &hf_smb_t2_alignment,
17163                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17164                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17165
17166         { &hf_smb_t2_stream_name_length,
17167                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17168                 NULL, 0, "Length of stream name", HFILL }},
17169
17170         { &hf_smb_t2_stream_size,
17171                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17172                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17173
17174         { &hf_smb_t2_stream_name,
17175                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17176                 NULL, 0, "Name of the stream", HFILL }},
17177
17178         { &hf_smb_t2_compressed_file_size,
17179                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17180                 NULL, 0, "Size of the compressed file", HFILL }},
17181
17182         { &hf_smb_t2_compressed_format,
17183                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17184                 NULL, 0, "Compression algorithm used", HFILL }},
17185
17186         { &hf_smb_t2_compressed_unit_shift,
17187                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17188                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17189
17190         { &hf_smb_t2_compressed_chunk_shift,
17191                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17192                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17193
17194         { &hf_smb_t2_compressed_cluster_shift,
17195                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17196                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17197
17198         { &hf_smb_dfs_path_consumed,
17199                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17200                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17201
17202         { &hf_smb_dfs_num_referrals,
17203                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17204                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17205
17206         { &hf_smb_get_dfs_server_hold_storage,
17207                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17208                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17209
17210         { &hf_smb_get_dfs_fielding,
17211                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17212                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17213
17214         { &hf_smb_dfs_referral_version,
17215                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17216                 NULL, 0, "Version of referral element", HFILL }},
17217
17218         { &hf_smb_dfs_referral_size,
17219                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17220                 NULL, 0, "Size of referral element", HFILL }},
17221
17222         { &hf_smb_dfs_referral_server_type,
17223                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17224                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17225
17226         { &hf_smb_dfs_referral_flags_strip,
17227                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17228                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17229
17230         { &hf_smb_dfs_referral_node_offset,
17231                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17232                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17233
17234         { &hf_smb_dfs_referral_node,
17235                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17236                 NULL, 0, "Name of entity to visit next", HFILL }},
17237
17238         { &hf_smb_dfs_referral_proximity,
17239                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17240                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17241
17242         { &hf_smb_dfs_referral_ttl,
17243                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17244                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17245
17246         { &hf_smb_dfs_referral_path_offset,
17247                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17248                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17249
17250         { &hf_smb_dfs_referral_path,
17251                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
17252                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
17253
17254         { &hf_smb_dfs_referral_alt_path_offset,
17255                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
17256                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
17257
17258         { &hf_smb_dfs_referral_alt_path,
17259                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
17260                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
17261
17262         { &hf_smb_end_of_search,
17263                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
17264                 NULL, 0, "Was last entry returned?", HFILL }},
17265
17266         { &hf_smb_last_name_offset,
17267                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
17268                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
17269
17270         { &hf_smb_fn_information_level,
17271                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
17272                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
17273
17274         { &hf_smb_monitor_handle,
17275                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
17276                 NULL, 0, "Handle for Find Notify operations", HFILL }},
17277
17278         { &hf_smb_change_count,
17279                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
17280                 NULL, 0, "Number of changes to wait for", HFILL }},
17281
17282         { &hf_smb_file_index,
17283                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
17284                 NULL, 0, "File index", HFILL }},
17285
17286         { &hf_smb_short_file_name,
17287                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
17288                 NULL, 0, "Short (8.3) File Name", HFILL }},
17289
17290         { &hf_smb_short_file_name_len,
17291                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
17292                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
17293
17294         { &hf_smb_fs_id,
17295                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
17296                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
17297
17298         { &hf_smb_sector_unit,
17299                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
17300                 NULL, 0, "Sectors per allocation unit", HFILL }},
17301
17302         { &hf_smb_fs_units,
17303                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
17304                 NULL, 0, "Total number of units on this filesystem", HFILL }},
17305
17306         { &hf_smb_fs_sector,
17307                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
17308                 NULL, 0, "Bytes per sector", HFILL }},
17309
17310         { &hf_smb_avail_units,
17311                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
17312                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
17313
17314         { &hf_smb_volume_serial_num,
17315                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
17316                 NULL, 0, "Volume serial number", HFILL }},
17317
17318         { &hf_smb_volume_label_len,
17319                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
17320                 NULL, 0, "Length of volume label", HFILL }},
17321
17322         { &hf_smb_volume_label,
17323                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
17324                 NULL, 0, "Volume label", HFILL }},
17325
17326         { &hf_smb_free_alloc_units64,
17327                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
17328                 NULL, 0, "Number of free allocation units", HFILL }},
17329
17330         { &hf_smb_caller_free_alloc_units64,
17331                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
17332                 NULL, 0, "Number of caller free allocation units", HFILL }},
17333
17334         { &hf_smb_actual_free_alloc_units64,
17335                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
17336                 NULL, 0, "Number of actual free allocation units", HFILL }},
17337
17338         { &hf_smb_soft_quota_limit,
17339                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
17340                 NULL, 0, "Soft Quota treshold", HFILL }},
17341
17342         { &hf_smb_hard_quota_limit,
17343                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
17344                 NULL, 0, "Hard Quota limit", HFILL }},
17345
17346         { &hf_smb_user_quota_used,
17347                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
17348                 NULL, 0, "How much Quota is used by this user", HFILL }},
17349
17350         { &hf_smb_max_name_len,
17351                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
17352                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
17353
17354         { &hf_smb_fs_name_len,
17355                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
17356                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
17357
17358         { &hf_smb_fs_name,
17359                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
17360                 NULL, 0, "Name of filesystem", HFILL }},
17361
17362         { &hf_smb_device_char_removable,
17363                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
17364                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
17365
17366         { &hf_smb_device_char_read_only,
17367                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
17368                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
17369
17370         { &hf_smb_device_char_floppy,
17371                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
17372                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
17373
17374         { &hf_smb_device_char_write_once,
17375                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
17376                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
17377
17378         { &hf_smb_device_char_remote,
17379                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
17380                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
17381
17382         { &hf_smb_device_char_mounted,
17383                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
17384                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
17385
17386         { &hf_smb_device_char_virtual,
17387                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
17388                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
17389
17390         { &hf_smb_fs_attr_css,
17391                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
17392                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
17393
17394         { &hf_smb_fs_attr_cpn,
17395                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
17396                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
17397
17398         { &hf_smb_fs_attr_pacls,
17399                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
17400                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
17401
17402         { &hf_smb_fs_attr_fc,
17403                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
17404                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
17405
17406         { &hf_smb_fs_attr_vq,
17407                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
17408                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
17409
17410         { &hf_smb_fs_attr_dim,
17411                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
17412                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
17413
17414         { &hf_smb_fs_attr_vic,
17415                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
17416                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
17417
17418         { &hf_smb_sec_desc_revision,
17419                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
17420                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
17421
17422         { &hf_smb_sid_revision,
17423                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
17424                 NULL, 0, "Version of SID structure", HFILL }},
17425
17426         { &hf_smb_sid_num_auth,
17427                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
17428                 NULL, 0, "Number of authorities for this SID", HFILL }},
17429
17430         { &hf_smb_acl_revision,
17431                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
17432                 NULL, 0, "Version of NT ACL structure", HFILL }},
17433
17434         { &hf_smb_acl_size,
17435                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
17436                 NULL, 0, "Size of NT ACL structure", HFILL }},
17437
17438         { &hf_smb_acl_num_aces,
17439                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
17440                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
17441
17442         { &hf_smb_user_quota_offset,
17443                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
17444                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
17445
17446         { &hf_smb_ace_type,
17447                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
17448                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
17449
17450         { &hf_smb_ace_size,
17451                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
17452                 NULL, 0, "Size of this ACE", HFILL }},
17453
17454         { &hf_smb_ace_flags_object_inherit,
17455                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
17456                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
17457
17458         { &hf_smb_ace_flags_container_inherit,
17459                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
17460                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
17461
17462         { &hf_smb_ace_flags_non_propagate_inherit,
17463                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
17464                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
17465
17466         { &hf_smb_ace_flags_inherit_only,
17467                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
17468                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
17469
17470         { &hf_smb_ace_flags_inherited_ace,
17471                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
17472                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
17473
17474         { &hf_smb_ace_flags_successful_access,
17475                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
17476                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
17477
17478         { &hf_smb_ace_flags_failed_access,
17479                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
17480                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
17481
17482         { &hf_smb_sec_desc_type_owner_defaulted,
17483                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
17484                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
17485
17486         { &hf_smb_sec_desc_type_group_defaulted,
17487                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
17488                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
17489
17490         { &hf_smb_sec_desc_type_dacl_present,
17491                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
17492                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
17493
17494         { &hf_smb_sec_desc_type_dacl_defaulted,
17495                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
17496                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
17497
17498         { &hf_smb_sec_desc_type_sacl_present,
17499                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
17500                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
17501
17502         { &hf_smb_sec_desc_type_sacl_defaulted,
17503                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
17504                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
17505
17506         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
17507                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
17508                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
17509
17510         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
17511                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
17512                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
17513
17514         { &hf_smb_sec_desc_type_dacl_auto_inherited,
17515                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
17516                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
17517
17518         { &hf_smb_sec_desc_type_sacl_auto_inherited,
17519                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
17520                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
17521
17522         { &hf_smb_sec_desc_type_dacl_protected,
17523                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
17524                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
17525
17526         { &hf_smb_sec_desc_type_sacl_protected,
17527                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
17528                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
17529
17530         { &hf_smb_sec_desc_type_self_relative,
17531                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
17532                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
17533
17534         { &hf_smb_quota_flags_deny_disk,
17535                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
17536                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
17537
17538         { &hf_smb_quota_flags_log_limit,
17539                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
17540                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
17541
17542         { &hf_smb_quota_flags_log_warning,
17543                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
17544                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
17545
17546         { &hf_smb_quota_flags_enabled,
17547                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
17548                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
17549
17550         { &hf_smb_segment_overlap,
17551                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17552                         "Fragment overlaps with other fragments", HFILL }},
17553
17554         { &hf_smb_segment_overlap_conflict,
17555                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17556                         "Overlapping fragments contained conflicting data", HFILL }},
17557
17558         { &hf_smb_segment_multiple_tails,
17559                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17560                         "Several tails were found when defragmenting the packet", HFILL }},
17561
17562         { &hf_smb_segment_too_long_fragment,
17563                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17564                         "Fragment contained data past end of packet", HFILL }},
17565
17566         { &hf_smb_segment_error,
17567                 { "Defragmentation error", "smb.segment.error", FT_NONE, BASE_NONE, NULL, 0x0,
17568                         "Defragmentation error due to illegal fragments", HFILL }},
17569
17570         { &hf_smb_segment,
17571                 { "SMB Segment", "smb.segment", FT_NONE, BASE_NONE, NULL, 0x0,
17572                         "SMB Segment", HFILL }},
17573
17574         { &hf_smb_segments,
17575                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
17576                         "SMB Segments", HFILL }},
17577         };
17578         static gint *ett[] = {
17579                 &ett_smb,
17580                 &ett_smb_hdr,
17581                 &ett_smb_command,
17582                 &ett_smb_fileattributes,
17583                 &ett_smb_capabilities,
17584                 &ett_smb_aflags,
17585                 &ett_smb_dialect,
17586                 &ett_smb_dialects,
17587                 &ett_smb_mode,
17588                 &ett_smb_rawmode,
17589                 &ett_smb_flags,
17590                 &ett_smb_flags2,
17591                 &ett_smb_desiredaccess,
17592                 &ett_smb_search,
17593                 &ett_smb_file,
17594                 &ett_smb_openfunction,
17595                 &ett_smb_filetype,
17596                 &ett_smb_openaction,
17597                 &ett_smb_writemode,
17598                 &ett_smb_lock_type,
17599                 &ett_smb_ssetupandxaction,
17600                 &ett_smb_optionsup,
17601                 &ett_smb_time_date,
17602                 &ett_smb_move_copy_flags,
17603                 &ett_smb_file_attributes,
17604                 &ett_smb_search_resume_key,
17605                 &ett_smb_search_dir_info,
17606                 &ett_smb_unlocks,
17607                 &ett_smb_unlock,
17608                 &ett_smb_locks,
17609                 &ett_smb_lock,
17610                 &ett_smb_open_flags,
17611                 &ett_smb_ipc_state,
17612                 &ett_smb_open_action,
17613                 &ett_smb_setup_action,
17614                 &ett_smb_connect_flags,
17615                 &ett_smb_connect_support_bits,
17616                 &ett_smb_nt_access_mask,
17617                 &ett_smb_nt_create_bits,
17618                 &ett_smb_nt_create_options,
17619                 &ett_smb_nt_share_access,
17620                 &ett_smb_nt_security_flags,
17621                 &ett_smb_nt_trans_setup,
17622                 &ett_smb_nt_trans_data,
17623                 &ett_smb_nt_trans_param,
17624                 &ett_smb_nt_notify_completion_filter,
17625                 &ett_smb_nt_ioctl_flags,
17626                 &ett_smb_security_information_mask,
17627                 &ett_smb_print_queue_entry,
17628                 &ett_smb_transaction_flags,
17629                 &ett_smb_transaction_params,
17630                 &ett_smb_find_first2_flags,
17631 #if 0
17632                 &ett_smb_ioflag,
17633 #endif
17634                 &ett_smb_transaction_data,
17635                 &ett_smb_stream_info,
17636                 &ett_smb_dfs_referrals,
17637                 &ett_smb_dfs_referral,
17638                 &ett_smb_dfs_referral_flags,
17639                 &ett_smb_get_dfs_flags,
17640                 &ett_smb_ff2_data,
17641                 &ett_smb_device_characteristics,
17642                 &ett_smb_fs_attributes,
17643                 &ett_smb_segments,
17644                 &ett_smb_segment,
17645                 &ett_smb_sec_desc,
17646                 &ett_smb_sid,
17647                 &ett_smb_acl,
17648                 &ett_smb_ace,
17649                 &ett_smb_ace_flags,
17650                 &ett_smb_sec_desc_type,
17651                 &ett_smb_quotaflags,
17652         };
17653         module_t *smb_module;
17654
17655         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
17656             "SMB", "smb");
17657         proto_register_subtree_array(ett, array_length(ett));
17658         proto_register_field_array(proto_smb, hf, array_length(hf));
17659         register_init_routine(&smb_init_protocol);
17660         smb_module = prefs_register_protocol(proto_smb, NULL);
17661         prefs_register_bool_preference(smb_module, "trans_reassembly",
17662                 "Reassemble SMB Transaction payload",
17663                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
17664                 &smb_trans_reassembly);
17665         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
17666                 "Reassemble DCERPC over SMB",
17667                 "Whether the dissector should reassemble DCERPC over SMB commands",
17668                 &smb_dcerpc_reassembly);
17669         register_init_routine(smb_trans_reassembly_init);
17670         register_init_routine(smb_dcerpc_reassembly_init);
17671 }
17672
17673 void
17674 proto_reg_handoff_smb(void)
17675 {
17676         heur_dissector_add("netbios", dissect_smb, proto_smb);
17677 }