Put back the stuff to dissect the last 2 bytes of
[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.264 2002/05/26 09:47:47 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42
43 #include <time.h>
44 #include <string.h>
45 #include <glib.h>
46 #include <ctype.h>
47 #include <epan/packet.h>
48 #include <epan/conversation.h>
49 #include "smb.h"
50 #include "alignment.h"
51 #include <epan/strutil.h>
52 #include "prefs.h"
53 #include "reassemble.h"
54
55 #include "packet-smb-mailslot.h"
56 #include "packet-smb-pipe.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS 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
579 static gint ett_smb = -1;
580 static gint ett_smb_hdr = -1;
581 static gint ett_smb_command = -1;
582 static gint ett_smb_fileattributes = -1;
583 static gint ett_smb_capabilities = -1;
584 static gint ett_smb_aflags = -1;
585 static gint ett_smb_dialect = -1;
586 static gint ett_smb_dialects = -1;
587 static gint ett_smb_mode = -1;
588 static gint ett_smb_rawmode = -1;
589 static gint ett_smb_flags = -1;
590 static gint ett_smb_flags2 = -1;
591 static gint ett_smb_desiredaccess = -1;
592 static gint ett_smb_search = -1;
593 static gint ett_smb_file = -1;
594 static gint ett_smb_openfunction = -1;
595 static gint ett_smb_filetype = -1;
596 static gint ett_smb_openaction = -1;
597 static gint ett_smb_writemode = -1;
598 static gint ett_smb_lock_type = -1;
599 static gint ett_smb_ssetupandxaction = -1;
600 static gint ett_smb_optionsup = -1;
601 static gint ett_smb_time_date = -1;
602 static gint ett_smb_move_copy_flags = -1;
603 static gint ett_smb_file_attributes = -1;
604 static gint ett_smb_search_resume_key = -1;
605 static gint ett_smb_search_dir_info = -1;
606 static gint ett_smb_unlocks = -1;
607 static gint ett_smb_unlock = -1;
608 static gint ett_smb_locks = -1;
609 static gint ett_smb_lock = -1;
610 static gint ett_smb_open_flags = -1;
611 static gint ett_smb_ipc_state = -1;
612 static gint ett_smb_open_action = -1;
613 static gint ett_smb_setup_action = -1;
614 static gint ett_smb_connect_flags = -1;
615 static gint ett_smb_connect_support_bits = -1;
616 static gint ett_smb_nt_access_mask = -1;
617 static gint ett_smb_nt_create_bits = -1;
618 static gint ett_smb_nt_create_options = -1;
619 static gint ett_smb_nt_share_access = -1;
620 static gint ett_smb_nt_security_flags = -1;
621 static gint ett_smb_nt_trans_setup = -1;
622 static gint ett_smb_nt_trans_data = -1;
623 static gint ett_smb_nt_trans_param = -1;
624 static gint ett_smb_nt_notify_completion_filter = -1;
625 static gint ett_smb_nt_ioctl_flags = -1;
626 static gint ett_smb_security_information_mask = -1;
627 static gint ett_smb_print_queue_entry = -1;
628 static gint ett_smb_transaction_flags = -1;
629 static gint ett_smb_transaction_params = -1;
630 static gint ett_smb_find_first2_flags = -1;
631 #if 0
632 static gint ett_smb_ioflag = -1;
633 #endif
634 static gint ett_smb_transaction_data = -1;
635 static gint ett_smb_stream_info = -1;
636 static gint ett_smb_dfs_referrals = -1;
637 static gint ett_smb_dfs_referral = -1;
638 static gint ett_smb_dfs_referral_flags = -1;
639 static gint ett_smb_get_dfs_flags = -1;
640 static gint ett_smb_ff2_data = -1;
641 static gint ett_smb_device_characteristics = -1;
642 static gint ett_smb_fs_attributes = -1;
643 static gint ett_smb_segments = -1;
644 static gint ett_smb_sec_desc = -1;
645 static gint ett_smb_sid = -1;
646 static gint ett_smb_acl = -1;
647 static gint ett_smb_ace = -1;
648 static gint ett_smb_ace_flags = -1;
649 static gint ett_smb_sec_desc_type = -1;
650 static gint ett_smb_quotaflags = -1;
651
652 proto_tree *top_tree=NULL;     /* ugly */
653
654 static char *decode_smb_name(unsigned char);
655 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd);
656 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
657     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
658     gboolean exactlen, guint16 *bcp);
659
660 /*
661  * Macros for use in the main dissector routines for an SMB.
662  */
663
664 #define WORD_COUNT      \
665         /* Word Count */                                \
666         wc = tvb_get_guint8(tvb, offset);               \
667         proto_tree_add_uint(tree, hf_smb_word_count,    \
668                 tvb, offset, 1, wc);                    \
669         offset += 1;                                    \
670         if(wc==0) goto bytecount;
671
672 #define BYTE_COUNT      \
673         bytecount:                                      \
674         bc = tvb_get_letohs(tvb, offset);               \
675         proto_tree_add_uint(tree, hf_smb_byte_count,    \
676                         tvb, offset, 2, bc);            \
677         offset += 2;                                    \
678         if(bc==0) goto endofcommand;
679
680 #define CHECK_BYTE_COUNT(len)   \
681         if (bc < len) goto endofcommand;
682
683 #define COUNT_BYTES(len)   {\
684         int tmp;            \
685         tmp=len;            \
686         offset += tmp;      \
687         bc -= tmp;          \
688         }
689
690 #define END_OF_SMB      \
691         if (bc != 0) { \
692                 proto_tree_add_text(tree, tvb, offset, bc, \
693                     "Extra byte parameters");           \
694                 offset += bc;                           \
695         }                                               \
696         endofcommand:
697
698 /*
699  * Macros for use in routines called by them.
700  */
701 #define CHECK_BYTE_COUNT_SUBR(len)      \
702         if (*bcp < len) {               \
703                 *trunc = TRUE;          \
704                 return offset;          \
705         }
706
707 #define CHECK_STRING_SUBR(fn)   \
708         if (fn == NULL) {       \
709                 *trunc = TRUE;  \
710                 return offset;  \
711         }
712
713 #define COUNT_BYTES_SUBR(len)   \
714         offset += len;          \
715         *bcp -= len;
716
717 /*
718  * Macros for use when dissecting transaction parameters and data
719  */
720 #define CHECK_BYTE_COUNT_TRANS(len)     \
721         if (bc < len) return offset;
722
723 #define CHECK_STRING_TRANS(fn)  \
724         if (fn == NULL) return offset;
725
726 #define COUNT_BYTES_TRANS(len)  \
727         offset += len;          \
728         bc -= len;
729
730 /*
731  * Macros for use in subrroutines dissecting transaction parameters or data
732  */
733 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
734         if (*bcp < len) return offset;
735
736 #define CHECK_STRING_TRANS_SUBR(fn)     \
737         if (fn == NULL) return offset;
738
739 #define COUNT_BYTES_TRANS_SUBR(len)     \
740         offset += len;                  \
741         *bcp -= len;
742
743
744 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
745    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
746    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
747 static gboolean smb_trans_reassembly = FALSE;
748 gboolean smb_dcerpc_reassembly = FALSE;
749
750 static GHashTable *smb_trans_fragment_table = NULL;
751 GHashTable *dcerpc_fragment_table = NULL;
752
753 static void
754 smb_trans_reassembly_init(void)
755 {
756         fragment_table_init(&smb_trans_fragment_table);
757 }
758 static void
759 smb_dcerpc_reassembly_init(void)
760 {
761         fragment_table_init(&dcerpc_fragment_table);
762 }
763
764
765 static fragment_data *
766 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
767                      int offset, int count, int pos, int totlen)
768 {
769         fragment_data *fd_head=NULL;
770         smb_info_t *si;
771         int more_frags;
772
773         more_frags=totlen>(pos+count);
774
775         si = (smb_info_t *)pinfo->private_data;
776         if (si->sip == NULL) {
777                 /*
778                  * We don't have the frame number of the request.
779                  *
780                  * XXX - is there truly nothing we can do here?
781                  * Can we not separately keep track of the original
782                  * transaction and its continuations, as we did
783                  * at one time?
784                  *
785                  * It is probably not much point in even trying to do something here
786                  * if we have never seen the initial request. Without the initial 
787                  * request we probably miss all parameters and the begining of data
788                  * so we cant even call a subdissector since we can not determine
789                  * which type of transaction call this is.
790                  */
791                 return NULL;
792         }
793
794         if(!pinfo->fd->flags.visited){
795                 fd_head = fragment_add(tvb, offset, pinfo,
796                                        si->sip->frame_req, smb_trans_fragment_table,
797                                        pos, count, more_frags);
798         } else {
799                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
800         }
801
802         /* we only show the defragmented packet for the first fragment,
803            or else we might end up with dissecting one HUGE transaction PDU
804            a LOT of times. (first fragment is the only one containing the setup
805            bytes)
806            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
807            SMBs. Takes a LOT of time dissecting and is not fun.
808         */
809         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
810                 return fd_head;
811         } else {
812                 return NULL;
813         }
814 }
815                 
816
817
818
819
820 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
821    These variables and functions are used to match
822    responses with calls
823    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
824 /*
825  * The information we need to save about a request in order to show the
826  * frame number of the request in the dissection of the reply.
827  */
828 typedef struct  {
829         guint32 frame;
830         guint32 pid_mid;
831 } smb_saved_info_key_t;
832
833 static GMemChunk *smb_saved_info_key_chunk = NULL;
834 static GMemChunk *smb_saved_info_chunk = NULL;
835 static int smb_saved_info_init_count = 200;
836
837 /* unmatched smb_saved_info structures.
838    For unmatched smb_saved_info structures we store the smb_saved_info
839    structure using the MID and the PID as the key.
840
841    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
842    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
843    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
844 */
845 static gint
846 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
847 {
848         register guint32 key1 = (guint32)k1;
849         register guint32 key2 = (guint32)k2;
850         return key1==key2;
851 }
852 static guint
853 smb_saved_info_hash_unmatched(gconstpointer k)
854 {
855         register guint32 key = (guint32)k;
856         return key;
857 }
858
859 /* matched smb_saved_info structures.
860    For matched smb_saved_info structures we store the smb_saved_info
861    structure twice in the table using the frame number, and a combination
862    of the MID and the PID, as the key.
863    The frame number is guaranteed to be unique but if ever someone makes
864    some change that will renumber the frames in a capture we are in BIG trouble.
865    This is not likely though since that would break (among other things) all the
866    reassembly routines as well.
867
868    We also need the MID as there may be more than one SMB request or reply
869    in a single frame, and we also need the PID as there may be more than
870    one outstanding request with the same MID and different PIDs.
871 */
872 static gint
873 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
874 {
875         const smb_saved_info_key_t *key1 = k1;
876         const smb_saved_info_key_t *key2 = k2;
877         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
878 }
879 static guint
880 smb_saved_info_hash_matched(gconstpointer k)
881 {
882         const smb_saved_info_key_t *key = k;
883         return key->frame + key->pid_mid;
884 }
885
886 /*
887  * The information we need to save about an NT Transaction request in order
888  * to dissect the reply.
889  */
890 typedef struct {
891         int subcmd;
892 } smb_nt_transact_info_t;
893
894 static GMemChunk *smb_nt_transact_info_chunk = NULL;
895 static int smb_nt_transact_info_init_count = 200;
896
897 /*
898  * The information we need to save about a Transaction2 request in order
899  * to dissect the reply.
900  */
901 typedef struct {
902         int subcmd;
903         int info_level;
904         gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
905 } smb_transact2_info_t;
906
907 static GMemChunk *smb_transact2_info_chunk = NULL;
908 static int smb_transact2_info_init_count = 200;
909
910 /*
911  * The information we need to save about a Transaction request in order
912  * to dissect the reply; this includes information for use by the
913  * Remote API dissector.
914  */
915 static GMemChunk *smb_transact_info_chunk = NULL;
916 static int smb_transact_info_init_count = 200;
917
918 static GMemChunk *conv_tables_chunk = NULL;
919 static GSList *conv_tables = NULL;
920 static int conv_tables_count = 10;
921
922
923 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
924    End of request/response matching functions
925    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
926
927 static const value_string buffer_format_vals[] = {
928         {1,     "Data Block"},
929         {2,     "Dialect"},
930         {3,     "Pathname"},
931         {4,     "ASCII"},
932         {5,     "Variable Block"},
933         {0,     NULL}
934 };
935
936 /*
937  * UTIME - this is *almost* like a UNIX time stamp, except that it's
938  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
939  * January 1, 1970, 00:00:00 GMT.
940  *
941  * This means we have to do some extra work to convert it.  This code is
942  * based on the Samba code:
943  *
944  *      Unix SMB/Netbios implementation.
945  *      Version 1.9.
946  *      time handling functions
947  *      Copyright (C) Andrew Tridgell 1992-1998
948  */
949
950 /*
951  * Yield the difference between *A and *B, in seconds, ignoring leap
952  * seconds.
953  */
954 #define TM_YEAR_BASE 1900
955
956 static int
957 tm_diff(struct tm *a, struct tm *b)
958 {
959         int ay = a->tm_year + (TM_YEAR_BASE - 1);
960         int by = b->tm_year + (TM_YEAR_BASE - 1);
961         int intervening_leap_days =
962             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
963         int years = ay - by;
964         int days =
965             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
966         int hours = 24*days + (a->tm_hour - b->tm_hour);
967         int minutes = 60*hours + (a->tm_min - b->tm_min);
968         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
969
970         return seconds;
971 }
972
973 /*
974  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
975  * determined.
976  */
977 static int
978 TimeZone(time_t t)
979 {
980         struct tm *tm = gmtime(&t);
981         struct tm tm_utc;
982
983         if (tm == NULL)
984                 return 0;
985         tm_utc = *tm;
986         tm = localtime(&t);
987         if (tm == NULL)
988                 return 0;
989         return tm_diff(&tm_utc,tm);
990 }
991
992 /*
993  * Return the same value as TimeZone, but it should be more efficient.
994  *
995  * We keep a table of DST offsets to prevent calling localtime() on each 
996  * call of this function. This saves a LOT of time on many unixes.
997  *
998  * Updated by Paul Eggert <eggert@twinsun.com>
999  */
1000 #ifndef CHAR_BIT
1001 #define CHAR_BIT 8
1002 #endif
1003
1004 #ifndef TIME_T_MIN
1005 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1006                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1007 #endif
1008 #ifndef TIME_T_MAX
1009 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1010 #endif
1011
1012 static int
1013 TimeZoneFaster(time_t t)
1014 {
1015         static struct dst_table {time_t start,end; int zone;} *tdt;
1016         static struct dst_table *dst_table = NULL;
1017         static int table_size = 0;
1018         int i;
1019         int zone = 0;
1020
1021         if (t == 0)
1022                 t = time(NULL);
1023
1024         /* Tunis has a 8 day DST region, we need to be careful ... */
1025 #define MAX_DST_WIDTH (365*24*60*60)
1026 #define MAX_DST_SKIP (7*24*60*60)
1027
1028         for (i = 0; i < table_size; i++) {
1029                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1030                         break;
1031         }
1032
1033         if (i < table_size) {
1034                 zone = dst_table[i].zone;
1035         } else {
1036                 time_t low,high;
1037
1038                 zone = TimeZone(t);
1039                 if (dst_table == NULL)
1040                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1041                 else
1042                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1043                 if (tdt == NULL) {
1044                         if (dst_table)
1045                                 free(dst_table);
1046                         table_size = 0;
1047                 } else {
1048                         dst_table = tdt;
1049                         table_size++;
1050     
1051                         dst_table[i].zone = zone; 
1052                         dst_table[i].start = dst_table[i].end = t;
1053     
1054                         /* no entry will cover more than 6 months */
1055                         low = t - MAX_DST_WIDTH/2;
1056                         if (t < low)
1057                                 low = TIME_T_MIN;
1058       
1059                         high = t + MAX_DST_WIDTH/2;
1060                         if (high < t)
1061                                 high = TIME_T_MAX;
1062       
1063                         /*
1064                          * Widen the new entry using two bisection searches.
1065                          */
1066                         while (low+60*60 < dst_table[i].start) {
1067                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1068                                         t = dst_table[i].start - MAX_DST_SKIP;
1069                                 else
1070                                         t = low + (dst_table[i].start-low)/2;
1071                                 if (TimeZone(t) == zone)
1072                                         dst_table[i].start = t;
1073                                 else
1074                                         low = t;
1075                         }
1076
1077                         while (high-60*60 > dst_table[i].end) {
1078                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1079                                         t = dst_table[i].end + MAX_DST_SKIP;
1080                                 else
1081                                         t = high - (high-dst_table[i].end)/2;
1082                                 if (TimeZone(t) == zone)
1083                                         dst_table[i].end = t;
1084                                 else
1085                                         high = t;
1086                         }
1087                 }
1088         }
1089         return zone;
1090 }
1091
1092 /*
1093  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1094  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1095  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1096  * daylight savings transitions because some local times are ambiguous.
1097  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1098  */
1099 static int
1100 LocTimeDiff(time_t lt)
1101 {
1102         int d = TimeZoneFaster(lt);
1103         time_t t = lt + d;
1104
1105         /* if overflow occurred, ignore all the adjustments so far */
1106         if (((t < lt) ^ (d < 0)))
1107                 t = lt;
1108
1109         /*
1110          * Now t should be close enough to the true UTC to yield the
1111          * right answer.
1112          */
1113         return TimeZoneFaster(t);
1114 }
1115
1116 static int
1117 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1118 {
1119         guint32 timeval;
1120         nstime_t ts;
1121  
1122         timeval = tvb_get_letohl(tvb, offset);
1123         if (timeval == 0xffffffff) {
1124                 proto_tree_add_text(tree, tvb, offset, 4,
1125                     "%s: No time specified (0xffffffff)",
1126                     proto_registrar_get_name(hf_date));
1127                 offset += 4;
1128                 return offset;
1129         }
1130
1131         /*
1132          * We add the local time offset.
1133          */
1134         ts.secs = timeval + LocTimeDiff(timeval);
1135         ts.nsecs = 0;
1136
1137         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1138         offset += 4;
1139  
1140         return offset;
1141 }
1142
1143 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1144
1145 /*
1146  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1147  * to an "nstime_t".
1148  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1149  * midnight "UTC", in 100ns units.
1150  * Return TRUE if the conversion succeeds, FALSE otherwise.
1151  *
1152  * According to the Samba code, it appears to be kludge-GMT (at least for
1153  * file listings). This means it's the GMT you get by taking a local time
1154  * and adding the server time zone offset.  This is NOT the same as GMT in
1155  * some cases.   However, we don't know the server time zone, so we don't
1156  * do that adjustment.
1157  *
1158  * This code is based on the Samba code:
1159  *
1160  *      Unix SMB/Netbios implementation.
1161  *      Version 1.9.
1162  *      time handling functions
1163  *      Copyright (C) Andrew Tridgell 1992-1998
1164  */
1165 static gboolean
1166 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1167 {
1168         double d;
1169         /* The next two lines are a fix needed for the 
1170             broken SCO compiler. JRA. */
1171         time_t l_time_min = TIME_T_MIN;
1172         time_t l_time_max = TIME_T_MAX;
1173
1174         if (filetime_high == 0)
1175                 return FALSE;
1176
1177         /*
1178          * Get the time as a double, in seconds and fractional seconds.
1179          */
1180         d = ((double)filetime_high)*4.0*(double)(1<<30);
1181         d += filetime_low;
1182         d *= 1.0e-7;
1183  
1184         /* Now adjust by 369 years, to make the seconds since 1970. */
1185         d -= TIME_FIXUP_CONSTANT;
1186
1187         if (!(l_time_min <= d && d <= l_time_max))
1188                 return FALSE;
1189
1190         /*
1191          * Get the time as seconds and nanoseconds.
1192          */
1193         tv->secs = d;
1194         tv->nsecs = (d - tv->secs)*1000000000;
1195
1196         return TRUE;
1197 }
1198
1199 int
1200 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1201 {
1202         guint32 filetime_high, filetime_low;
1203         nstime_t ts;
1204
1205         /* XXX there seems also to be another special time value which is fairly common :
1206            0x40000000 00000000  
1207            the meaning of this one is yet unknown 
1208         */
1209         if (tree) {
1210                 filetime_low = tvb_get_letohl(tvb, offset);
1211                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1212                 if (filetime_low == 0 && filetime_high == 0) {
1213                         proto_tree_add_text(tree, tvb, offset, 8,
1214                             "%s: No time specified (0)",
1215                             proto_registrar_get_name(hf_date));
1216                 } else if(filetime_low==0 && filetime_high==0x80000000){
1217                         proto_tree_add_text(tree, tvb, offset, 8,
1218                             "%s: Infinity (relative time)",
1219                             proto_registrar_get_name(hf_date));
1220                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1221                         proto_tree_add_text(tree, tvb, offset, 8,
1222                             "%s: Infinity (absolute time)",
1223                             proto_registrar_get_name(hf_date));
1224                 } else {                        
1225                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1226                                 proto_tree_add_time(tree, hf_date, tvb,
1227                                     offset, 8, &ts);
1228                         } else {
1229                                 proto_tree_add_text(tree, tvb, offset, 8,
1230                                     "%s: Time can't be converted",
1231                                     proto_registrar_get_name(hf_date));
1232                         }
1233                 }
1234         }
1235
1236         offset += 8;
1237         return offset;
1238 }
1239
1240 static int
1241 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1242     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1243 {
1244         guint16 dos_time, dos_date;
1245         proto_item *item = NULL;
1246         proto_tree *tree = NULL;
1247         struct tm tm;
1248         time_t t;
1249         static const int mday_noleap[12] = {
1250                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1251         };
1252         static const int mday_leap[12] = {
1253                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1254         };
1255 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1256         nstime_t tv;
1257
1258         if (time_first) {
1259                 dos_time = tvb_get_letohs(tvb, offset);
1260                 dos_date = tvb_get_letohs(tvb, offset+2);
1261         } else {
1262                 dos_date = tvb_get_letohs(tvb, offset);
1263                 dos_time = tvb_get_letohs(tvb, offset+2);
1264         }
1265
1266         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1267             (dos_date == 0 && dos_time == 0)) {
1268                 /*
1269                  * No date/time specified.
1270                  */
1271                 if(parent_tree){
1272                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1273                             "%s: No time specified (0x%08x)",
1274                             proto_registrar_get_name(hf_date),
1275                             (dos_date << 16) | dos_time);
1276                 }
1277                 offset += 4;
1278                 return offset;
1279         }
1280
1281         tm.tm_sec = (dos_time&0x1f)*2;
1282         tm.tm_min = (dos_time>>5)&0x3f;
1283         tm.tm_hour = (dos_time>>11)&0x1f;
1284         tm.tm_mday = dos_date&0x1f;
1285         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1286         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1287         tm.tm_isdst = -1;
1288
1289         /*
1290          * Do some sanity checks before calling "mktime()";
1291          * "mktime()" doesn't do them, it "normalizes" out-of-range
1292          * values.
1293          */
1294         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1295            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1296            (ISLEAP(tm.tm_year + 1900) ?
1297              tm.tm_mday > mday_leap[tm.tm_mon] :
1298              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1299              (t = mktime(&tm)) == -1) {
1300                 /*
1301                  * Invalid date/time.
1302                  */
1303                 if (parent_tree) {
1304                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1305                             "%s: Invalid time",
1306                             proto_registrar_get_name(hf_date));
1307                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1308                         if (time_first) {
1309                                 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);
1310                                 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);
1311                         } else {
1312                                 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);
1313                                 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);
1314                         }
1315                 }
1316                 offset += 4;
1317                 return offset;
1318         }
1319
1320         tv.secs = t;
1321         tv.nsecs = 0;
1322
1323         if(parent_tree){
1324                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1325                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1326                 if (time_first) {
1327                         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);
1328                         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);
1329                 } else {
1330                         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);
1331                         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);
1332                 }
1333         }
1334
1335         offset += 4;
1336
1337         return offset;
1338 }
1339
1340
1341 static const value_string da_access_vals[] = {
1342         { 0,            "Open for reading"},
1343         { 1,            "Open for writing"},
1344         { 2,            "Open for reading and writing"},
1345         { 3,            "Open for execute"},
1346         {0, NULL}
1347 };
1348 static const value_string da_sharing_vals[] = {
1349         { 0,            "Compatibility mode"},
1350         { 1,            "Deny read/write/execute (exclusive)"},
1351         { 2,            "Deny write"},
1352         { 3,            "Deny read/execute"},
1353         { 4,            "Deny none"},
1354         {0, NULL}
1355 };
1356 static const value_string da_locality_vals[] = {
1357         { 0,            "Locality of reference unknown"},
1358         { 1,            "Mainly sequential access"},
1359         { 2,            "Mainly random access"},
1360         { 3,            "Random access with some locality"},
1361         {0, NULL}
1362 };
1363 static const true_false_string tfs_da_caching = {
1364         "Do not cache this file",
1365         "Caching permitted on this file"
1366 };
1367 static const true_false_string tfs_da_writetru = {
1368         "Write through enabled",
1369         "Write through disabled"
1370 };
1371 static int
1372 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1373 {
1374         guint16 mask;
1375         proto_item *item = NULL;
1376         proto_tree *tree = NULL;
1377
1378         mask = tvb_get_letohs(tvb, offset);
1379
1380         if(parent_tree){
1381                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1382                         "%s Access: 0x%04x", type, mask);
1383                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1384         }
1385
1386         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1387                 tvb, offset, 2, mask);
1388         proto_tree_add_boolean(tree, hf_smb_access_caching,
1389                 tvb, offset, 2, mask);
1390         proto_tree_add_uint(tree, hf_smb_access_locality,
1391                 tvb, offset, 2, mask);
1392         proto_tree_add_uint(tree, hf_smb_access_sharing,
1393                 tvb, offset, 2, mask);
1394         proto_tree_add_uint(tree, hf_smb_access_mode,
1395                 tvb, offset, 2, mask);
1396
1397         offset += 2;
1398
1399         return offset;
1400 }
1401
1402 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1403 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1404 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1405 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1406 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1407 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1408 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1409 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1410 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1411 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1412 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1413 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1414 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1415 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1416 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1417
1418 /*
1419  * These are flags to be used in NT Create operations.
1420  */
1421 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1422 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1423 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1424 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1425 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1426 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1427 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1428
1429 static const true_false_string tfs_file_attribute_write_through = {
1430         "This object requires WRITE THROUGH",
1431         "This object does NOT require write through",
1432 };
1433 static const true_false_string tfs_file_attribute_no_buffering = {
1434         "This object requires NO BUFFERING",
1435         "This object can be buffered",
1436 };
1437 static const true_false_string tfs_file_attribute_random_access = {
1438         "This object will be RANDOM ACCESSed",
1439         "Random access is NOT requested",
1440 };
1441 static const true_false_string tfs_file_attribute_sequential_scan = {
1442         "This object is optimized for SEQUENTIAL SCAN",
1443         "This object is NOT optimized for sequential scan",
1444 };
1445 static const true_false_string tfs_file_attribute_delete_on_close = {
1446         "This object will be DELETED ON CLOSE",
1447         "This object will not be deleted on close",
1448 };
1449 static const true_false_string tfs_file_attribute_backup_semantics = {
1450         "This object supports BACKUP SEMANTICS",
1451         "This object does NOT support backup semantics",
1452 };
1453 static const true_false_string tfs_file_attribute_posix_semantics = {
1454         "This object supports POSIX SEMANTICS",
1455         "This object does NOT support POSIX semantics",
1456 };
1457 static const true_false_string tfs_file_attribute_read_only = {
1458         "This file is READ ONLY",
1459         "This file is NOT read only",
1460 };
1461 static const true_false_string tfs_file_attribute_hidden = {
1462         "This is a HIDDEN file",
1463         "This is NOT a hidden file"
1464 };
1465 static const true_false_string tfs_file_attribute_system = {
1466         "This is a SYSTEM file",
1467         "This is NOT a system file"
1468 };
1469 static const true_false_string tfs_file_attribute_volume = {
1470         "This is a VOLUME ID",
1471         "This is NOT a volume ID"
1472 };
1473 static const true_false_string tfs_file_attribute_directory = {
1474         "This is a DIRECTORY",
1475         "This is NOT a directory"
1476 };
1477 static const true_false_string tfs_file_attribute_archive = {
1478         "This is an ARCHIVE file",
1479         "This is NOT an archive file"
1480 };
1481 static const true_false_string tfs_file_attribute_device = {
1482         "This is a DEVICE",
1483         "This is NOT a device"
1484 };
1485 static const true_false_string tfs_file_attribute_normal = {
1486         "This file is an ordinary file",
1487         "This file has some attribute set"
1488 };
1489 static const true_false_string tfs_file_attribute_temporary = {
1490         "This is a TEMPORARY file",
1491         "This is NOT a temporary file"
1492 };
1493 static const true_false_string tfs_file_attribute_sparse = {
1494         "This is a SPARSE file",
1495         "This is NOT a sparse file"
1496 };
1497 static const true_false_string tfs_file_attribute_reparse = {
1498         "This file has an associated REPARSE POINT",
1499         "This file does NOT have an associated reparse point"
1500 };
1501 static const true_false_string tfs_file_attribute_compressed = {
1502         "This is a COMPRESSED file",
1503         "This is NOT a compressed file"
1504 };
1505 static const true_false_string tfs_file_attribute_offline = {
1506         "This file is OFFLINE",
1507         "This file is NOT offline"
1508 };
1509 static const true_false_string tfs_file_attribute_not_content_indexed = {
1510         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1511         "This file MAY be indexed by the content indexing service"
1512 };
1513 static const true_false_string tfs_file_attribute_encrypted = {
1514         "This is an ENCRYPTED file",
1515         "This is NOT an encrypted file"
1516 };
1517
1518 static int
1519 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1520 {
1521         guint16 mask;
1522         proto_item *item = NULL;
1523         proto_tree *tree = NULL;
1524
1525         mask = tvb_get_letohs(tvb, offset);
1526
1527         if(parent_tree){
1528                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1529                         "File Attributes: 0x%04x", mask);
1530                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1531         }
1532         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1533                 tvb, offset, 2, mask);
1534         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1535                 tvb, offset, 2, mask);
1536         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1537                 tvb, offset, 2, mask);
1538         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1539                 tvb, offset, 2, mask);
1540         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1541                 tvb, offset, 2, mask);
1542         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1543                 tvb, offset, 2, mask);
1544
1545         offset += 2;
1546
1547         return offset;
1548 }
1549
1550 /* 3.11 */
1551 static int
1552 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1553 {
1554         guint32 mask;
1555         proto_item *item = NULL;
1556         proto_tree *tree = NULL;
1557
1558         mask = tvb_get_letohl(tvb, offset);
1559
1560         if(parent_tree){
1561                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1562                         "File Attributes: 0x%08x", mask);
1563                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1564         }
1565
1566         /*
1567          * XXX - Network Monitor disagrees on some of the
1568          * bits, e.g. the bits above temporary are "atomic write"
1569          * and "transaction write", and it says nothing about the
1570          * bits above that.
1571          *
1572          * Does the Win32 API documentation, or the NT Native API book,
1573          * suggest anything?
1574          */
1575         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1576                 tvb, offset, 4, mask);
1577         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1578                 tvb, offset, 4, mask);
1579         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1580                 tvb, offset, 4, mask);
1581         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1582                 tvb, offset, 4, mask);
1583         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1584                 tvb, offset, 4, mask);
1585         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1586                 tvb, offset, 4, mask);
1587         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1588                 tvb, offset, 4, mask);
1589         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1590                 tvb, offset, 4, mask);
1591         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1592                 tvb, offset, 4, mask);
1593         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1594                 tvb, offset, 4, mask);
1595         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1596                 tvb, offset, 4, mask);
1597         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1598                 tvb, offset, 4, mask);
1599         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1600                 tvb, offset, 4, mask);
1601         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1602                 tvb, offset, 4, mask);
1603         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1604                 tvb, offset, 4, mask);
1605         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1606                 tvb, offset, 4, mask);
1607         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1608                 tvb, offset, 4, mask);
1609         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1610                 tvb, offset, 4, mask);
1611         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1612                 tvb, offset, 4, mask);
1613         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1614                 tvb, offset, 4, mask);
1615         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1616                 tvb, offset, 4, mask);
1617         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1618                 tvb, offset, 4, mask);
1619
1620         offset += 4;
1621
1622         return offset;
1623 }
1624
1625 static int
1626 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1627 {
1628         guint8 mask;
1629         proto_item *item = NULL;
1630         proto_tree *tree = NULL;
1631
1632         mask = tvb_get_guint8(tvb, offset);
1633
1634         if(parent_tree){
1635                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1636                         "File Attributes: 0x%02x", mask);
1637                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1638         }
1639         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1640                 tvb, offset, 1, mask);
1641         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1642                 tvb, offset, 1, mask);
1643         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1644                 tvb, offset, 1, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1646                 tvb, offset, 1, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1648                 tvb, offset, 1, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1650                 tvb, offset, 1, mask);
1651
1652         offset += 1;
1653
1654         return offset;
1655 }
1656
1657 static const true_false_string tfs_search_attribute_read_only = {
1658         "Include READ ONLY files in search results",
1659         "Do NOT include read only files in search results",
1660 };
1661 static const true_false_string tfs_search_attribute_hidden = {
1662         "Include HIDDEN files in search results",
1663         "Do NOT include hidden files in search results"
1664 };
1665 static const true_false_string tfs_search_attribute_system = {
1666         "Include SYSTEM files in search results",
1667         "Do NOT include system files in search results"
1668 };
1669 static const true_false_string tfs_search_attribute_volume = {
1670         "Include VOLUME IDs in search results",
1671         "Do NOT include volume IDs in search results"
1672 };
1673 static const true_false_string tfs_search_attribute_directory = {
1674         "Include DIRECTORIES in search results",
1675         "Do NOT include directories in search results"
1676 };
1677 static const true_false_string tfs_search_attribute_archive = {
1678         "Include ARCHIVE files in search results",
1679         "Do NOT include archive files in search results"
1680 };
1681
1682 static int
1683 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1684 {
1685         guint16 mask;
1686         proto_item *item = NULL;
1687         proto_tree *tree = NULL;
1688
1689         mask = tvb_get_letohs(tvb, offset);
1690
1691         if(parent_tree){
1692                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1693                         "Search Attributes: 0x%04x", mask);
1694                 tree = proto_item_add_subtree(item, ett_smb_search);
1695         }
1696
1697         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1698                 tvb, offset, 2, mask);
1699         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1700                 tvb, offset, 2, mask);
1701         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1702                 tvb, offset, 2, mask);  
1703         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1704                 tvb, offset, 2, mask);
1705         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1706                 tvb, offset, 2, mask);
1707         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1708                 tvb, offset, 2, mask);
1709
1710         offset += 2;
1711         return offset;
1712 }
1713
1714 #if 0
1715 /*
1716  * XXX - this isn't used.
1717  * Is this used for anything?  NT Create AndX doesn't use it.
1718  * Is there some 16-bit attribute field with more bits than Read Only,
1719  * Hidden, System, Volume ID, Directory, and Archive?
1720  */
1721 static int
1722 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1723 {
1724         guint32 mask;
1725         proto_item *item = NULL;
1726         proto_tree *tree = NULL;
1727
1728         mask = tvb_get_letohl(tvb, offset);
1729
1730         if(parent_tree){
1731                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1732                         "File Attributes: 0x%08x", mask);
1733                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1734         }
1735         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1736                 tvb, offset, 2, mask);
1737         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1738                 tvb, offset, 2, mask);
1739         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1740                 tvb, offset, 2, mask);
1741         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1742                 tvb, offset, 2, mask);
1743         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1744                 tvb, offset, 2, mask);
1745         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1746                 tvb, offset, 2, mask);
1747         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1748                 tvb, offset, 2, mask);
1749         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1750                 tvb, offset, 2, mask);
1751         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1752                 tvb, offset, 2, mask);
1753         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1754                 tvb, offset, 2, mask);
1755         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1756                 tvb, offset, 2, mask);
1757         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1758                 tvb, offset, 2, mask);
1759         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1760                 tvb, offset, 2, mask);
1761         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1762                 tvb, offset, 2, mask);
1763         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1764                 tvb, offset, 2, mask);
1765
1766         offset += 2;
1767
1768         return offset;
1769 }
1770 #endif
1771
1772
1773 #define SERVER_CAP_RAW_MODE            0x00000001
1774 #define SERVER_CAP_MPX_MODE            0x00000002
1775 #define SERVER_CAP_UNICODE             0x00000004
1776 #define SERVER_CAP_LARGE_FILES         0x00000008
1777 #define SERVER_CAP_NT_SMBS             0x00000010
1778 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1779 #define SERVER_CAP_STATUS32            0x00000040
1780 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1781 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1782 #define SERVER_CAP_NT_FIND             0x00000200
1783 #define SERVER_CAP_DFS                 0x00001000
1784 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1785 #define SERVER_CAP_LARGE_READX         0x00004000
1786 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1787 #define SERVER_CAP_UNIX                0x00800000
1788 #define SERVER_CAP_RESERVED            0x02000000
1789 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1790 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1791 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1792 static const true_false_string tfs_server_cap_raw_mode = {
1793         "Read Raw and Write Raw are supported",
1794         "Read Raw and Write Raw are not supported"
1795 };
1796 static const true_false_string tfs_server_cap_mpx_mode = {
1797         "Read Mpx and Write Mpx are supported",
1798         "Read Mpx and Write Mpx are not supported"
1799 };
1800 static const true_false_string tfs_server_cap_unicode = {
1801         "Unicode strings are supported",
1802         "Unicode strings are not supported"
1803 };
1804 static const true_false_string tfs_server_cap_large_files = {
1805         "Large files are supported",
1806         "Large files are not supported",
1807 };
1808 static const true_false_string tfs_server_cap_nt_smbs = {
1809         "NT SMBs are supported",
1810         "NT SMBs are not supported"
1811 };
1812 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1813         "RPC remote APIs are supported",
1814         "RPC remote APIs are not supported"
1815 };
1816 static const true_false_string tfs_server_cap_nt_status = {
1817         "NT status codes are supported",
1818         "NT status codes are not supported"
1819 };
1820 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1821         "Level 2 oplocks are supported",
1822         "Level 2 oplocks are not supported"
1823 };
1824 static const true_false_string tfs_server_cap_lock_and_read = {
1825         "Lock and Read is supported",
1826         "Lock and Read is not supported"
1827 };
1828 static const true_false_string tfs_server_cap_nt_find = {
1829         "NT Find is supported",
1830         "NT Find is not supported"
1831 };
1832 static const true_false_string tfs_server_cap_dfs = {
1833         "Dfs is supported",
1834         "Dfs is not supported"
1835 };
1836 static const true_false_string tfs_server_cap_infolevel_passthru = {
1837         "NT information level request passthrough is supported",
1838         "NT information level request passthrough is not supported"
1839 };
1840 static const true_false_string tfs_server_cap_large_readx = {
1841         "Large Read andX is supported",
1842         "Large Read andX is not supported"
1843 };
1844 static const true_false_string tfs_server_cap_large_writex = {
1845         "Large Write andX is supported",
1846         "Large Write andX is not supported"
1847 };
1848 static const true_false_string tfs_server_cap_unix = {
1849         "UNIX extensions are supported",
1850         "UNIX extensions are not supported"
1851 };
1852 static const true_false_string tfs_server_cap_reserved = {
1853         "Reserved",
1854         "Reserved"
1855 };
1856 static const true_false_string tfs_server_cap_bulk_transfer = {
1857         "Bulk Read and Bulk Write are supported",
1858         "Bulk Read and Bulk Write are not supported"
1859 };
1860 static const true_false_string tfs_server_cap_compressed_data = {
1861         "Compressed data transfer is supported",
1862         "Compressed data transfer is not supported"
1863 };
1864 static const true_false_string tfs_server_cap_extended_security = {
1865         "Extended security exchanges are supported",
1866         "Extended security exchanges are not supported"
1867 };
1868 static int
1869 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1870 {
1871         guint32 mask;
1872         proto_item *item = NULL;
1873         proto_tree *tree = NULL;
1874
1875         mask = tvb_get_letohl(tvb, offset);
1876
1877         if(parent_tree){
1878                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1879                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1880         }
1881
1882         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1883                 tvb, offset, 4, mask);
1884         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1885                 tvb, offset, 4, mask);
1886         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1887                 tvb, offset, 4, mask);
1888         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1889                 tvb, offset, 4, mask);
1890         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1891                 tvb, offset, 4, mask);
1892         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1893                 tvb, offset, 4, mask);
1894         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1895                 tvb, offset, 4, mask);
1896         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1897                 tvb, offset, 4, mask);
1898         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1899                 tvb, offset, 4, mask);
1900         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1901                 tvb, offset, 4, mask);
1902         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1903                 tvb, offset, 4, mask);
1904         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1905                 tvb, offset, 4, mask);
1906         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1907                 tvb, offset, 4, mask);
1908         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1909                 tvb, offset, 4, mask);
1910         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1911                 tvb, offset, 4, mask);
1912         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1913                 tvb, offset, 4, mask);
1914         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1915                 tvb, offset, 4, mask);
1916         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1917                 tvb, offset, 4, mask);
1918         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1919                 tvb, offset, 4, mask);
1920
1921         return mask;
1922 }
1923
1924 #define RAWMODE_READ   0x01
1925 #define RAWMODE_WRITE  0x02
1926 static const true_false_string tfs_rm_read = {
1927         "Read Raw is supported",
1928         "Read Raw is not supported"
1929 };
1930 static const true_false_string tfs_rm_write = {
1931         "Write Raw is supported",
1932         "Write Raw is not supported"
1933 };
1934
1935 static int
1936 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1937 {
1938         guint16 mask;
1939         proto_item *item = NULL;
1940         proto_tree *tree = NULL;
1941
1942         mask = tvb_get_letohs(tvb, offset);
1943
1944         if(parent_tree){
1945                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1946                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1947         }
1948
1949         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1950         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1951
1952         offset += 2;
1953
1954         return offset;
1955 }
1956
1957 #define SECURITY_MODE_MODE             0x01
1958 #define SECURITY_MODE_PASSWORD         0x02
1959 #define SECURITY_MODE_SIGNATURES       0x04
1960 #define SECURITY_MODE_SIG_REQUIRED     0x08
1961 static const true_false_string tfs_sm_mode = {
1962         "USER security mode",
1963         "SHARE security mode"
1964 };
1965 static const true_false_string tfs_sm_password = {
1966         "ENCRYPTED password. Use challenge/response",
1967         "PLAINTEXT password"
1968 };
1969 static const true_false_string tfs_sm_signatures = {
1970         "Security signatures ENABLED",
1971         "Security signatures NOT enabled"
1972 };
1973 static const true_false_string tfs_sm_sig_required = {
1974         "Security signatures REQUIRED",
1975         "Security signatures NOT required"
1976 };
1977
1978 static int
1979 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1980 {
1981         guint16 mask = 0;
1982         proto_item *item = NULL;
1983         proto_tree *tree = NULL;
1984
1985         switch(wc){
1986         case 13:
1987                 mask = tvb_get_letohs(tvb, offset);
1988                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1989                                 "Security Mode: 0x%04x", mask);
1990                 tree = proto_item_add_subtree(item, ett_smb_mode);
1991                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1992                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1993                 offset += 2;
1994                 break;
1995
1996         case 17:
1997                 mask = tvb_get_guint8(tvb, offset);
1998                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1999                                 "Security Mode: 0x%02x", mask);
2000                 tree = proto_item_add_subtree(item, ett_smb_mode);
2001                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2002                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2003                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2004                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2005                 offset += 1;
2006                 break;
2007         }
2008
2009         return offset;
2010 }
2011
2012 static int
2013 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2014 {
2015         proto_item *it = NULL;
2016         proto_tree *tr = NULL;
2017         guint16 bc;
2018         guint8 wc;
2019
2020         WORD_COUNT;
2021
2022         BYTE_COUNT;
2023
2024         if(tree){
2025                 it = proto_tree_add_text(tree, tvb, offset, bc,
2026                                 "Requested Dialects");
2027                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2028         }
2029
2030         while(bc){
2031                 int len;
2032                 const guint8 *str;
2033                 proto_item *dit = NULL;
2034                 proto_tree *dtr = NULL;
2035
2036                 /* XXX - what if this runs past bc? */
2037                 len = tvb_strsize(tvb, offset+1);
2038                 str = tvb_get_ptr(tvb, offset+1, len);
2039
2040                 if(tr){
2041                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2042                                         "Dialect: %s", str);
2043                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2044                 }
2045
2046                 /* Buffer Format */
2047                 CHECK_BYTE_COUNT(1);
2048                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2049                         TRUE);
2050                 COUNT_BYTES(1);
2051
2052                 /*Dialect Name */
2053                 CHECK_BYTE_COUNT(len);
2054                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2055                         len, str);
2056                 COUNT_BYTES(len);
2057         }
2058
2059         END_OF_SMB
2060
2061         return offset;
2062 }
2063
2064 static int
2065 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2066 {
2067         guint8 wc;
2068         guint16 dialect;
2069         const char *dn;
2070         int dn_len;
2071         guint16 bc;
2072         guint16 ekl=0;
2073         guint32 caps=0;
2074         gint16 tz;
2075
2076         WORD_COUNT;
2077
2078         /* Dialect Index */
2079         dialect = tvb_get_letohs(tvb, offset);
2080         switch(wc){
2081         case 1:
2082                 if(dialect==0xffff){
2083                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2084                                 tvb, offset, 2, dialect,
2085                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2086                 } else {
2087                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2088                                 tvb, offset, 2, dialect);
2089                 }
2090                 break;
2091         case 13:
2092                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2093                         tvb, offset, 2, dialect,
2094                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2095                 break;
2096         case 17:
2097                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2098                         tvb, offset, 2, dialect,
2099                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2100                 break;
2101         default:
2102                 proto_tree_add_text(tree, tvb, offset, wc*2,
2103                         "Words for unknown response format");
2104                 offset += wc*2;
2105                 goto bytecount;
2106         }
2107         offset += 2;
2108
2109         switch(wc){
2110         case 13:
2111                 /* Security Mode */
2112                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2113
2114                 /* Maximum Transmit Buffer Size */
2115                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2116                         tvb, offset, 2, TRUE);
2117                 offset += 2;
2118
2119                 /* Maximum Multiplex Count */
2120                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2121                         tvb, offset, 2, TRUE);
2122                 offset += 2;
2123
2124                 /* Maximum Vcs Number */
2125                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2126                         tvb, offset, 2, TRUE);
2127                 offset += 2;
2128
2129                 /* raw mode */
2130                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2131
2132                 /* session key */
2133                 proto_tree_add_item(tree, hf_smb_session_key,
2134                         tvb, offset, 4, TRUE);
2135                 offset += 4;
2136
2137                 /* current time and date at server */
2138                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2139                     TRUE);
2140
2141                 /* time zone */
2142                 tz = tvb_get_letohs(tvb, offset);
2143                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2144                 offset += 2;
2145
2146                 /* encryption key length */
2147                 ekl = tvb_get_letohs(tvb, offset);
2148                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2149                 offset += 2;
2150
2151                 /* 2 reserved bytes */
2152                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2153                 offset += 2;
2154
2155                 break;
2156
2157         case 17:
2158                 /* Security Mode */
2159                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2160
2161                 /* Maximum Multiplex Count */
2162                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2163                         tvb, offset, 2, TRUE);
2164                 offset += 2;
2165
2166                 /* Maximum Vcs Number */
2167                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2168                         tvb, offset, 2, TRUE);
2169                 offset += 2;
2170
2171                 /* Maximum Transmit Buffer Size */
2172                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2173                         tvb, offset, 4, TRUE);
2174                 offset += 4;
2175
2176                 /* maximum raw buffer size */
2177                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2178                         tvb, offset, 4, TRUE);
2179                 offset += 4;
2180
2181                 /* session key */
2182                 proto_tree_add_item(tree, hf_smb_session_key,
2183                         tvb, offset, 4, TRUE);
2184                 offset += 4;
2185
2186                 /* server capabilities */
2187                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2188                 offset += 4;
2189
2190                 /* system time */
2191                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2192                                 hf_smb_system_time);
2193
2194                 /* time zone */
2195                 tz = tvb_get_letohs(tvb, offset);
2196                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2197                         tvb, offset, 2, tz,
2198                         "Server Time Zone: %d min from UTC", tz);
2199                 offset += 2;
2200
2201                 /* encryption key length */
2202                 ekl = tvb_get_guint8(tvb, offset);
2203                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2204                         tvb, offset, 1, ekl);
2205                 offset += 1;
2206
2207                 break;
2208         }
2209
2210         BYTE_COUNT;
2211
2212         switch(wc){
2213         case 13:
2214                 /* challenge/response encryption key */
2215                 if(ekl){
2216                         CHECK_BYTE_COUNT(ekl);
2217                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2218                         COUNT_BYTES(ekl);
2219                 }
2220
2221                 /*
2222                  * Primary domain.
2223                  *
2224                  * XXX - not present if negotiated dialect isn't
2225                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2226                  * have to see the request, or assume what dialect strings
2227                  * were sent, to determine that.
2228                  *
2229                  * Is this something other than a primary domain if the
2230                  * negotiated dialect is Windows for Workgroups 3.1a?
2231                  * It appears to be 8 bytes of binary data in at least
2232                  * one capture - is that an encryption key or something
2233                  * such as that?
2234                  */
2235                 dn = get_unicode_or_ascii_string(tvb, &offset,
2236                         pinfo, &dn_len, FALSE, FALSE, &bc);
2237                 if (dn == NULL)
2238                         goto endofcommand;
2239                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2240                         offset, dn_len,dn);
2241                 COUNT_BYTES(dn_len);
2242                 break;
2243
2244         case 17:
2245                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2246                         smb_info_t *si;
2247
2248                         /* challenge/response encryption key */
2249                         /* XXX - is this aligned on an even boundary? */
2250                         if(ekl){
2251                                 CHECK_BYTE_COUNT(ekl);
2252                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2253                                         tvb, offset, ekl, TRUE);
2254                                 COUNT_BYTES(ekl);
2255                         }
2256
2257                         /* domain */
2258                         /* this string is special, unicode is flagged in caps */
2259                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2260                         si = pinfo->private_data;
2261                         si->unicode = (caps&SERVER_CAP_UNICODE);
2262                         dn = get_unicode_or_ascii_string(tvb,
2263                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2264                                 &bc);
2265                         if (dn == NULL)
2266                                 goto endofcommand;
2267                         proto_tree_add_string(tree, hf_smb_primary_domain,
2268                                 tvb, offset, dn_len, dn);
2269                         COUNT_BYTES(dn_len);
2270                 } else {
2271                         /* guid */
2272                         /* XXX - show it in the standard Microsoft format
2273                            for GUIDs? */
2274                         CHECK_BYTE_COUNT(16);
2275                         proto_tree_add_item(tree, hf_smb_server_guid,
2276                                 tvb, offset, 16, TRUE);
2277                         COUNT_BYTES(16);
2278
2279                         /* security blob */
2280                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2281                            data structure, at least in NT 5.0-and-later
2282                            server replies? */
2283                         if(bc){
2284                                 proto_tree_add_item(tree, hf_smb_security_blob,
2285                                         tvb, offset, bc, TRUE);
2286                                 COUNT_BYTES(bc);
2287                         }
2288                 }
2289                 break;
2290         }
2291
2292         END_OF_SMB
2293
2294         return offset;
2295 }
2296
2297
2298 static int
2299 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2300 {
2301         int dn_len;
2302         const char *dn;
2303         guint8 wc;
2304         guint16 bc;
2305
2306         WORD_COUNT;
2307  
2308         BYTE_COUNT;
2309
2310         /* buffer format */
2311         CHECK_BYTE_COUNT(1);
2312         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2313         COUNT_BYTES(1);
2314
2315         /* dir name */
2316         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2317                 FALSE, FALSE, &bc);
2318         if (dn == NULL)
2319                 goto endofcommand;
2320         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2321                 dn);
2322         COUNT_BYTES(dn_len);
2323
2324         if (check_col(pinfo->cinfo, COL_INFO)) {
2325                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2326         }
2327
2328         END_OF_SMB
2329
2330         return offset;
2331 }
2332
2333 static int
2334 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2335 {
2336         guint8 wc;
2337         guint16 bc;
2338  
2339         WORD_COUNT;
2340  
2341         BYTE_COUNT;
2342
2343         END_OF_SMB
2344
2345         return offset;
2346 }
2347
2348 static int
2349 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2350 {
2351         guint16 ec, bc;
2352         guint8 wc;
2353
2354         WORD_COUNT;
2355
2356         /* echo count */
2357         ec = tvb_get_letohs(tvb, offset);
2358         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2359         offset += 2;
2360
2361         BYTE_COUNT;
2362
2363         if (bc != 0) {
2364                 /* echo data */
2365                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2366                 COUNT_BYTES(bc);
2367         }
2368
2369         END_OF_SMB
2370
2371         return offset;
2372 }
2373
2374 static int
2375 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2376 {
2377         guint16 bc;
2378         guint8 wc;
2379
2380         WORD_COUNT;
2381
2382         /* echo sequence number */
2383         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2384         offset += 2;
2385
2386         BYTE_COUNT;
2387
2388         if (bc != 0) {
2389                 /* echo data */
2390                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2391                 COUNT_BYTES(bc);
2392         }
2393
2394         END_OF_SMB
2395
2396         return offset;
2397 }
2398
2399 static int
2400 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2401 {
2402         int an_len, pwlen;
2403         const char *an;
2404         guint8 wc;
2405         guint16 bc;
2406
2407         WORD_COUNT;
2408  
2409         BYTE_COUNT;
2410
2411         /* buffer format */
2412         CHECK_BYTE_COUNT(1);
2413         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2414         COUNT_BYTES(1);
2415
2416         /* Path */
2417         an = get_unicode_or_ascii_string(tvb, &offset,
2418                 pinfo, &an_len, FALSE, FALSE, &bc);
2419         if (an == NULL)
2420                 goto endofcommand;
2421         proto_tree_add_string(tree, hf_smb_path, tvb,
2422                 offset, an_len, an);
2423         COUNT_BYTES(an_len);
2424
2425         if (check_col(pinfo->cinfo, COL_INFO)) {
2426                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2427         }
2428
2429         /* buffer format */
2430         CHECK_BYTE_COUNT(1);
2431         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2432         COUNT_BYTES(1);
2433
2434         /* password, ANSI */
2435         /* XXX - what if this runs past bc? */
2436         pwlen = tvb_strsize(tvb, offset);
2437         CHECK_BYTE_COUNT(pwlen);
2438         proto_tree_add_item(tree, hf_smb_password,
2439                 tvb, offset, pwlen, TRUE);
2440         COUNT_BYTES(pwlen);
2441
2442         /* buffer format */
2443         CHECK_BYTE_COUNT(1);
2444         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2445         COUNT_BYTES(1);
2446
2447         /* Service */
2448         an = get_unicode_or_ascii_string(tvb, &offset,
2449                 pinfo, &an_len, FALSE, FALSE, &bc);
2450         if (an == NULL)
2451                 goto endofcommand;
2452         proto_tree_add_string(tree, hf_smb_service, tvb,
2453                 offset, an_len, an);
2454         COUNT_BYTES(an_len);
2455
2456         END_OF_SMB
2457
2458         return offset;
2459 }
2460
2461 static int
2462 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2463 {
2464         guint8 wc;
2465         guint16 bc;
2466
2467         WORD_COUNT;
2468  
2469         /* Maximum Buffer Size */
2470         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2471         offset += 2;
2472
2473         /* tid */
2474         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2475         offset += 2;
2476
2477         BYTE_COUNT;
2478
2479         END_OF_SMB
2480
2481         return offset;
2482 }
2483  
2484
2485 static const true_false_string tfs_of_create = {
2486         "Create file if it does not exist",
2487         "Fail if file does not exist"
2488 };
2489 static const value_string of_open[] = {
2490         { 0,            "Fail if file exists"},
2491         { 1,            "Open file if it exists"},
2492         { 2,            "Truncate file if it exists"},
2493         {0, NULL}
2494 };
2495 static int
2496 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2497 {
2498         guint16 mask;
2499         proto_item *item = NULL;
2500         proto_tree *tree = NULL;
2501
2502         mask = tvb_get_letohs(tvb, offset);
2503
2504         if(parent_tree){
2505                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2506                         "Open Function: 0x%04x", mask);
2507                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2508         }
2509
2510         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2511                 tvb, offset, 2, mask);
2512         proto_tree_add_uint(tree, hf_smb_open_function_open,
2513                 tvb, offset, 2, mask);
2514
2515         offset += 2;
2516
2517         return offset;
2518 }
2519
2520
2521 static const true_false_string tfs_mf_file = {
2522         "Target must be a file",
2523         "Target needn't be a file"
2524 };
2525 static const true_false_string tfs_mf_dir = {
2526         "Target must be a directory",
2527         "Target needn't be a directory"
2528 };
2529 static const true_false_string tfs_mf_verify = {
2530         "MUST verify all writes",
2531         "Don't have to verify writes"
2532 };
2533 static int
2534 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2535 {
2536         guint16 mask;
2537         proto_item *item = NULL;
2538         proto_tree *tree = NULL;
2539
2540         mask = tvb_get_letohs(tvb, offset);
2541
2542         if(parent_tree){
2543                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2544                         "Flags: 0x%04x", mask);
2545                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2546         }
2547  
2548         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2549                 tvb, offset, 2, mask);
2550         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2551                 tvb, offset, 2, mask);
2552         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2553                 tvb, offset, 2, mask);
2554
2555         offset += 2;
2556
2557         return offset;
2558 }
2559
2560 static const true_false_string tfs_cf_mode = {
2561         "ASCII",
2562         "Binary"
2563 };
2564 static const true_false_string tfs_cf_tree_copy = {
2565         "Copy is a tree copy",
2566         "Copy is a file copy"
2567 };
2568 static const true_false_string tfs_cf_ea_action = {
2569         "Fail copy",
2570         "Discard EAs"
2571 };
2572 static int
2573 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2574 {
2575         guint16 mask;
2576         proto_item *item = NULL;
2577         proto_tree *tree = NULL;
2578
2579         mask = tvb_get_letohs(tvb, offset);
2580
2581         if(parent_tree){
2582                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2583                         "Flags: 0x%04x", mask);
2584                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2585         }
2586  
2587         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2588                 tvb, offset, 2, mask);
2589         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2590                 tvb, offset, 2, mask);
2591         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2592                 tvb, offset, 2, mask);
2593         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2594                 tvb, offset, 2, mask);
2595         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2596                 tvb, offset, 2, mask);
2597         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2598                 tvb, offset, 2, mask);
2599         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2600                 tvb, offset, 2, mask);
2601
2602         offset += 2;
2603
2604         return offset;
2605 }
2606
2607 static int
2608 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2609 {
2610         int fn_len;
2611         guint16 tid;
2612         guint16 bc;
2613         guint8 wc;
2614         const char *fn;
2615
2616         WORD_COUNT;
2617
2618         /* tid */
2619         tid = tvb_get_letohs(tvb, offset);
2620         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2621                 "TID (target): 0x%04x", tid);
2622         offset += 2;
2623
2624         /* open function */
2625         offset = dissect_open_function(tvb, tree, offset);
2626
2627         /* move flags */
2628         offset = dissect_move_flags(tvb, tree, offset);
2629
2630         BYTE_COUNT;
2631
2632         /* buffer format */
2633         CHECK_BYTE_COUNT(1);
2634         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2635         COUNT_BYTES(1);
2636
2637         /* file name */
2638         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2639                 FALSE, FALSE, &bc);
2640         if (fn == NULL)
2641                 goto endofcommand;
2642         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2643                 fn_len, fn, "Old File Name: %s", fn);
2644         COUNT_BYTES(fn_len);
2645
2646         if (check_col(pinfo->cinfo, COL_INFO)) {
2647                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2648         }
2649
2650         /* buffer format */
2651         CHECK_BYTE_COUNT(1);
2652         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2653         COUNT_BYTES(1);
2654
2655         /* file name */
2656         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2657                 FALSE, FALSE, &bc);
2658         if (fn == NULL)
2659                 goto endofcommand;
2660         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2661                 fn_len, fn, "New File Name: %s", fn);
2662         COUNT_BYTES(fn_len);
2663
2664         if (check_col(pinfo->cinfo, COL_INFO)) {
2665                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2666         }
2667
2668         END_OF_SMB
2669
2670         return offset;
2671 }
2672
2673 static int
2674 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2675 {
2676         int fn_len;
2677         guint16 tid;
2678         guint16 bc;
2679         guint8 wc;
2680         const char *fn;
2681
2682         WORD_COUNT;
2683
2684         /* tid */
2685         tid = tvb_get_letohs(tvb, offset);
2686         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2687                 "TID (target): 0x%04x", tid);
2688         offset += 2;
2689
2690         /* open function */
2691         offset = dissect_open_function(tvb, tree, offset);
2692
2693         /* copy flags */
2694         offset = dissect_copy_flags(tvb, tree, offset);
2695
2696         BYTE_COUNT;
2697
2698         /* buffer format */
2699         CHECK_BYTE_COUNT(1);
2700         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2701         COUNT_BYTES(1);
2702
2703         /* file name */
2704         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2705                 FALSE, FALSE, &bc);
2706         if (fn == NULL)
2707                 goto endofcommand;
2708         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2709                 fn_len, fn, "Source File Name: %s", fn);
2710         COUNT_BYTES(fn_len);
2711
2712         if (check_col(pinfo->cinfo, COL_INFO)) {
2713                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2714         }
2715
2716         /* buffer format */
2717         CHECK_BYTE_COUNT(1);
2718         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2719         COUNT_BYTES(1);
2720
2721         /* file name */
2722         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2723                 FALSE, FALSE, &bc);
2724         if (fn == NULL)
2725                 goto endofcommand;
2726         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2727                 fn_len, fn, "Destination File Name: %s", fn);
2728         COUNT_BYTES(fn_len);
2729
2730         if (check_col(pinfo->cinfo, COL_INFO)) {
2731                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2732         }
2733
2734         END_OF_SMB
2735
2736         return offset;
2737 }
2738
2739 static int
2740 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2741 {
2742         int fn_len;
2743         const char *fn;
2744         guint8 wc;
2745         guint16 bc;
2746
2747         WORD_COUNT;
2748
2749         /* # of files moved */
2750         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2751         offset += 2;
2752
2753         BYTE_COUNT;
2754
2755         /* buffer format */
2756         CHECK_BYTE_COUNT(1);
2757         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2758         COUNT_BYTES(1);
2759
2760         /* file name */
2761         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2762                 FALSE, FALSE, &bc);
2763         if (fn == NULL)
2764                 goto endofcommand;
2765         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2766                 fn);
2767         COUNT_BYTES(fn_len);
2768
2769         END_OF_SMB
2770
2771         return offset;
2772 }
2773
2774 static int
2775 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2776 {
2777         int fn_len;
2778         const char *fn;
2779         guint8 wc;
2780         guint16 bc;
2781
2782         WORD_COUNT;
2783
2784         /* desired access */
2785         offset = dissect_access(tvb, tree, offset, "Desired");
2786
2787         /* Search Attributes */
2788         offset = dissect_search_attributes(tvb, tree, offset);
2789
2790         BYTE_COUNT;
2791
2792         /* buffer format */
2793         CHECK_BYTE_COUNT(1);
2794         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2795         COUNT_BYTES(1);
2796
2797         /* file name */
2798         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2799                 FALSE, FALSE, &bc);
2800         if (fn == NULL)
2801                 goto endofcommand;
2802         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2803                 fn);
2804         COUNT_BYTES(fn_len);
2805
2806         if (check_col(pinfo->cinfo, COL_INFO)) {
2807                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2808         }
2809
2810         END_OF_SMB
2811
2812         return offset;
2813 }
2814
2815 void
2816 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2817     int len, guint16 fid)
2818 {
2819         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2820         if (check_col(pinfo->cinfo, COL_INFO))
2821                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2822 }
2823
2824 static int
2825 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2826 {
2827         guint8 wc;
2828         guint16 bc;
2829         guint16 fid;
2830
2831         WORD_COUNT;
2832
2833         /* fid */
2834         fid = tvb_get_letohs(tvb, offset);
2835         add_fid(tvb, pinfo, tree, offset, 2, fid);
2836         offset += 2;
2837
2838         /* File Attributes */
2839         offset = dissect_file_attributes(tvb, tree, offset);
2840
2841         /* last write time */
2842         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2843         
2844         /* File Size */
2845         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2846         offset += 4;
2847
2848         /* granted access */
2849         offset = dissect_access(tvb, tree, offset, "Granted");
2850
2851         BYTE_COUNT;
2852
2853         END_OF_SMB
2854
2855         return offset;
2856 }
2857
2858 static int
2859 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2860 {
2861         guint8 wc;
2862         guint16 bc;
2863         guint16 fid;
2864
2865         WORD_COUNT;
2866
2867         /* fid */
2868         fid = tvb_get_letohs(tvb, offset);
2869         add_fid(tvb, pinfo, tree, offset, 2, fid);
2870         offset += 2;
2871
2872         BYTE_COUNT;
2873
2874         END_OF_SMB
2875
2876         return offset;
2877 }
2878
2879 static int
2880 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2881 {
2882         int fn_len;
2883         const char *fn;
2884         guint8 wc;
2885         guint16 bc;
2886
2887         WORD_COUNT;
2888
2889         /* file attributes */
2890         offset = dissect_file_attributes(tvb, tree, offset);
2891
2892         /* creation time */
2893         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2894
2895         BYTE_COUNT;
2896
2897         /* buffer format */
2898         CHECK_BYTE_COUNT(1);
2899         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2900         COUNT_BYTES(1);
2901
2902         /* File Name */
2903         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2904                 FALSE, FALSE, &bc);
2905         if (fn == NULL)
2906                 goto endofcommand;
2907         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2908                 fn);
2909         COUNT_BYTES(fn_len);
2910
2911         if (check_col(pinfo->cinfo, COL_INFO)) {
2912                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2913         }
2914
2915         END_OF_SMB
2916
2917         return offset;
2918 }
2919
2920 static int
2921 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2922 {
2923         guint8 wc;
2924         guint16 bc, fid;
2925
2926         WORD_COUNT;
2927
2928         /* fid */
2929         fid = tvb_get_letohs(tvb, offset);
2930         add_fid(tvb, pinfo, tree, offset, 2, fid);
2931         offset += 2;
2932
2933         /* last write time */
2934         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2935
2936         BYTE_COUNT;
2937
2938         END_OF_SMB
2939
2940         return offset;
2941 }
2942
2943 static int
2944 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2945 {
2946         int fn_len;
2947         const char *fn;
2948         guint8 wc;
2949         guint16 bc;
2950
2951         WORD_COUNT;
2952
2953         /* search attributes */
2954         offset = dissect_search_attributes(tvb, tree, offset);
2955
2956         BYTE_COUNT;
2957
2958         /* buffer format */
2959         CHECK_BYTE_COUNT(1);
2960         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2961         COUNT_BYTES(1);
2962
2963         /* file name */
2964         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2965                 FALSE, FALSE, &bc);
2966         if (fn == NULL)
2967                 goto endofcommand;
2968         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2969                 fn);
2970         COUNT_BYTES(fn_len);
2971
2972         if (check_col(pinfo->cinfo, COL_INFO)) {
2973                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2974         }
2975
2976         END_OF_SMB
2977
2978         return offset;
2979 }
2980
2981 static int
2982 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2983 {
2984         int fn_len;
2985         const char *fn;
2986         guint8 wc;
2987         guint16 bc;
2988
2989         WORD_COUNT;
2990
2991         /* search attributes */
2992         offset = dissect_search_attributes(tvb, tree, offset);
2993
2994         BYTE_COUNT;
2995
2996         /* buffer format */
2997         CHECK_BYTE_COUNT(1);
2998         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2999         COUNT_BYTES(1);
3000
3001         /* old file name */
3002         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3003                 FALSE, FALSE, &bc);
3004         if (fn == NULL)
3005                 goto endofcommand;
3006         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3007                 fn);
3008         COUNT_BYTES(fn_len);
3009
3010         if (check_col(pinfo->cinfo, COL_INFO)) {
3011                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3012         }
3013
3014         /* buffer format */
3015         CHECK_BYTE_COUNT(1);
3016         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3017         COUNT_BYTES(1);
3018
3019         /* file name */
3020         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3021                 FALSE, FALSE, &bc);
3022         if (fn == NULL)
3023                 goto endofcommand;
3024         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3025                 fn);
3026         COUNT_BYTES(fn_len);
3027
3028         if (check_col(pinfo->cinfo, COL_INFO)) {
3029                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3030         }
3031
3032         END_OF_SMB
3033
3034         return offset;
3035 }
3036
3037 static int
3038 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3039 {
3040         int fn_len;
3041         const char *fn;
3042         guint8 wc;
3043         guint16 bc;
3044
3045         WORD_COUNT;
3046
3047         /* search attributes */
3048         offset = dissect_search_attributes(tvb, tree, offset);
3049  
3050         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3051         offset += 2;
3052
3053         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3054         offset += 4;
3055
3056         BYTE_COUNT;
3057
3058         /* buffer format */
3059         CHECK_BYTE_COUNT(1);
3060         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3061         COUNT_BYTES(1);
3062
3063         /* old file name */
3064         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3065                 FALSE, FALSE, &bc);
3066         if (fn == NULL)
3067                 goto endofcommand;
3068         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3069                 fn);
3070         COUNT_BYTES(fn_len);
3071
3072         if (check_col(pinfo->cinfo, COL_INFO)) {
3073                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3074         }
3075
3076         /* buffer format */
3077         CHECK_BYTE_COUNT(1);
3078         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3079         COUNT_BYTES(1);
3080
3081         /* file name */
3082         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3083                 FALSE, FALSE, &bc);
3084         if (fn == NULL)
3085                 goto endofcommand;
3086         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3087                 fn);
3088         COUNT_BYTES(fn_len);
3089
3090         if (check_col(pinfo->cinfo, COL_INFO)) {
3091                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3092         }
3093
3094         END_OF_SMB
3095
3096         return offset;
3097 }
3098
3099
3100 static int
3101 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3102 {
3103         guint16 bc;
3104         guint8 wc;
3105         const char *fn;
3106         int fn_len;
3107
3108         WORD_COUNT;
3109
3110         BYTE_COUNT;
3111
3112         /* Buffer Format */
3113         CHECK_BYTE_COUNT(1);
3114         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3115         COUNT_BYTES(1);
3116
3117         /* File Name */
3118         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3119                 FALSE, FALSE, &bc);
3120         if (fn == NULL)
3121                 goto endofcommand;
3122         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3123                 fn);
3124         COUNT_BYTES(fn_len);
3125
3126         if (check_col(pinfo->cinfo, COL_INFO)) {
3127                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3128         }
3129
3130         END_OF_SMB
3131
3132         return offset;
3133 }
3134  
3135 static int
3136 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3137 {
3138         guint16 bc;
3139         guint8 wc;
3140
3141         WORD_COUNT;
3142
3143         /* File Attributes */
3144         offset = dissect_file_attributes(tvb, tree, offset);
3145
3146         /* Last Write Time */
3147         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3148
3149         /* File Size */
3150         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3151         offset += 4;
3152
3153         /* 10 reserved bytes */
3154         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3155         offset += 10;
3156
3157         BYTE_COUNT;
3158
3159         END_OF_SMB
3160
3161         return offset;
3162 }
3163
3164 static int
3165 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3166 {
3167         int fn_len;
3168         const char *fn;
3169         guint8 wc;
3170         guint16 bc;
3171
3172         WORD_COUNT;
3173
3174         /* file attributes */
3175         offset = dissect_file_attributes(tvb, tree, offset);
3176
3177         /* last write time */
3178         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3179
3180         /* 10 reserved bytes */
3181         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3182         offset += 10;
3183
3184         BYTE_COUNT;
3185
3186         /* buffer format */
3187         CHECK_BYTE_COUNT(1);
3188         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3189         COUNT_BYTES(1);
3190
3191         /* file name */
3192         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3193                 FALSE, FALSE, &bc);
3194         if (fn == NULL)
3195                 goto endofcommand;
3196         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3197                 fn);
3198         COUNT_BYTES(fn_len);
3199
3200         if (check_col(pinfo->cinfo, COL_INFO)) {
3201                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3202         }
3203
3204         END_OF_SMB
3205
3206         return offset;
3207 }
3208
3209 static int
3210 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3211 {
3212         guint8 wc;
3213         guint16 bc;
3214         smb_info_t *si;
3215         unsigned int fid;
3216
3217         WORD_COUNT;
3218
3219         /* fid */
3220         fid = tvb_get_letohs(tvb, offset);
3221         add_fid(tvb, pinfo, tree, offset, 2, fid);
3222         offset += 2;
3223         if (!pinfo->fd->flags.visited) {
3224                 /* remember the FID for the processing of the response */
3225                 si = (smb_info_t *)pinfo->private_data;
3226                 si->sip->extra_info=(void *)fid;
3227         }
3228
3229         /* read count */
3230         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3231         offset += 2;
3232
3233         /* offset */
3234         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3235         offset += 4;
3236
3237         /* remaining */
3238         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3239         offset += 2;
3240
3241         BYTE_COUNT;
3242
3243         END_OF_SMB
3244
3245         return offset;
3246 }
3247
3248 int
3249 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3250 {
3251         int tvblen;
3252
3253         if(bc>datalen){
3254                 /* We have some initial padding bytes. */
3255                 /* XXX - use the data offset here instead? */
3256                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3257                         TRUE);
3258                 offset += bc-datalen;
3259                 bc = datalen;
3260         }
3261         tvblen = tvb_length_remaining(tvb, offset);
3262         if(bc>tvblen){
3263                 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);
3264                 offset += tvblen;
3265         } else {
3266                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3267                 offset += bc;
3268         }
3269         return offset;
3270 }
3271
3272 static int
3273 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3274     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3275 {
3276         int tvblen;
3277         tvbuff_t *dcerpc_tvb;
3278
3279         if(bc>datalen){
3280                 /* We have some initial padding bytes. */
3281                 /* XXX - use the data offset here instead? */
3282                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3283                         TRUE);
3284                 offset += bc-datalen;
3285                 bc = datalen;
3286         }
3287         tvblen = tvb_length_remaining(tvb, offset);
3288         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3289         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3290         if(bc>tvblen)
3291                 offset += tvblen;
3292         else
3293                 offset += bc;
3294         return offset;
3295 }
3296
3297 static int
3298 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3299 {
3300         guint16 cnt=0, bc;
3301         guint8 wc;
3302         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3303         int fid=0;
3304
3305         WORD_COUNT;
3306
3307         /* read count */
3308         cnt = tvb_get_letohs(tvb, offset);
3309         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3310         offset += 2;
3311
3312         /* 8 reserved bytes */
3313         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3314         offset += 8;
3315
3316         /* If we have seen the request, then print which FID this refers to */
3317         /* first check if we have seen the request */
3318         if(si->sip != NULL && si->sip->frame_req>0){
3319                 fid=(int)si->sip->extra_info;
3320                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3321         }
3322
3323         BYTE_COUNT;
3324
3325         /* buffer format */
3326         CHECK_BYTE_COUNT(1);
3327         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3328         COUNT_BYTES(1);
3329
3330         /* data len */
3331         CHECK_BYTE_COUNT(2);
3332         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3333         COUNT_BYTES(2);
3334
3335         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3336            read write */
3337         if(bc){
3338                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3339                         /* dcerpc call */
3340                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3341                             top_tree, offset, bc, bc, fid);
3342                 } else {
3343                         /* ordinary file data, or we didn't see the request,
3344                            so we don't know whether this is a DCERPC call
3345                            or not */
3346                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3347                 }
3348                 bc = 0;
3349         }
3350
3351         END_OF_SMB
3352
3353         return offset;
3354 }
3355
3356 static int
3357 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3358 {
3359         guint16 cnt, bc;
3360         guint8 wc;
3361
3362         WORD_COUNT;
3363
3364         /* read count */
3365         cnt = tvb_get_letohs(tvb, offset);
3366         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3367         offset += 2;
3368
3369         /* 8 reserved bytes */
3370         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3371         offset += 8;
3372
3373         BYTE_COUNT;
3374
3375         /* buffer format */
3376         CHECK_BYTE_COUNT(1);
3377         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3378         COUNT_BYTES(1);
3379
3380         /* data len */
3381         CHECK_BYTE_COUNT(2);
3382         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3383         COUNT_BYTES(2);
3384
3385         END_OF_SMB
3386
3387         return offset;
3388 }
3389
3390
3391 static int
3392 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3393 {
3394         guint32 ofs=0;
3395         guint16 cnt=0, bc, fid=0;
3396         guint8 wc;
3397         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3398
3399         WORD_COUNT;
3400
3401         /* fid */
3402         fid = tvb_get_letohs(tvb, offset);
3403         add_fid(tvb, pinfo, tree, offset, 2, fid);
3404         offset += 2;
3405
3406         /* write count */
3407         cnt = tvb_get_letohs(tvb, offset);
3408         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3409         offset += 2;
3410
3411         /* offset */
3412         ofs = tvb_get_letohl(tvb, offset);
3413         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3414         offset += 4;
3415
3416         if (check_col(pinfo->cinfo, COL_INFO))
3417                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3418                                 ", %d byte%s at offset %d", cnt, 
3419                                 (cnt == 1) ? "" : "s", ofs);
3420
3421         /* remaining */
3422         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3423         offset += 2;
3424
3425         BYTE_COUNT;
3426
3427         /* buffer format */
3428         CHECK_BYTE_COUNT(1);
3429         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3430         COUNT_BYTES(1);
3431
3432         /* data len */
3433         CHECK_BYTE_COUNT(2);
3434         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3435         COUNT_BYTES(2);
3436
3437         if (bc != 0) {
3438                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3439                         /* dcerpc call */
3440                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3441                             top_tree, offset, bc, bc, fid);
3442                 } else {
3443                         /* ordinary file data */
3444                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3445                 }
3446                 bc = 0;
3447         }
3448
3449         END_OF_SMB
3450
3451         return offset;
3452 }
3453  
3454 static int
3455 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3456 {
3457         guint8 wc;
3458         guint16 bc, cnt;
3459
3460         WORD_COUNT;
3461
3462         /* write count */
3463         cnt = tvb_get_letohs(tvb, offset);
3464         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3465         offset += 2;
3466
3467         if (check_col(pinfo->cinfo, COL_INFO))
3468                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3469                                 ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
3470
3471         BYTE_COUNT;
3472
3473         END_OF_SMB
3474
3475         return offset;
3476 }
3477
3478 static int
3479 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3480 {
3481         guint8 wc;
3482         guint16 bc, fid;
3483
3484         WORD_COUNT;
3485
3486         /* fid */
3487         fid = tvb_get_letohs(tvb, offset);
3488         add_fid(tvb, pinfo, tree, offset, 2, fid);
3489         offset += 2;
3490
3491         /* lock count */
3492         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3493         offset += 4;
3494
3495         /* offset */
3496         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3497         offset += 4;
3498
3499         BYTE_COUNT;
3500
3501         END_OF_SMB
3502
3503         return offset;
3504 }
3505
3506 static int
3507 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3508 {
3509         int fn_len;
3510         const char *fn;
3511         guint8 wc;
3512         guint16 bc;
3513
3514         WORD_COUNT;
3515
3516         /* 2 reserved bytes */
3517         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3518         offset += 2;
3519
3520         /* Creation time */
3521         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3522
3523         BYTE_COUNT;
3524
3525         /* buffer format */
3526         CHECK_BYTE_COUNT(1);
3527         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3528         COUNT_BYTES(1);
3529
3530         /* directory name */
3531         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3532                 FALSE, FALSE, &bc);
3533         if (fn == NULL)
3534                 goto endofcommand;
3535         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3536                 fn);
3537         COUNT_BYTES(fn_len);
3538
3539         if (check_col(pinfo->cinfo, COL_INFO)) {
3540                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3541         }
3542
3543         END_OF_SMB
3544
3545         return offset;
3546 }
3547
3548 static int
3549 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3550 {
3551         int fn_len;
3552         const char *fn;
3553         guint8 wc;
3554         guint16 bc, fid;
3555
3556         WORD_COUNT;
3557
3558         /* fid */
3559         fid = tvb_get_letohs(tvb, offset);
3560         add_fid(tvb, pinfo, tree, offset, 2, fid);
3561         offset += 2;
3562
3563         BYTE_COUNT;
3564
3565         /* buffer format */
3566         CHECK_BYTE_COUNT(1);
3567         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3568         COUNT_BYTES(1);
3569
3570         /* file name */
3571         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3572                 FALSE, FALSE, &bc);
3573         if (fn == NULL)
3574                 goto endofcommand;
3575         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3576                 fn);
3577         COUNT_BYTES(fn_len);
3578
3579         END_OF_SMB
3580
3581         return offset;
3582 }
3583
3584 static const value_string seek_mode_vals[] = {
3585         {0,     "From Start Of File"},
3586         {1,     "From Current Position"},
3587         {2,     "From End Of File"},
3588         {0,     NULL}
3589 };
3590
3591 static int
3592 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3593 {
3594         guint8 wc;
3595         guint16 bc, fid;
3596
3597         WORD_COUNT;
3598
3599         /* fid */
3600         fid = tvb_get_letohs(tvb, offset);
3601         add_fid(tvb, pinfo, tree, offset, 2, fid);
3602         offset += 2;
3603
3604         /* Seek Mode */
3605         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3606         offset += 2;
3607
3608         /* offset */
3609         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3610         offset += 4;
3611
3612         BYTE_COUNT;
3613
3614         END_OF_SMB
3615
3616         return offset;
3617 }
3618
3619 static int
3620 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3621 {
3622         guint8 wc;
3623         guint16 bc;
3624
3625         WORD_COUNT;
3626
3627         /* offset */
3628         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3629         offset += 4;
3630
3631         BYTE_COUNT;
3632
3633         END_OF_SMB
3634
3635         return offset;
3636 }
3637  
3638 static int
3639 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3640 {
3641         guint8 wc;
3642         guint16 bc, fid;
3643
3644         WORD_COUNT;
3645
3646         /* fid */
3647         fid = tvb_get_letohs(tvb, offset);
3648         add_fid(tvb, pinfo, tree, offset, 2, fid);
3649         offset += 2;
3650
3651         /* create time */
3652         offset = dissect_smb_datetime(tvb, tree, offset,
3653                 hf_smb_create_time,
3654                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3655
3656         /* access time */
3657         offset = dissect_smb_datetime(tvb, tree, offset,
3658                 hf_smb_access_time,
3659                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3660
3661         /* last write time */
3662         offset = dissect_smb_datetime(tvb, tree, offset,
3663                 hf_smb_last_write_time,
3664                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3665
3666         BYTE_COUNT;
3667
3668         END_OF_SMB
3669
3670         return offset;
3671 }
3672
3673 static int
3674 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3675 {
3676         guint8 wc;
3677         guint16 bc;
3678
3679         WORD_COUNT;
3680
3681         /* create time */
3682         offset = dissect_smb_datetime(tvb, tree, offset,
3683                 hf_smb_create_time,
3684                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3685
3686         /* access time */
3687         offset = dissect_smb_datetime(tvb, tree, offset,
3688                 hf_smb_access_time,
3689                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3690
3691         /* last write time */
3692         offset = dissect_smb_datetime(tvb, tree, offset,
3693                 hf_smb_last_write_time,
3694                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3695
3696         /* data size */
3697         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3698         offset += 4;
3699
3700         /* allocation size */
3701         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3702         offset += 4;
3703
3704         /* File Attributes */
3705         offset = dissect_file_attributes(tvb, tree, offset);
3706
3707         BYTE_COUNT;
3708
3709         END_OF_SMB
3710
3711         return offset;
3712 }
3713
3714 static int
3715 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3716 {
3717         guint8 wc;
3718         guint16 cnt=0;
3719         guint16 bc, fid;
3720
3721         WORD_COUNT;
3722
3723         /* fid */
3724         fid = tvb_get_letohs(tvb, offset);
3725         add_fid(tvb, pinfo, tree, offset, 2, fid);
3726         offset += 2;
3727
3728         /* write count */
3729         cnt = tvb_get_letohs(tvb, offset);
3730         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3731         offset += 2;
3732
3733         /* offset */
3734         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3735         offset += 4;
3736
3737         /* last write time */
3738         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3739         
3740         if(wc==12){
3741                 /* 12 reserved bytes */
3742                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3743                 offset += 12;
3744         }
3745
3746         BYTE_COUNT;
3747
3748         /* 1 pad byte */
3749         CHECK_BYTE_COUNT(1);
3750         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3751         COUNT_BYTES(1);
3752         
3753         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3754         bc = 0; /* XXX */
3755
3756         END_OF_SMB
3757
3758         return offset;
3759 }
3760  
3761 static int
3762 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3763 {
3764         guint8 wc;
3765         guint16 bc;
3766
3767         WORD_COUNT;
3768
3769         /* write count */
3770         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3771         offset += 2;
3772
3773         BYTE_COUNT;
3774
3775         END_OF_SMB
3776
3777         return offset;
3778 }
3779
3780 static int
3781 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3782 {
3783         guint8 wc;
3784         guint16 bc, fid;
3785         guint32 to;
3786
3787         WORD_COUNT;
3788
3789         /* fid */
3790         fid = tvb_get_letohs(tvb, offset);
3791         add_fid(tvb, pinfo, tree, offset, 2, fid);
3792         offset += 2;
3793
3794         /* offset */
3795         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3796         offset += 4;
3797
3798         /* max count */
3799         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3800         offset += 2;
3801
3802         /* min count */
3803         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3804         offset += 2;
3805
3806         /* timeout */
3807         to = tvb_get_letohl(tvb, offset);
3808         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3809         offset += 4;
3810
3811         /* 2 reserved bytes */
3812         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3813         offset += 2;
3814
3815         if(wc==10){
3816                 /* high offset */
3817                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3818                 offset += 4;
3819         }
3820
3821         BYTE_COUNT;
3822
3823         END_OF_SMB
3824
3825         return offset;
3826 }
3827
3828 static int
3829 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3830 {
3831         guint8 wc;
3832         guint16 bc;
3833
3834         WORD_COUNT;
3835
3836         /* units */
3837         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3838         offset += 2;
3839
3840         /* bpu */
3841         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3842         offset += 2;
3843
3844         /* block size */
3845         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3846         offset += 2;
3847
3848         /* free units */
3849         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3850         offset += 2;
3851
3852         /* 2 reserved bytes */
3853         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3854         offset += 2;
3855
3856         BYTE_COUNT;
3857
3858         END_OF_SMB
3859
3860         return offset;
3861 }
3862
3863 static int
3864 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3865 {
3866         guint8 wc;
3867         guint16 bc, fid;
3868
3869         WORD_COUNT;
3870
3871         /* fid */
3872         fid = tvb_get_letohs(tvb, offset);
3873         add_fid(tvb, pinfo, tree, offset, 2, fid);
3874         offset += 2;
3875
3876         /* offset */
3877         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3878         offset += 4;
3879
3880         /* max count */
3881         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3882         offset += 2;
3883
3884         /* min count */
3885         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3886         offset += 2;
3887
3888         /* 6 reserved bytes */
3889         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3890         offset += 6;
3891
3892         BYTE_COUNT;
3893
3894         END_OF_SMB
3895
3896         return offset;
3897 }
3898
3899 static int
3900 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3901 {
3902         guint16 datalen=0, bc;
3903         guint8 wc;
3904
3905         WORD_COUNT;
3906
3907         /* offset */
3908         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3909         offset += 4;
3910
3911         /* count */
3912         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3913         offset += 2;
3914
3915         /* 2 reserved bytes */
3916         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3917         offset += 2;
3918
3919         /* data compaction mode */
3920         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3921         offset += 2;
3922
3923         /* 2 reserved bytes */
3924         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3925         offset += 2;
3926
3927         /* data len */
3928         datalen = tvb_get_letohs(tvb, offset);
3929         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3930         offset += 2;
3931
3932         /* data offset */
3933         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3934         offset += 2;
3935
3936         BYTE_COUNT;
3937
3938         /* file data */
3939         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
3940         bc = 0;
3941
3942         END_OF_SMB
3943
3944         return offset;
3945 }
3946
3947
3948 static const true_false_string tfs_write_mode_write_through = {
3949         "WRITE THROUGH requested",
3950         "Write through not requested"
3951 };
3952 static const true_false_string tfs_write_mode_return_remaining = {
3953         "RETURN REMAINING (pipe/dev) requested",
3954         "DON'T return remaining (pipe/dev)"
3955 };
3956 static const true_false_string tfs_write_mode_raw = {
3957         "Use WriteRawNamedPipe (pipe)",
3958         "DON'T use WriteRawNamedPipe (pipe)"
3959 };
3960 static const true_false_string tfs_write_mode_message_start = {
3961         "This is the START of a MESSAGE (pipe)",
3962         "This is NOT the start of a message (pipe)"
3963 };
3964 static const true_false_string tfs_write_mode_connectionless = {
3965         "CONNECTIONLESS mode requested",
3966         "Connectionless mode NOT requested"
3967 };
3968 static int
3969 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
3970 {
3971         guint16 mask;
3972         proto_item *item = NULL;
3973         proto_tree *tree = NULL;
3974
3975         mask = tvb_get_letohs(tvb, offset);
3976
3977         if(parent_tree){
3978                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3979                         "Write Mode: 0x%04x", mask);
3980                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3981         }
3982
3983         if(bm&0x0080){
3984                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3985                         tvb, offset, 2, mask);
3986         }
3987         if(bm&0x0008){
3988                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3989                         tvb, offset, 2, mask);
3990         }
3991         if(bm&0x0004){
3992                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3993                         tvb, offset, 2, mask);
3994         }
3995         if(bm&0x0002){
3996                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3997                         tvb, offset, 2, mask);
3998         }
3999         if(bm&0x0001){
4000                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4001                         tvb, offset, 2, mask);
4002         }
4003
4004         offset += 2;
4005         return offset;
4006 }
4007
4008 static int
4009 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4010 {
4011         guint32 to;
4012         guint16 datalen=0, bc, fid;
4013         guint8 wc;
4014
4015         WORD_COUNT;
4016
4017         /* fid */
4018         fid = tvb_get_letohs(tvb, offset);
4019         add_fid(tvb, pinfo, tree, offset, 2, fid);
4020         offset += 2;
4021
4022         /* total data length */
4023         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4024         offset += 2;
4025
4026         /* 2 reserved bytes */
4027         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4028         offset += 2;
4029
4030         /* offset */
4031         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4032         offset += 4;
4033
4034         /* timeout */
4035         to = tvb_get_letohl(tvb, offset);
4036         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4037         offset += 4;
4038
4039         /* mode */
4040         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4041
4042         /* 4 reserved bytes */
4043         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4044         offset += 4;
4045
4046         /* data len */
4047         datalen = tvb_get_letohs(tvb, offset);
4048         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4049         offset += 2;
4050
4051         /* data offset */
4052         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4053         offset += 2;
4054
4055         BYTE_COUNT;
4056
4057         /* file data */
4058         /* XXX - use the data offset to determine where the data starts? */
4059         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4060         bc = 0;
4061
4062         END_OF_SMB
4063
4064         return offset;
4065 }
4066  
4067 static int
4068 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4069 {
4070         guint8 wc;
4071         guint16 bc;
4072
4073         WORD_COUNT;
4074
4075         /* remaining */
4076         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4077         offset += 2;
4078
4079         BYTE_COUNT;
4080
4081         END_OF_SMB
4082
4083         return offset;
4084 }
4085
4086 static int
4087 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4088 {
4089         guint32 to;
4090         guint16 datalen=0, bc, fid;
4091         guint8 wc;
4092
4093         WORD_COUNT;
4094
4095         /* fid */
4096         fid = tvb_get_letohs(tvb, offset);
4097         add_fid(tvb, pinfo, tree, offset, 2, fid);
4098         offset += 2;
4099
4100         /* total data length */
4101         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4102         offset += 2;
4103
4104         /* 2 reserved bytes */
4105         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4106         offset += 2;
4107
4108         /* offset */
4109         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4110         offset += 4;
4111
4112         /* timeout */
4113         to = tvb_get_letohl(tvb, offset);
4114         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4115         offset += 4;
4116
4117         /* mode */
4118         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4119
4120         /* request mask */
4121         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4122         offset += 4;
4123         
4124         /* data len */
4125         datalen = tvb_get_letohs(tvb, offset);
4126         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4127         offset += 2;
4128
4129         /* data offset */
4130         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4131         offset += 2;
4132
4133         BYTE_COUNT;
4134
4135         /* file data */
4136         /* XXX - use the data offset to determine where the data starts? */
4137         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4138         bc = 0;
4139
4140         END_OF_SMB
4141
4142         return offset;
4143 }
4144  
4145 static int
4146 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4147 {
4148         guint8 wc;
4149         guint16 bc;
4150
4151         WORD_COUNT;
4152
4153         /* response mask */
4154         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4155         offset += 4;
4156         
4157         BYTE_COUNT;
4158
4159         END_OF_SMB
4160
4161         return offset;
4162 }
4163
4164 static int
4165 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4166 {
4167         guint8 wc;
4168         guint16 bc;
4169
4170         WORD_COUNT;
4171
4172         /* sid */
4173         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
4174         offset += 2;
4175
4176         BYTE_COUNT;
4177
4178         END_OF_SMB
4179
4180         return offset;
4181 }
4182
4183 static int
4184 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4185     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4186     gboolean has_find_id)
4187 {
4188         proto_item *item = NULL;
4189         proto_tree *tree = NULL;
4190         int fn_len;
4191         const char *fn;
4192         char fname[11+1];
4193
4194         if(parent_tree){
4195                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4196                         "Resume Key");
4197                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4198         }
4199
4200         /* reserved byte */
4201         CHECK_BYTE_COUNT_SUBR(1);
4202         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4203         COUNT_BYTES_SUBR(1);
4204
4205         /* file name */
4206         fn_len = 11;
4207         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4208                 TRUE, TRUE, bcp);
4209         CHECK_STRING_SUBR(fn);
4210         /* ensure that it's null-terminated */
4211         strncpy(fname, fn, 11);
4212         fname[11] = '\0';
4213         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4214                 fname);
4215         COUNT_BYTES_SUBR(fn_len);
4216
4217         if (has_find_id) {
4218                 CHECK_BYTE_COUNT_SUBR(1);
4219                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4220                 COUNT_BYTES_SUBR(1);
4221
4222                 /* server cookie */
4223                 CHECK_BYTE_COUNT_SUBR(4);
4224                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4225                 COUNT_BYTES_SUBR(4);
4226         } else {
4227                 /* server cookie */
4228                 CHECK_BYTE_COUNT_SUBR(5);
4229                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4230                 COUNT_BYTES_SUBR(5);
4231         }
4232
4233         /* client cookie */
4234         CHECK_BYTE_COUNT_SUBR(4);
4235         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4236         COUNT_BYTES_SUBR(4);
4237
4238         *trunc = FALSE;
4239         return offset;
4240 }
4241
4242 static int
4243 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4244     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4245     gboolean has_find_id)
4246 {
4247         proto_item *item = NULL;
4248         proto_tree *tree = NULL;
4249         int fn_len;
4250         const char *fn;
4251         char fname[13+1];
4252
4253         if(parent_tree){
4254                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4255                         "Directory Information");
4256                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4257         }
4258
4259         /* resume key */
4260         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4261             trunc, has_find_id);
4262         if (*trunc)
4263                 return offset;
4264
4265         /* File Attributes */
4266         CHECK_BYTE_COUNT_SUBR(1);
4267         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4268         *bcp -= 1;
4269
4270         /* last write time */
4271         CHECK_BYTE_COUNT_SUBR(4);
4272         offset = dissect_smb_datetime(tvb, tree, offset,
4273                 hf_smb_last_write_time,
4274                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4275                 TRUE);
4276         *bcp -= 4;
4277
4278         /* File Size */
4279         CHECK_BYTE_COUNT_SUBR(4);
4280         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4281         COUNT_BYTES_SUBR(4);
4282
4283         /* file name */
4284         fn_len = 13;
4285         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4286                 TRUE, TRUE, bcp);
4287         CHECK_STRING_SUBR(fn);
4288         /* ensure that it's null-terminated */
4289         strncpy(fname, fn, 13);
4290         fname[13] = '\0';
4291         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4292                 fname);
4293         COUNT_BYTES_SUBR(fn_len);
4294
4295         *trunc = FALSE;
4296         return offset;
4297 }
4298
4299
4300 static int
4301 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4302     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4303     gboolean has_find_id)
4304 {
4305         int fn_len;
4306         const char *fn;
4307         guint16 rkl;
4308         guint8 wc;
4309         guint16 bc;
4310         gboolean trunc;
4311
4312         WORD_COUNT;
4313
4314         /* max count */
4315         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4316         offset += 2;
4317
4318         /* Search Attributes */
4319         offset = dissect_search_attributes(tvb, tree, offset);
4320
4321         BYTE_COUNT;
4322
4323         /* buffer format */
4324         CHECK_BYTE_COUNT(1);
4325         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4326         COUNT_BYTES(1);
4327
4328         /* file name */
4329         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4330                 TRUE, FALSE, &bc);
4331         if (fn == NULL)
4332                 goto endofcommand;
4333         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4334                 fn);
4335         COUNT_BYTES(fn_len);
4336
4337         if (check_col(pinfo->cinfo, COL_INFO)) {
4338                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4339         }
4340
4341         /* buffer format */
4342         CHECK_BYTE_COUNT(1);
4343         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4344         COUNT_BYTES(1);
4345
4346         /* resume key length */
4347         CHECK_BYTE_COUNT(2);
4348         rkl = tvb_get_letohs(tvb, offset);
4349         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4350         COUNT_BYTES(2);
4351
4352         /* resume key */
4353         if(rkl){
4354                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4355                     &bc, &trunc, has_find_id);
4356                 if (trunc)
4357                         goto endofcommand;
4358         }
4359
4360         END_OF_SMB
4361
4362         return offset;
4363 }
4364
4365 static int
4366 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4367     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4368 {
4369         return dissect_search_find_request(tvb, pinfo, tree, offset,
4370             smb_tree, FALSE);
4371 }
4372
4373 static int
4374 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4375     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4376 {
4377         return dissect_search_find_request(tvb, pinfo, tree, offset,
4378             smb_tree, TRUE);
4379 }
4380
4381 static int
4382 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4383     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4384 {
4385         return dissect_search_find_request(tvb, pinfo, tree, offset,
4386             smb_tree, TRUE);
4387 }
4388
4389 static int
4390 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4391     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4392     gboolean has_find_id)
4393 {
4394         guint16 count=0;
4395         guint8 wc;
4396         guint16 bc;
4397         gboolean trunc;
4398
4399         WORD_COUNT;
4400
4401         /* count */
4402         count = tvb_get_letohs(tvb, offset);
4403         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4404         offset += 2;
4405
4406         BYTE_COUNT;
4407
4408         /* buffer format */
4409         CHECK_BYTE_COUNT(1);
4410         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4411         COUNT_BYTES(1);
4412
4413         /* data len */
4414         CHECK_BYTE_COUNT(2);
4415         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4416         COUNT_BYTES(2);
4417
4418         while(count--){
4419                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4420                     &bc, &trunc, has_find_id);
4421                 if (trunc)
4422                         goto endofcommand;
4423         }
4424
4425         END_OF_SMB
4426
4427         return offset;
4428 }
4429
4430 static int
4431 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4432 {
4433         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4434             FALSE);
4435 }
4436
4437 static int
4438 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4439 {
4440         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4441             TRUE);
4442 }
4443
4444 static int
4445 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4446     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4447 {
4448         guint8 wc;
4449         guint16 bc;
4450         guint16 data_len;
4451
4452         WORD_COUNT;
4453
4454         /* reserved */
4455         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4456         offset += 2;
4457
4458         BYTE_COUNT;
4459
4460         /* buffer format */
4461         CHECK_BYTE_COUNT(1);
4462         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4463         COUNT_BYTES(1);
4464
4465         /* data len */
4466         CHECK_BYTE_COUNT(2);
4467         data_len = tvb_get_ntohs(tvb, offset);
4468         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4469         COUNT_BYTES(2);
4470
4471         if (data_len != 0) {
4472                 CHECK_BYTE_COUNT(data_len);
4473                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4474                     data_len, TRUE);
4475                 COUNT_BYTES(data_len);
4476         }
4477
4478         END_OF_SMB
4479
4480         return offset;
4481 }
4482
4483 static const value_string locking_ol_vals[] = {
4484         {0,     "Client is not holding oplock on this file"},
4485         {1,     "Level 2 oplock currently held by client"},
4486         {0, NULL}
4487 };
4488
4489 static const true_false_string tfs_lock_type_large = {
4490         "Large file locking format requested",
4491         "Large file locking format not requested"
4492 };
4493 static const true_false_string tfs_lock_type_cancel = {
4494         "Cancel outstanding lock request",
4495         "Don't cancel outstanding lock request"
4496 };
4497 static const true_false_string tfs_lock_type_change = {
4498         "Change lock type",
4499         "Don't change lock type"
4500 };
4501 static const true_false_string tfs_lock_type_oplock = {
4502         "This is an oplock break notification/response",
4503         "This is not an oplock break notification/response"
4504 };
4505 static const true_false_string tfs_lock_type_shared = {
4506         "This is a shared lock",
4507         "This is an exclusive lock"
4508 };
4509 static int
4510 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4511 {
4512         guint8  wc, cmd=0xff, lt=0;
4513         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4514         guint32 to;
4515         proto_item *litem = NULL;
4516         proto_tree *ltree = NULL;
4517         proto_item *it = NULL;
4518         proto_tree *tr = NULL;
4519         int old_offset = offset;
4520
4521         WORD_COUNT;
4522
4523         /* next smb command */
4524         cmd = tvb_get_guint8(tvb, offset);
4525         if(cmd!=0xff){
4526                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4527         } else {
4528                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4529         }
4530         offset += 1;
4531
4532         /* reserved byte */
4533         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4534         offset += 1;
4535
4536         /* andxoffset */
4537         andxoffset = tvb_get_letohs(tvb, offset);
4538         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4539         offset += 2;
4540
4541         /* fid */
4542         fid = tvb_get_letohs(tvb, offset);
4543         add_fid(tvb, pinfo, tree, offset, 2, fid);
4544         offset += 2;
4545
4546         /* lock type */
4547         lt = tvb_get_guint8(tvb, offset);
4548         if(tree){
4549                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4550                         "Lock Type: 0x%02x", lt);
4551                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4552         }
4553         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4554                 tvb, offset, 1, lt);
4555         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4556                 tvb, offset, 1, lt);
4557         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4558                 tvb, offset, 1, lt);
4559         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4560                 tvb, offset, 1, lt);
4561         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4562                 tvb, offset, 1, lt);
4563         offset += 1;
4564
4565         /* oplock level */
4566         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4567         offset += 1;
4568
4569         /* timeout */
4570         to = tvb_get_letohl(tvb, offset);
4571         if (to == 0)
4572                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4573         else if (to == 0xffffffff)
4574                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4575         else
4576                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4577         offset += 4;
4578
4579         /* number of unlocks */
4580         un = tvb_get_letohs(tvb, offset);
4581         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4582         offset += 2;
4583
4584         /* number of locks */
4585         ln = tvb_get_letohs(tvb, offset);
4586         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4587         offset += 2;
4588
4589         BYTE_COUNT;
4590
4591         /* unlocks */
4592         if(un){
4593                 old_offset = offset;
4594
4595                 it = proto_tree_add_text(tree, tvb, offset, -1,
4596                         "Unlocks");
4597                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4598                 while(un--){
4599                         proto_item *litem = NULL;
4600                         proto_tree *ltree = NULL;
4601                         if(lt&0x10){
4602                                 /* large lock format */
4603                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4604                                         "Unlock");
4605                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4606                                 
4607                                 /* PID */
4608                                 CHECK_BYTE_COUNT(2);
4609                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4610                                 COUNT_BYTES(2);
4611
4612                                 /* 2 reserved bytes */
4613                                 CHECK_BYTE_COUNT(2);
4614                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4615                                 COUNT_BYTES(2);
4616
4617                                 /* offset */
4618                                 CHECK_BYTE_COUNT(8);
4619                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4620                                 COUNT_BYTES(8);
4621
4622                                 /* length */
4623                                 CHECK_BYTE_COUNT(8);
4624                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4625                                 COUNT_BYTES(8);
4626                         } else {
4627                                 /* normal lock format */
4628                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4629                                         "Unlock");
4630                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4631                                 
4632                                 /* PID */
4633                                 CHECK_BYTE_COUNT(2);
4634                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4635                                 COUNT_BYTES(2);
4636
4637                                 /* offset */
4638                                 CHECK_BYTE_COUNT(4);
4639                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4640                                 COUNT_BYTES(4);
4641
4642                                 /* lock count */
4643                                 CHECK_BYTE_COUNT(4);
4644                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4645                                 COUNT_BYTES(4);
4646                         }
4647                 }
4648                 proto_item_set_len(it, offset-old_offset);
4649                 it = NULL;
4650         }
4651
4652         /* locks */
4653         if(ln){
4654                 old_offset = offset;
4655
4656                 it = proto_tree_add_text(tree, tvb, offset, -1,
4657                         "Locks");
4658                 tr = proto_item_add_subtree(it, ett_smb_locks);
4659                 while(ln--){
4660                         proto_item *litem = NULL;
4661                         proto_tree *ltree = NULL;
4662                         if(lt&0x10){
4663                                 /* large lock format */
4664                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4665                                         "Lock");
4666                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4667                                 
4668                                 /* PID */
4669                                 CHECK_BYTE_COUNT(2);
4670                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4671                                 COUNT_BYTES(2);
4672
4673                                 /* 2 reserved bytes */
4674                                 CHECK_BYTE_COUNT(2);
4675                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4676                                 COUNT_BYTES(2);
4677
4678                                 /* offset */
4679                                 CHECK_BYTE_COUNT(8);
4680                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4681                                 COUNT_BYTES(8);
4682
4683                                 /* length */
4684                                 CHECK_BYTE_COUNT(8);
4685                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4686                                 COUNT_BYTES(8);
4687                         } else {
4688                                 /* normal lock format */
4689                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4690                                         "Unlock");
4691                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4692                                 
4693                                 /* PID */
4694                                 CHECK_BYTE_COUNT(2);
4695                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4696                                 COUNT_BYTES(2);
4697
4698                                 /* offset */
4699                                 CHECK_BYTE_COUNT(4);
4700                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4701                                 COUNT_BYTES(4);
4702
4703                                 /* lock count */
4704                                 CHECK_BYTE_COUNT(4);
4705                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4706                                 COUNT_BYTES(4);
4707                         }
4708                 }
4709                 proto_item_set_len(it, offset-old_offset);
4710                 it = NULL;
4711         }
4712
4713         END_OF_SMB
4714
4715         if (it != NULL) {
4716                 /*
4717                  * We ran out of byte count in the middle of dissecting
4718                  * the locks or the unlocks; set the site of the item
4719                  * we were dissecting.
4720                  */
4721                 proto_item_set_len(it, offset-old_offset);
4722         }
4723
4724         /* call AndXCommand (if there are any) */
4725         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4726
4727         return offset;
4728 }
4729
4730 static int
4731 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4732 {
4733         guint8  wc, cmd=0xff;
4734         guint16 andxoffset=0;
4735         guint16 bc;
4736
4737         WORD_COUNT;
4738
4739         /* next smb command */
4740         cmd = tvb_get_guint8(tvb, offset);
4741         if(cmd!=0xff){
4742                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4743         } else {
4744                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4745         }
4746         offset += 1;
4747
4748         /* reserved byte */
4749         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4750         offset += 1;
4751
4752         /* andxoffset */
4753         andxoffset = tvb_get_letohs(tvb, offset);
4754         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4755         offset += 2;
4756
4757         BYTE_COUNT;
4758
4759         END_OF_SMB
4760
4761         /* call AndXCommand (if there are any) */
4762         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4763
4764         return offset;
4765 }
4766
4767
4768 static const value_string oa_open_vals[] = {
4769         { 0,            "No action taken?"},
4770         { 1,            "The file existed and was opened"},
4771         { 2,            "The file did not exist but was created"},
4772         { 3,            "The file existed and was truncated"},
4773         {0,     NULL}
4774 };
4775 static const true_false_string tfs_oa_lock = {
4776         "File is currently opened only by this user",
4777         "File is opened by another user (or mode not supported by server)"
4778 };
4779 static int
4780 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4781 {
4782         guint16 mask;
4783         proto_item *item = NULL;
4784         proto_tree *tree = NULL;
4785
4786         mask = tvb_get_letohs(tvb, offset);
4787
4788         if(parent_tree){
4789                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4790                         "Action: 0x%04x", mask);
4791                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4792         }
4793
4794         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4795                 tvb, offset, 2, mask);
4796         proto_tree_add_uint(tree, hf_smb_open_action_open,
4797                 tvb, offset, 2, mask);
4798
4799         offset += 2;
4800
4801         return offset;
4802 }
4803
4804 static const true_false_string tfs_open_flags_add_info = {
4805         "Additional information requested",
4806         "Additional information not requested"
4807 };
4808 static const true_false_string tfs_open_flags_ex_oplock = {
4809         "Exclusive oplock requested",
4810         "Exclusive oplock not requested"
4811 };
4812 static const true_false_string tfs_open_flags_batch_oplock = {
4813         "Batch oplock requested",
4814         "Batch oplock not requested"
4815 };
4816 static const true_false_string tfs_open_flags_ealen = {
4817         "Total length of EAs requested",
4818         "Total length of EAs not requested"
4819 };
4820 static int
4821 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4822 {
4823         guint16 mask;
4824         proto_item *item = NULL;
4825         proto_tree *tree = NULL;
4826
4827         mask = tvb_get_letohs(tvb, offset);
4828
4829         if(parent_tree){
4830                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4831                         "Flags: 0x%04x", mask);
4832                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4833         }
4834
4835         if(bm&0x0001){
4836                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4837                         tvb, offset, 2, mask);
4838         }
4839         if(bm&0x0002){
4840                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4841                         tvb, offset, 2, mask);
4842         }
4843         if(bm&0x0004){
4844                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4845                         tvb, offset, 2, mask);
4846         }
4847         if(bm&0x0008){
4848                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4849                         tvb, offset, 2, mask);
4850         }
4851
4852         offset += 2;
4853
4854         return offset;
4855 }
4856
4857 static const value_string filetype_vals[] = {
4858         { 0,            "Disk file or directory"},
4859         { 1,            "Named pipe in byte mode"},
4860         { 2,            "Named pipe in message mode"},
4861         { 3,            "Spooled printer"},
4862         {0, NULL}
4863 };
4864 static int
4865 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4866 {
4867         guint8  wc, cmd=0xff;
4868         guint16 andxoffset=0, bc;
4869         int fn_len;
4870         const char *fn;
4871
4872         WORD_COUNT;
4873
4874         /* next smb command */
4875         cmd = tvb_get_guint8(tvb, offset);
4876         if(cmd!=0xff){
4877                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4878         } else {
4879                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4880         }
4881         offset += 1;
4882
4883         /* reserved byte */
4884         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4885         offset += 1;
4886
4887         /* andxoffset */
4888         andxoffset = tvb_get_letohs(tvb, offset);
4889         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4890         offset += 2;
4891
4892         /* open flags */
4893         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
4894
4895         /* desired access */
4896         offset = dissect_access(tvb, tree, offset, "Desired");
4897
4898         /* Search Attributes */
4899         offset = dissect_search_attributes(tvb, tree, offset);
4900
4901         /* File Attributes */
4902         offset = dissect_file_attributes(tvb, tree, offset);
4903
4904         /* creation time */
4905         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4906         
4907         /* open function */
4908         offset = dissect_open_function(tvb, tree, offset);
4909
4910         /* allocation size */
4911         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4912         offset += 4;
4913
4914         /* 8 reserved bytes */
4915         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4916         offset += 8;
4917
4918         BYTE_COUNT;
4919
4920         /* file name */
4921         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4922                 FALSE, FALSE, &bc);
4923         if (fn == NULL)
4924                 goto endofcommand;
4925         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4926                 fn);
4927         COUNT_BYTES(fn_len);
4928
4929         if (check_col(pinfo->cinfo, COL_INFO)) {
4930                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4931         }
4932
4933         END_OF_SMB
4934
4935         /* call AndXCommand (if there are any) */
4936         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
4937
4938         return offset;
4939 }
4940
4941 static const true_false_string tfs_ipc_state_nonblocking = {
4942         "Reads/writes return immediately if no data available",
4943         "Reads/writes block if no data available"
4944 };
4945 static const value_string ipc_state_endpoint_vals[] = {
4946         { 0,            "Consumer end of pipe"},
4947         { 1,            "Server end of pipe"},
4948         {0,     NULL}
4949 };
4950 static const value_string ipc_state_pipe_type_vals[] = {
4951         { 0,            "Byte stream pipe"},
4952         { 1,            "Message pipe"},
4953         {0,     NULL}
4954 };
4955 static const value_string ipc_state_read_mode_vals[] = {
4956         { 0,            "Read pipe as a byte stream"},
4957         { 1,            "Read messages from pipe"},
4958         {0,     NULL}
4959 };
4960
4961 int
4962 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
4963     gboolean setstate)
4964 {
4965         guint16 mask;
4966         proto_item *item = NULL;
4967         proto_tree *tree = NULL;
4968
4969         mask = tvb_get_letohs(tvb, offset);
4970
4971         if(parent_tree){
4972                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4973                         "IPC State: 0x%04x", mask);
4974                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4975         }
4976
4977         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4978                 tvb, offset, 2, mask);
4979         if (!setstate) {
4980                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4981                         tvb, offset, 2, mask);
4982                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4983                         tvb, offset, 2, mask);
4984         }
4985         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4986                 tvb, offset, 2, mask);
4987         if (!setstate) {
4988                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4989                         tvb, offset, 2, mask);
4990         }
4991
4992         offset += 2;
4993
4994         return offset;
4995 }
4996
4997 static int
4998 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4999 {
5000         guint8  wc, cmd=0xff;
5001         guint16 andxoffset=0, bc;
5002         guint16 fid;
5003
5004         WORD_COUNT;
5005
5006         /* next smb command */
5007         cmd = tvb_get_guint8(tvb, offset);
5008         if(cmd!=0xff){
5009                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5010         } else {
5011                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5012         }
5013         offset += 1;
5014
5015         /* reserved byte */
5016         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5017         offset += 1;
5018
5019         /* andxoffset */
5020         andxoffset = tvb_get_letohs(tvb, offset);
5021         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5022         offset += 2;
5023
5024         /* fid */
5025         fid = tvb_get_letohs(tvb, offset);
5026         add_fid(tvb, pinfo, tree, offset, 2, fid);
5027         offset += 2;
5028
5029         /* File Attributes */
5030         offset = dissect_file_attributes(tvb, tree, offset);
5031
5032         /* last write time */
5033         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5034         
5035         /* File Size */
5036         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5037         offset += 4;
5038
5039         /* granted access */
5040         offset = dissect_access(tvb, tree, offset, "Granted");
5041
5042         /* File Type */
5043         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5044         offset += 2;
5045
5046         /* IPC State */
5047         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5048
5049         /* open_action */
5050         offset = dissect_open_action(tvb, tree, offset);
5051
5052         /* server fid */
5053         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5054         offset += 4;
5055
5056         /* 2 reserved bytes */
5057         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5058         offset += 2;
5059
5060         BYTE_COUNT;
5061
5062         END_OF_SMB
5063
5064         /* call AndXCommand (if there are any) */
5065         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5066
5067         return offset;
5068 }
5069
5070 static int
5071 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5072 {
5073         guint8  wc, cmd=0xff;
5074         guint16 andxoffset=0, bc, maxcnt = 0;
5075         guint32 ofs = 0;
5076         smb_info_t *si;
5077         unsigned int fid;
5078
5079         WORD_COUNT;
5080
5081         /* next smb command */
5082         cmd = tvb_get_guint8(tvb, offset);
5083         if(cmd!=0xff){
5084                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5085         } else {
5086                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5087         }
5088         offset += 1;
5089
5090         /* reserved byte */
5091         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5092         offset += 1;
5093
5094         /* andxoffset */
5095         andxoffset = tvb_get_letohs(tvb, offset);
5096         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5097         offset += 2;
5098
5099         /* fid */
5100         fid = tvb_get_letohs(tvb, offset);
5101         add_fid(tvb, pinfo, tree, offset, 2, fid);
5102         offset += 2;
5103         if (!pinfo->fd->flags.visited) {
5104                 /* remember the FID for the processing of the response */
5105                 si = (smb_info_t *)pinfo->private_data;
5106                 si->sip->extra_info=(void *)fid;
5107         }
5108
5109         /* offset */
5110         ofs = tvb_get_letohl(tvb, offset);
5111         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5112         offset += 4;
5113
5114         /* max count */
5115         maxcnt = tvb_get_letohs(tvb, offset);
5116         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5117         offset += 2;
5118
5119         if (check_col(pinfo->cinfo, COL_INFO))
5120                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5121                                 ", %d byte%s at offset %d", maxcnt, 
5122                                 (maxcnt == 1) ? "" : "s", ofs);
5123
5124         /* min count */
5125         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5126         offset += 2;
5127
5128         /* XXX - max count high */
5129         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5130         offset += 4;
5131
5132         /* remaining */
5133         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5134         offset += 2;
5135
5136         if(wc==12){
5137                 /* high offset */
5138                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5139                 offset += 4;
5140         }
5141
5142         BYTE_COUNT;
5143
5144         END_OF_SMB
5145
5146         /* call AndXCommand (if there are any) */
5147         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5148
5149         return offset;
5150 }
5151
5152 static int
5153 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5154 {
5155         guint8  wc, cmd=0xff;
5156         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5157         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5158         int fid=0;
5159
5160         WORD_COUNT;
5161
5162         /* next smb command */
5163         cmd = tvb_get_guint8(tvb, offset);
5164         if(cmd!=0xff){
5165                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5166         } else {
5167                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5168         }
5169         offset += 1;
5170  
5171         /* reserved byte */
5172         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5173         offset += 1;
5174
5175         /* andxoffset */
5176         andxoffset = tvb_get_letohs(tvb, offset);
5177         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5178         offset += 2;
5179
5180         /* If we have seen the request, then print which FID this refers to */
5181         /* first check if we have seen the request */
5182         if(si->sip != NULL && si->sip->frame_req>0){
5183                 fid=(int)si->sip->extra_info;
5184                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5185         }
5186
5187         /* remaining */
5188         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5189         offset += 2;
5190
5191         /* data compaction mode */
5192         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5193         offset += 2;
5194
5195         /* 2 reserved bytes */
5196         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5197         offset += 2;
5198
5199         /* data len */
5200         datalen = tvb_get_letohs(tvb, offset);
5201         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5202         offset += 2;
5203
5204         if (check_col(pinfo->cinfo, COL_INFO))
5205                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5206                                 ", %d byte%s", datalen, 
5207                                 (datalen == 1) ? "" : "s");
5208
5209         /* data offset */
5210         dataoffset=tvb_get_letohs(tvb, offset);
5211         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5212         offset += 2;
5213
5214         /* 10 reserved bytes */
5215         /* XXX - first 2 bytes are data length high, not reserved */
5216         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5217         offset += 10;
5218
5219         BYTE_COUNT;
5220
5221         /* is this part of DCERPC over SMB reassembly?*/
5222         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
5223             && (bc<=tvb_length_remaining(tvb, offset)) ){
5224                 gpointer hash_value;
5225                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
5226                                                 si->ct->dcerpc_fid_to_frame,
5227                                                 si->sip->extra_info)) != NULL) {
5228                         fragment_data *fd_head;
5229                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5230
5231                         /* first fragment is always from a SMB Trans command and
5232                            offset 0 of the following read/write SMB commands start
5233                            BEYOND the first Trans SMB payload. Look for offset
5234                            in first read fragment */
5235                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5236                         if(fd_head){
5237                                 /* skip to last fragment  and add this data there*/
5238                                 while(fd_head->next){
5239                                         fd_head=fd_head->next;
5240                                 }
5241                                 /* if dataoffset was not specified in the SMB command
5242                                    then we try to guess it as good as we can
5243                                 */
5244                                 if(dataoffset==0){
5245                                         dataoffset=offset+bc-datalen;
5246                                 }
5247                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5248                                         frame, dcerpc_fragment_table,
5249                                         fd_head->offset+fd_head->len, 
5250                                         datalen, TRUE);
5251                                 /* we completed reassembly, abort searching for more 
5252                                    fragments*/
5253                                 if(fd_head){
5254                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5255                                                 si->sip->extra_info);   
5256                                 }
5257                         }
5258                 }
5259         }
5260
5261         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
5262            read write */
5263         if(bc){
5264                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
5265                         /* dcerpc call */
5266                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5267                             top_tree, offset, bc, datalen, fid);
5268                 } else {
5269                         /* ordinary file data, or we didn't see the request,
5270                            so we don't know whether this is a DCERPC call
5271                            or not */
5272                         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5273                 }
5274                 bc = 0;
5275         }
5276
5277         END_OF_SMB
5278
5279         /* call AndXCommand (if there are any) */
5280         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5281
5282         return offset;
5283 }
5284
5285 static int
5286 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5287 {
5288         guint32 ofs=0;
5289         guint8  wc, cmd=0xff;
5290         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5291         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5292         unsigned int fid=0;
5293
5294         WORD_COUNT;
5295
5296         /* next smb command */
5297         cmd = tvb_get_guint8(tvb, offset);
5298         if(cmd!=0xff){
5299                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5300         } else {
5301                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5302         }
5303         offset += 1;
5304
5305         /* reserved byte */
5306         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5307         offset += 1;
5308
5309         /* andxoffset */
5310         andxoffset = tvb_get_letohs(tvb, offset);
5311         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5312         offset += 2;
5313
5314         /* fid */
5315         fid = tvb_get_letohs(tvb, offset);
5316         add_fid(tvb, pinfo, tree, offset, 2, fid);
5317         offset += 2;
5318         if (!pinfo->fd->flags.visited) {
5319                 /* remember the FID for the processing of the response */
5320                 si->sip->extra_info=(void *)fid;
5321         }
5322
5323         /* offset */
5324         ofs = tvb_get_letohl(tvb, offset);
5325         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5326         offset += 4;
5327
5328         /* reserved */
5329         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5330         offset += 4;
5331
5332         /* mode */
5333         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5334
5335         /* remaining */
5336         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5337         offset += 2;
5338
5339         /* XXX - data length high */
5340         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5341         offset += 2;
5342
5343         /* data len */
5344         datalen = tvb_get_letohs(tvb, offset);
5345         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5346         offset += 2;
5347
5348         /* data offset */
5349         dataoffset=tvb_get_letohs(tvb, offset);
5350         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5351         offset += 2;
5352
5353         /* FIXME: add byte/offset to COL_INFO */
5354
5355         if(wc==14){
5356                 /* high offset */
5357                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5358                 offset += 4;
5359         }
5360
5361         BYTE_COUNT;
5362
5363         /* is this part of DCERPC over SMB reassembly?*/
5364         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5365                 gpointer hash_value;
5366                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5367                         si->sip->extra_info);
5368                 if(hash_value){
5369                         fragment_data *fd_head;
5370                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5371
5372                         /* first fragment is always from a SMB Trans command and
5373                            offset 0 of the following read/write SMB commands start
5374                            BEYOND the first Trans SMB payload. Look for offset
5375                            in first read fragment */
5376                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5377                         if(fd_head){
5378                                 /* skip to last fragment  and add this data there*/
5379                                 while(fd_head->next){
5380                                         fd_head=fd_head->next;
5381                                 }
5382                                 /* if dataoffset was not specified in the SMB command
5383                                    then we try to guess it as good as we can
5384                                 */
5385                                 if(dataoffset==0){
5386                                         dataoffset=offset+bc-datalen;
5387                                 }
5388                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5389                                         frame, dcerpc_fragment_table,
5390                                         fd_head->offset+fd_head->len, 
5391                                         datalen, TRUE);
5392                                 /* we completed reassembly, abort searching for more 
5393                                    fragments*/
5394                                 if(fd_head){
5395                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5396                                                 si->sip->extra_info);   
5397                                 }
5398                         }
5399                 }
5400         }
5401
5402         /* file data */
5403         if (bc != 0) {
5404                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5405                         /* dcerpc call */
5406                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5407                             top_tree, offset, bc, datalen, fid);
5408                 } else {
5409                         /* ordinary file data */
5410                         offset = dissect_file_data(tvb, tree, offset,
5411                             bc, datalen);
5412                 }
5413                 bc = 0;
5414         }
5415
5416         END_OF_SMB
5417
5418         /* call AndXCommand (if there are any) */
5419         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5420
5421         return offset;
5422 }
5423
5424 static int
5425 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5426 {
5427         guint8  wc, cmd=0xff;
5428         guint16 andxoffset=0, bc;
5429         smb_info_t *si;
5430
5431         WORD_COUNT;
5432
5433         /* next smb command */
5434         cmd = tvb_get_guint8(tvb, offset);
5435         if(cmd!=0xff){
5436                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5437         } else {
5438                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5439         }
5440         offset += 1;
5441  
5442         /* reserved byte */
5443         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5444         offset += 1;
5445
5446         /* andxoffset */
5447         andxoffset = tvb_get_letohs(tvb, offset);
5448         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5449         offset += 2;
5450
5451         /* If we have seen the request, then print which FID this refers to */
5452         si = (smb_info_t *)pinfo->private_data;
5453         /* first check if we have seen the request */
5454         if(si->sip != NULL && si->sip->frame_req>0){
5455                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5456         }
5457
5458         /* write count */
5459         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5460         offset += 2;
5461
5462         /* remaining */
5463         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5464         offset += 2;
5465
5466         /* 4 reserved bytes */
5467         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5468         offset += 4;
5469
5470         BYTE_COUNT;
5471
5472         END_OF_SMB
5473
5474         /* call AndXCommand (if there are any) */
5475         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5476
5477         return offset;
5478 }
5479
5480
5481 static const true_false_string tfs_setup_action_guest = {
5482         "Logged in as GUEST",
5483         "Not logged in as GUEST"
5484 };
5485 static int
5486 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5487 {
5488         guint16 mask;
5489         proto_item *item = NULL;
5490         proto_tree *tree = NULL;
5491
5492         mask = tvb_get_letohs(tvb, offset);
5493
5494         if(parent_tree){
5495                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5496                         "Action: 0x%04x", mask);
5497                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5498         }
5499
5500         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5501                 tvb, offset, 2, mask);
5502
5503         offset += 2;
5504
5505         return offset;
5506 }
5507  
5508
5509 static int
5510 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5511 {
5512         guint8  wc, cmd=0xff;
5513         guint16 bc;
5514         guint16 andxoffset=0;
5515         int an_len;
5516         const char *an;
5517         int dn_len;
5518         const char *dn;
5519         guint16 pwlen=0;
5520         guint16 sbloblen=0;
5521         guint16 apwlen=0, upwlen=0;
5522
5523         WORD_COUNT;
5524
5525         /* next smb command */
5526         cmd = tvb_get_guint8(tvb, offset);
5527         if(cmd!=0xff){
5528                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5529         } else {
5530                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5531         }
5532         offset += 1;
5533
5534         /* reserved byte */
5535         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5536         offset += 1;
5537
5538         /* andxoffset */
5539         andxoffset = tvb_get_letohs(tvb, offset);
5540         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5541         offset += 2;
5542
5543         /* Maximum Buffer Size */
5544         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5545         offset += 2;
5546
5547         /* Maximum Multiplex Count */
5548         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5549         offset += 2;
5550
5551         /* VC Number */
5552         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5553         offset += 2;
5554
5555         /* session key */
5556         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5557         offset += 4;
5558
5559         switch (wc) {
5560         case 10:
5561                 /* password length, ASCII*/
5562                 pwlen = tvb_get_letohs(tvb, offset);
5563                 proto_tree_add_uint(tree, hf_smb_password_len,
5564                         tvb, offset, 2, pwlen);
5565                 offset += 2;
5566
5567                 /* 4 reserved bytes */
5568                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5569                 offset += 4;
5570
5571                 break;
5572
5573         case 12:
5574                 /* security blob length */
5575                 sbloblen = tvb_get_letohs(tvb, offset);
5576                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5577                 offset += 2;
5578
5579                 /* 4 reserved bytes */
5580                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5581                 offset += 4;
5582
5583                 /* capabilities */
5584                 dissect_negprot_capabilities(tvb, tree, offset);
5585                 offset += 4;
5586
5587                 break;
5588
5589         case 13:
5590                 /* password length, ANSI*/
5591                 apwlen = tvb_get_letohs(tvb, offset);
5592                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5593                         tvb, offset, 2, apwlen);
5594                 offset += 2;
5595
5596                 /* password length, Unicode*/
5597                 upwlen = tvb_get_letohs(tvb, offset);
5598                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5599                         tvb, offset, 2, upwlen);
5600                 offset += 2;
5601
5602                 /* 4 reserved bytes */
5603                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5604                 offset += 4;
5605
5606                 /* capabilities */
5607                 dissect_negprot_capabilities(tvb, tree, offset);
5608                 offset += 4;
5609
5610                 break;
5611         }
5612
5613         BYTE_COUNT;
5614
5615         if (wc==12) {
5616                 /* security blob */
5617                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5618                    data structure, at least in NT 5.0-and-later
5619                    server replies? */
5620                 if(sbloblen){
5621                         CHECK_BYTE_COUNT(sbloblen);
5622                         proto_tree_add_item(tree, hf_smb_security_blob,
5623                                 tvb, offset, sbloblen, TRUE);
5624                         COUNT_BYTES(sbloblen);
5625                 }
5626
5627                 /* OS */
5628                 an = get_unicode_or_ascii_string(tvb, &offset,
5629                         pinfo, &an_len, FALSE, FALSE, &bc);
5630                 if (an == NULL)
5631                         goto endofcommand;
5632                 proto_tree_add_string(tree, hf_smb_os, tvb,
5633                         offset, an_len, an);
5634                 COUNT_BYTES(an_len);
5635
5636                 /* LANMAN */
5637                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5638                  * padding/null string/whatever in front of this. W2K doesn't
5639                  * appear to. I suspect that's a bug that got fixed; I also
5640                  * suspect that, in practice, nobody ever looks at that field
5641                  * because the bug didn't appear to get fixed until NT 5.0....
5642                  */
5643                 an = get_unicode_or_ascii_string(tvb, &offset,
5644                         pinfo, &an_len, FALSE, FALSE, &bc);
5645                 if (an == NULL)
5646                         goto endofcommand;
5647                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5648                         offset, an_len, an);
5649                 COUNT_BYTES(an_len);
5650
5651                 /* Primary domain */
5652                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5653                  * byte in front of this, at least if all the strings are
5654                  * ASCII and the account name is empty. Another bug?
5655                  */
5656                 dn = get_unicode_or_ascii_string(tvb, &offset,
5657                         pinfo, &dn_len, FALSE, FALSE, &bc);
5658                 if (dn == NULL)
5659                         goto endofcommand;
5660                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5661                         offset, dn_len, dn);
5662                 COUNT_BYTES(dn_len);
5663         } else {
5664                 switch (wc) {
5665
5666                 case 10:
5667                         if(pwlen){
5668                                 /* password, ASCII */
5669                                 CHECK_BYTE_COUNT(pwlen);
5670                                 proto_tree_add_item(tree, hf_smb_password, 
5671                                         tvb, offset, pwlen, TRUE);
5672                                 COUNT_BYTES(pwlen);
5673                         }
5674
5675                         break;
5676
5677                 case 13:
5678                         if(apwlen){
5679                                 /* password, ANSI */
5680                                 CHECK_BYTE_COUNT(apwlen);
5681                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5682                                         tvb, offset, apwlen, TRUE);
5683                                 COUNT_BYTES(apwlen);
5684                         }
5685
5686                         if(upwlen){
5687                                 /* password, Unicode */
5688                                 CHECK_BYTE_COUNT(upwlen);
5689                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5690                                         tvb, offset, upwlen, TRUE);
5691                                 COUNT_BYTES(upwlen);
5692                         }
5693
5694                         break;
5695                 }
5696
5697                 /* Account Name */
5698                 an = get_unicode_or_ascii_string(tvb, &offset,
5699                         pinfo, &an_len, FALSE, FALSE, &bc);
5700                 if (an == NULL)
5701                         goto endofcommand;
5702                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5703                         an);
5704                 COUNT_BYTES(an_len);
5705
5706                 /* Primary domain */
5707                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5708                  * byte in front of this, at least if all the strings are
5709                  * ASCII and the account name is empty. Another bug?
5710                  */
5711                 dn = get_unicode_or_ascii_string(tvb, &offset,
5712                         pinfo, &dn_len, FALSE, FALSE, &bc);
5713                 if (dn == NULL)
5714                         goto endofcommand;
5715                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5716                         offset, dn_len, dn);
5717                 COUNT_BYTES(dn_len);
5718
5719                 if (check_col(pinfo->cinfo, COL_INFO)) {
5720                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5721
5722                         if (!dn[0] && !an[0])
5723                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5724                                                 "anonymous");
5725                         else
5726                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5727                                                 "%s\\%s", dn,an);
5728                 }
5729
5730                 /* OS */
5731                 an = get_unicode_or_ascii_string(tvb, &offset,
5732                         pinfo, &an_len, FALSE, FALSE, &bc);
5733                 if (an == NULL)
5734                         goto endofcommand;
5735                 proto_tree_add_string(tree, hf_smb_os, tvb,
5736                         offset, an_len, an);
5737                 COUNT_BYTES(an_len);
5738
5739                 /* LANMAN */
5740                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5741                  * padding/null string/whatever in front of this. W2K doesn't
5742                  * appear to. I suspect that's a bug that got fixed; I also
5743                  * suspect that, in practice, nobody ever looks at that field
5744                  * because the bug didn't appear to get fixed until NT 5.0....
5745                  */
5746                 an = get_unicode_or_ascii_string(tvb, &offset,
5747                         pinfo, &an_len, FALSE, FALSE, &bc);
5748                 if (an == NULL)
5749                         goto endofcommand;
5750                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5751                         offset, an_len, an);
5752                 COUNT_BYTES(an_len);
5753         }
5754
5755         END_OF_SMB
5756
5757         /* call AndXCommand (if there are any) */
5758         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5759
5760         return offset;
5761 }
5762
5763 static int
5764 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5765 {
5766         guint8  wc, cmd=0xff;
5767         guint16 andxoffset=0, bc;
5768         guint16 sbloblen=0;
5769         int an_len;
5770         const char *an;
5771
5772         WORD_COUNT;
5773
5774         /* next smb command */
5775         cmd = tvb_get_guint8(tvb, offset);
5776         if(cmd!=0xff){
5777                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5778         } else {
5779                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5780         }
5781         offset += 1;
5782
5783         /* reserved byte */
5784         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5785         offset += 1;
5786
5787         /* andxoffset */
5788         andxoffset = tvb_get_letohs(tvb, offset);
5789         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5790         offset += 2;
5791
5792         /* flags */
5793         offset = dissect_setup_action(tvb, tree, offset);
5794
5795         if(wc==4){
5796                 /* security blob length */
5797                 sbloblen = tvb_get_letohs(tvb, offset);
5798                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5799                 offset += 2;
5800         }
5801
5802         BYTE_COUNT;
5803
5804         if(wc==4) {
5805                 /* security blob */
5806                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5807                    data structure, at least in NT 5.0-and-later
5808                    server replies? */
5809                 if(sbloblen){
5810                         CHECK_BYTE_COUNT(sbloblen);
5811                         proto_tree_add_item(tree, hf_smb_security_blob,
5812                                 tvb, offset, sbloblen, TRUE);
5813                         COUNT_BYTES(sbloblen);
5814                 }
5815         }
5816
5817         /* OS */
5818         an = get_unicode_or_ascii_string(tvb, &offset,
5819                 pinfo, &an_len, FALSE, FALSE, &bc);
5820         if (an == NULL)
5821                 goto endofcommand;
5822         proto_tree_add_string(tree, hf_smb_os, tvb,
5823                 offset, an_len, an);
5824         COUNT_BYTES(an_len);
5825
5826         /* LANMAN */
5827         an = get_unicode_or_ascii_string(tvb, &offset,
5828                 pinfo, &an_len, FALSE, FALSE, &bc);
5829         if (an == NULL)
5830                 goto endofcommand;
5831         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5832                 offset, an_len, an);
5833         COUNT_BYTES(an_len);
5834
5835         if(wc==3) {
5836                 /* Primary domain */
5837                 an = get_unicode_or_ascii_string(tvb, &offset,
5838                         pinfo, &an_len, FALSE, FALSE, &bc);
5839                 if (an == NULL)
5840                         goto endofcommand;
5841                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5842                         offset, an_len, an);
5843                 COUNT_BYTES(an_len);
5844         }
5845
5846         END_OF_SMB
5847
5848         /* call AndXCommand (if there are any) */
5849         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5850
5851         return offset;
5852 }
5853
5854  
5855 static int
5856 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5857 {
5858         guint8  wc, cmd=0xff;
5859         guint16 andxoffset=0;
5860         guint16 bc;
5861
5862         WORD_COUNT;
5863
5864         /* next smb command */
5865         cmd = tvb_get_guint8(tvb, offset);
5866         if(cmd!=0xff){
5867                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5868         } else {
5869                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5870         }
5871         offset += 1;
5872
5873         /* reserved byte */
5874         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5875         offset += 1;
5876
5877         /* andxoffset */
5878         andxoffset = tvb_get_letohs(tvb, offset);
5879         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5880         offset += 2;
5881
5882         BYTE_COUNT;
5883
5884         END_OF_SMB
5885
5886         /* call AndXCommand (if there are any) */
5887         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
5888
5889         return offset;
5890 }
5891
5892  
5893 static const true_false_string tfs_connect_support_search = {
5894         "Exclusive search bits supported",
5895         "Exclusive search bits not supported"
5896 };
5897 static const true_false_string tfs_connect_support_in_dfs = {
5898         "Share is in Dfs",
5899         "Share isn't in Dfs"
5900 };
5901
5902 static int
5903 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5904 {
5905         guint16 mask;
5906         proto_item *item = NULL;
5907         proto_tree *tree = NULL;
5908
5909         mask = tvb_get_letohs(tvb, offset);
5910
5911         if(parent_tree){
5912                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5913                         "Optional Support: 0x%04x", mask);
5914                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5915         }
5916
5917         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5918                 tvb, offset, 2, mask);
5919         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5920                 tvb, offset, 2, mask);
5921
5922         offset += 2;
5923
5924         return offset;
5925 }
5926
5927 static const true_false_string tfs_disconnect_tid = {
5928         "DISCONNECT TID",
5929         "Do NOT disconnect TID"
5930 };
5931
5932 static int
5933 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5934 {
5935         guint16 mask;
5936         proto_item *item = NULL;
5937         proto_tree *tree = NULL;
5938
5939         mask = tvb_get_letohs(tvb, offset);
5940
5941         if(parent_tree){
5942                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5943                         "Flags: 0x%04x", mask);
5944                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5945         }
5946
5947         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5948                 tvb, offset, 2, mask);
5949
5950         offset += 2;
5951
5952         return offset;
5953 }
5954
5955 static int
5956 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5957 {
5958         guint8  wc, cmd=0xff;
5959         guint16 bc;
5960         guint16 andxoffset=0, pwlen=0;
5961         int an_len;
5962         const char *an;
5963
5964         WORD_COUNT;
5965
5966         /* next smb command */
5967         cmd = tvb_get_guint8(tvb, offset);
5968         if(cmd!=0xff){
5969                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5970         } else {
5971                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5972         }
5973         offset += 1;
5974
5975         /* reserved byte */
5976         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5977         offset += 1;
5978
5979         /* andxoffset */
5980         andxoffset = tvb_get_letohs(tvb, offset);
5981         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5982         offset += 2;
5983
5984         /* flags */
5985         offset = dissect_connect_flags(tvb, tree, offset);
5986
5987         /* password length*/
5988         pwlen = tvb_get_letohs(tvb, offset);
5989         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5990         offset += 2;
5991
5992         BYTE_COUNT;
5993
5994         /* password */
5995         CHECK_BYTE_COUNT(pwlen);
5996         proto_tree_add_item(tree, hf_smb_password, 
5997                 tvb, offset, pwlen, TRUE);
5998         COUNT_BYTES(pwlen);
5999
6000         /* Path */
6001         an = get_unicode_or_ascii_string(tvb, &offset,
6002                 pinfo, &an_len, FALSE, FALSE, &bc);
6003         if (an == NULL)
6004                 goto endofcommand;
6005         proto_tree_add_string(tree, hf_smb_path, tvb,
6006                 offset, an_len, an);
6007         COUNT_BYTES(an_len);
6008
6009         if (check_col(pinfo->cinfo, COL_INFO)) {
6010                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6011         }
6012
6013         /*
6014          * NOTE: the Service string is always ASCII, even if the
6015          * "strings are Unicode" bit is set in the flags2 field
6016          * of the SMB.
6017          */
6018
6019         /* Service */
6020         /* XXX - what if this runs past bc? */
6021         an_len = tvb_strsize(tvb, offset);
6022         CHECK_BYTE_COUNT(an_len);
6023         an = tvb_get_ptr(tvb, offset, an_len);
6024         proto_tree_add_string(tree, hf_smb_service, tvb,
6025                 offset, an_len, an);
6026         COUNT_BYTES(an_len);
6027
6028         END_OF_SMB
6029
6030         /* call AndXCommand (if there are any) */
6031         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
6032
6033         return offset;
6034 }
6035
6036
6037 static int
6038 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6039 {
6040         guint8  wc, wleft, cmd=0xff;
6041         guint16 andxoffset=0;
6042         guint16 bc;
6043         int an_len;
6044         const char *an;
6045
6046         WORD_COUNT;
6047
6048         wleft = wc;     /* this is at least 1 */
6049
6050         /* next smb command */
6051         cmd = tvb_get_guint8(tvb, offset);
6052         if(cmd!=0xff){
6053                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6054         } else {
6055                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6056         }
6057         offset += 1;
6058
6059         /* reserved byte */
6060         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6061         offset += 1;
6062
6063         wleft--;
6064         if (wleft == 0)
6065                 goto bytecount;
6066
6067         /* andxoffset */
6068         andxoffset = tvb_get_letohs(tvb, offset);
6069         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6070         offset += 2;
6071         wleft--;
6072         if (wleft == 0)
6073                 goto bytecount;
6074
6075         /* flags */
6076         offset = dissect_connect_support_bits(tvb, tree, offset);
6077         wleft--;
6078
6079         /* XXX - I've seen captures where this is 7, but I have no
6080            idea how to dissect it.  I'm guessing the third word
6081            contains connect support bits, which looks plausible
6082            from the values I've seen. */
6083
6084         while (wleft != 0) {
6085                 proto_tree_add_text(tree, tvb, offset, 2,
6086                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6087                 offset += 2;
6088                 wleft--;
6089         }
6090
6091         BYTE_COUNT;
6092
6093         /*
6094          * NOTE: even though the SNIA CIFS spec doesn't say there's
6095          * a "Service" string if there's a word count of 2, the
6096          * document at
6097          *
6098          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6099          *
6100          * (it's in an ugly format - text intended to be sent to a
6101          * printer, with backspaces and overstrikes used for boldfacing
6102          * and underlining; UNIX "col -b" can be used to strip the
6103          * overstrikes out) says there's a "Service" string there, and
6104          * some network traffic has it.
6105          */
6106
6107         /*
6108          * NOTE: the Service string is always ASCII, even if the
6109          * "strings are Unicode" bit is set in the flags2 field
6110          * of the SMB.
6111          */
6112
6113         /* Service */
6114         /* XXX - what if this runs past bc? */
6115         an_len = tvb_strsize(tvb, offset);
6116         CHECK_BYTE_COUNT(an_len);
6117         an = tvb_get_ptr(tvb, offset, an_len);
6118         proto_tree_add_string(tree, hf_smb_service, tvb,
6119                 offset, an_len, an);
6120         COUNT_BYTES(an_len);
6121
6122         /* Now when we know the service type, store it so that we know it for later commands down
6123            this tree */
6124         if(!pinfo->fd->flags.visited){
6125                 smb_info_t *si = (smb_info_t *)pinfo->private_data;
6126                 /* Remove any previous entry for this TID */
6127                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6128                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6129                 }
6130                 if(strcmp(an,"IPC") == 0){
6131                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6132                 } else {
6133                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6134                 }
6135         }
6136
6137
6138         if(wc==3){
6139                 if (bc != 0) {
6140                         /*
6141                          * Sometimes this isn't present.
6142                          */
6143
6144                         /* Native FS */
6145                         an = get_unicode_or_ascii_string(tvb, &offset,
6146                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
6147                         if (an == NULL)
6148                                 goto endofcommand;
6149                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6150                                 offset, an_len, an);
6151                         COUNT_BYTES(an_len);
6152                 }
6153         }
6154
6155         END_OF_SMB
6156
6157         /* call AndXCommand (if there are any) */
6158         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
6159
6160         return offset;
6161 }
6162
6163
6164
6165 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6166    NT Transaction command  begins here
6167    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6168 #define NT_TRANS_CREATE         1
6169 #define NT_TRANS_IOCTL          2
6170 #define NT_TRANS_SSD            3
6171 #define NT_TRANS_NOTIFY         4
6172 #define NT_TRANS_RENAME         5
6173 #define NT_TRANS_QSD            6
6174 #define NT_TRANS_GET_USER_QUOTA 7
6175 #define NT_TRANS_SET_USER_QUOTA 8
6176 static const value_string nt_cmd_vals[] = {
6177         {NT_TRANS_CREATE,               "NT CREATE"},
6178         {NT_TRANS_IOCTL,                "NT IOCTL"},
6179         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6180         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6181         {NT_TRANS_RENAME,               "NT RENAME"},
6182         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6183         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6184         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6185         {0, NULL}
6186 };
6187
6188 static const value_string nt_ioctl_isfsctl_vals[] = {
6189         {0,     "Device IOCTL"},
6190         {1,     "FS control : FSCTL"},
6191         {0, NULL}
6192 };
6193
6194 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6195 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6196         "Apply the command to share root handle (MUST BE Dfs)",
6197         "Apply to this share",
6198 };
6199
6200 static const value_string nt_notify_action_vals[] = {
6201         {1,     "ADDED (object was added"},
6202         {2,     "REMOVED (object was removed)"},
6203         {3,     "MODIFIED (object was modified)"},
6204         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6205         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6206         {6,     "ADDED_STREAM (a stream was added)"},
6207         {7,     "REMOVED_STREAM (a stream was removed)"},
6208         {8,     "MODIFIED_STREAM (a stream was modified)"},
6209         {0, NULL}
6210 };
6211
6212 static const value_string watch_tree_vals[] = {
6213         {0,     "Current directory only"},
6214         {1,     "Subdirectories also"},
6215         {0, NULL}
6216 };
6217
6218 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6219 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6220 #define NT_NOTIFY_STREAM_NAME   0x00000200
6221 #define NT_NOTIFY_SECURITY      0x00000100
6222 #define NT_NOTIFY_EA            0x00000080
6223 #define NT_NOTIFY_CREATION      0x00000040
6224 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6225 #define NT_NOTIFY_LAST_WRITE    0x00000010
6226 #define NT_NOTIFY_SIZE          0x00000008
6227 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6228 #define NT_NOTIFY_DIR_NAME      0x00000002
6229 #define NT_NOTIFY_FILE_NAME     0x00000001
6230 static const true_false_string tfs_nt_notify_stream_write = {
6231         "Notify on changes to STREAM WRITE",
6232         "Do NOT notify on changes to stream write",
6233 };
6234 static const true_false_string tfs_nt_notify_stream_size = {
6235         "Notify on changes to STREAM SIZE",
6236         "Do NOT notify on changes to stream size",
6237 };
6238 static const true_false_string tfs_nt_notify_stream_name = {
6239         "Notify on changes to STREAM NAME",
6240         "Do NOT notify on changes to stream name",
6241 };
6242 static const true_false_string tfs_nt_notify_security = {
6243         "Notify on changes to SECURITY",
6244         "Do NOT notify on changes to security",
6245 };
6246 static const true_false_string tfs_nt_notify_ea = {
6247         "Notify on changes to EA",
6248         "Do NOT notify on changes to EA",
6249 };
6250 static const true_false_string tfs_nt_notify_creation = {
6251         "Notify on changes to CREATION TIME",
6252         "Do NOT notify on changes to creation time",
6253 };
6254 static const true_false_string tfs_nt_notify_last_access = {
6255         "Notify on changes to LAST ACCESS TIME",
6256         "Do NOT notify on changes to last access time",
6257 };
6258 static const true_false_string tfs_nt_notify_last_write = {
6259         "Notify on changes to LAST WRITE TIME",
6260         "Do NOT notify on changes to last write time",
6261 };
6262 static const true_false_string tfs_nt_notify_size = {
6263         "Notify on changes to SIZE",
6264         "Do NOT notify on changes to size",
6265 };
6266 static const true_false_string tfs_nt_notify_attributes = {
6267         "Notify on changes to ATTRIBUTES",
6268         "Do NOT notify on changes to attributes",
6269 };
6270 static const true_false_string tfs_nt_notify_dir_name = {
6271         "Notify on changes to DIR NAME",
6272         "Do NOT notify on changes to dir name",
6273 };
6274 static const true_false_string tfs_nt_notify_file_name = {
6275         "Notify on changes to FILE NAME",
6276         "Do NOT notify on changes to file name",
6277 };
6278
6279 static const value_string create_disposition_vals[] = {
6280         {0,     "Supersede (supersede existing file (if it exists))"},
6281         {1,     "Open (if file exists open it, else fail)"},
6282         {2,     "Create (if file exists fail, else create it)"},
6283         {3,     "Open If (if file exists open it, else create it)"},
6284         {4,     "Overwrite (if file exists overwrite, else fail)"},
6285         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6286         {0, NULL}
6287 };
6288
6289 static const value_string impersonation_level_vals[] = {
6290         {0,     "Anonymous"},
6291         {1,     "Identification"},
6292         {2,     "Impersonation"},
6293         {3,     "Delegation"},
6294         {0, NULL}
6295 };
6296
6297 static const true_false_string tfs_nt_security_flags_context_tracking = {
6298         "Security tracking mode is DYNAMIC",
6299         "Security tracking mode is STATIC",
6300 };
6301
6302 static const true_false_string tfs_nt_security_flags_effective_only = {
6303         "ONLY ENABLED aspects of the client's security context are available",
6304         "ALL aspects of the client's security context are available",
6305 };
6306
6307 static const true_false_string tfs_nt_create_bits_oplock = {
6308         "Requesting OPLOCK",
6309         "Does NOT request oplock"
6310 };
6311
6312 static const true_false_string tfs_nt_create_bits_boplock = {
6313         "Requesting BATCH OPLOCK",
6314         "Does NOT request batch oplock"
6315 };
6316
6317 /*
6318  * XXX - must be a directory, and can be a file, or can be a directory,
6319  * and must be a file?
6320  */
6321 static const true_false_string tfs_nt_create_bits_dir = {
6322         "Target of open MUST be a DIRECTORY",
6323         "Target of open can be a file"
6324 };
6325
6326 static const true_false_string tfs_nt_access_mask_generic_read = {
6327         "GENERIC READ is set",
6328         "Generic read is NOT set"
6329 };
6330 static const true_false_string tfs_nt_access_mask_generic_write = {
6331         "GENERIC WRITE is set",
6332         "Generic write is NOT set"
6333 };
6334 static const true_false_string tfs_nt_access_mask_generic_execute = {
6335         "GENERIC EXECUTE is set",
6336         "Generic execute is NOT set"
6337 };
6338 static const true_false_string tfs_nt_access_mask_generic_all = {
6339         "GENERIC ALL is set",
6340         "Generic all is NOT set"
6341 };
6342 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6343         "MAXIMUM ALLOWED is set",
6344         "Maximum allowed is NOT set"
6345 };
6346 static const true_false_string tfs_nt_access_mask_system_security = {
6347         "SYSTEM SECURITY is set",
6348         "System security is NOT set"
6349 };
6350 static const true_false_string tfs_nt_access_mask_synchronize = {
6351         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6352         "Can NOT wait on handle to synchronize on completion of I/O"
6353 };
6354 static const true_false_string tfs_nt_access_mask_write_owner = {
6355         "Can WRITE OWNER (take ownership)",
6356         "Can NOT write owner (take ownership)"
6357 };
6358 static const true_false_string tfs_nt_access_mask_write_dac = {
6359         "OWNER may WRITE the DAC",
6360         "Owner may NOT write to the DAC"
6361 };
6362 static const true_false_string tfs_nt_access_mask_read_control = {
6363         "READ ACCESS to owner, group and ACL of the SID",
6364         "Read access is NOT granted to owner, group and ACL of the SID"
6365 };
6366 static const true_false_string tfs_nt_access_mask_delete = {
6367         "DELETE access",
6368         "NO delete access"
6369 };
6370 static const true_false_string tfs_nt_access_mask_write_attributes = {
6371         "WRITE ATTRIBUTES access",
6372         "NO write attributes access"
6373 };
6374 static const true_false_string tfs_nt_access_mask_read_attributes = {
6375         "READ ATTRIBUTES access",
6376         "NO read attributes access"
6377 };
6378 static const true_false_string tfs_nt_access_mask_delete_child = {
6379         "DELETE CHILD access",
6380         "NO delete child access"
6381 };
6382 static const true_false_string tfs_nt_access_mask_execute = {
6383         "EXECUTE access",
6384         "NO execute access"
6385 };
6386 static const true_false_string tfs_nt_access_mask_write_ea = {
6387         "WRITE EXTENDED ATTRIBUTES access",
6388         "NO write extended attributes access"
6389 };
6390 static const true_false_string tfs_nt_access_mask_read_ea = {
6391         "READ EXTENDED ATTRIBUTES access",
6392         "NO read extended attributes access"
6393 };
6394 static const true_false_string tfs_nt_access_mask_append = {
6395         "APPEND access",
6396         "NO append access"
6397 };
6398 static const true_false_string tfs_nt_access_mask_write = {
6399         "WRITE access",
6400         "NO write access"
6401 };
6402 static const true_false_string tfs_nt_access_mask_read = {
6403         "READ access",
6404         "NO read access"
6405 };
6406
6407 static const true_false_string tfs_nt_share_access_delete = {
6408         "Object can be shared for DELETE",
6409         "Object can NOT be shared for delete"
6410 };
6411 static const true_false_string tfs_nt_share_access_write = {
6412         "Object can be shared for WRITE",
6413         "Object can NOT be shared for write"
6414 };
6415 static const true_false_string tfs_nt_share_access_read = {
6416         "Object can be shared for READ",
6417         "Object can NOT be shared for delete"
6418 };
6419
6420 static const value_string oplock_level_vals[] = {
6421         {0,     "No oplock granted"},
6422         {1,     "Exclusive oplock granted"},
6423         {2,     "Batch oplock granted"},
6424         {3,     "Level II oplock granted"},
6425         {0, NULL}
6426 };
6427
6428 static const value_string device_type_vals[] = {
6429         {0x00000001,    "Beep"},
6430         {0x00000002,    "CDROM"},
6431         {0x00000003,    "CDROM Filesystem"},
6432         {0x00000004,    "Controller"},
6433         {0x00000005,    "Datalink"},
6434         {0x00000006,    "Dfs"},
6435         {0x00000007,    "Disk"},
6436         {0x00000008,    "Disk Filesystem"},
6437         {0x00000009,    "Filesystem"},
6438         {0x0000000a,    "Inport Port"},
6439         {0x0000000b,    "Keyboard"},
6440         {0x0000000c,    "Mailslot"},
6441         {0x0000000d,    "MIDI-In"},
6442         {0x0000000e,    "MIDI-Out"},
6443         {0x0000000f,    "Mouse"},
6444         {0x00000010,    "Multi UNC Provider"},
6445         {0x00000011,    "Named Pipe"},
6446         {0x00000012,    "Network"},
6447         {0x00000013,    "Network Browser"},
6448         {0x00000014,    "Network Filesystem"},
6449         {0x00000015,    "NULL"},
6450         {0x00000016,    "Parallel Port"},
6451         {0x00000017,    "Physical card"},
6452         {0x00000018,    "Printer"},
6453         {0x00000019,    "Scanner"},
6454         {0x0000001a,    "Serial Mouse port"},
6455         {0x0000001b,    "Serial port"},
6456         {0x0000001c,    "Screen"},
6457         {0x0000001d,    "Sound"},
6458         {0x0000001e,    "Streams"},
6459         {0x0000001f,    "Tape"},
6460         {0x00000020,    "Tape Filesystem"},
6461         {0x00000021,    "Transport"},
6462         {0x00000022,    "Unknown"},
6463         {0x00000023,    "Video"},
6464         {0x00000024,    "Virtual Disk"},
6465         {0x00000025,    "WAVE-In"},
6466         {0x00000026,    "WAVE-Out"},
6467         {0x00000027,    "8042 Port"},
6468         {0x00000028,    "Network Redirector"},
6469         {0x00000029,    "Battery"},
6470         {0x0000002a,    "Bus Extender"},
6471         {0x0000002b,    "Modem"},
6472         {0x0000002c,    "VDM"},
6473         {0,     NULL}
6474 };
6475
6476 static const value_string is_directory_vals[] = {
6477         {0,     "This is NOT a directory"},
6478         {1,     "This is a DIRECTORY"},
6479         {0, NULL}
6480 };
6481
6482 typedef struct _nt_trans_data {
6483         int subcmd;
6484         guint32 sd_len;
6485         guint32 ea_len;
6486 } nt_trans_data;
6487
6488
6489
6490 static int
6491 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6492 {
6493         guint8 mask;
6494         proto_item *item = NULL;
6495         proto_tree *tree = NULL;
6496
6497         mask = tvb_get_guint8(tvb, offset);
6498
6499         if(parent_tree){
6500                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6501                         "Security Flags: 0x%02x", mask);
6502                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6503         }
6504
6505         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6506                 tvb, offset, 1, mask);
6507         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6508                 tvb, offset, 1, mask);
6509
6510         offset += 1;
6511
6512         return offset;
6513 }
6514
6515 static int
6516 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6517 {
6518         guint32 mask;
6519         proto_item *item = NULL;
6520         proto_tree *tree = NULL;
6521
6522         mask = tvb_get_letohl(tvb, offset);
6523
6524         if(parent_tree){
6525                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6526                         "Share Access: 0x%08x", mask);
6527                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6528         }
6529
6530         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6531                 tvb, offset, 4, mask);
6532         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6533                 tvb, offset, 4, mask);
6534         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6535                 tvb, offset, 4, mask);
6536
6537         offset += 4;
6538
6539         return offset;
6540 }
6541
6542
6543 static int
6544 dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6545 {
6546         guint32 mask;
6547         proto_item *item = NULL;
6548         proto_tree *tree = NULL;
6549
6550         mask = tvb_get_letohl(tvb, offset);
6551
6552         if(parent_tree){
6553                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6554                         "Access Mask: 0x%08x", mask);
6555                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6556         }
6557
6558         /*
6559          * Some of these bits come from 
6560          *
6561          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6562          *
6563          * and others come from the section on ZwOpenFile in "Windows(R)
6564          * NT(R)/2000 Native API Reference".
6565          */
6566         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6567                 tvb, offset, 4, mask);
6568         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6569                 tvb, offset, 4, mask);
6570         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6571                 tvb, offset, 4, mask);
6572         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6573                 tvb, offset, 4, mask);
6574         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6575                 tvb, offset, 4, mask);
6576         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6577                 tvb, offset, 4, mask);
6578         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6579                 tvb, offset, 4, mask);
6580         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6581                 tvb, offset, 4, mask);
6582         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6583                 tvb, offset, 4, mask);
6584         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6585                 tvb, offset, 4, mask);
6586         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6587                 tvb, offset, 4, mask);
6588         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6589                 tvb, offset, 4, mask);
6590         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6591                 tvb, offset, 4, mask);
6592         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6593                 tvb, offset, 4, mask);
6594         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6595                 tvb, offset, 4, mask);
6596         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6597                 tvb, offset, 4, mask);
6598         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6599                 tvb, offset, 4, mask);
6600         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6601                 tvb, offset, 4, mask);
6602         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6603                 tvb, offset, 4, mask);
6604         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6605                 tvb, offset, 4, mask);
6606
6607         offset += 4;
6608
6609         return offset;
6610 }
6611
6612 static int
6613 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6614 {
6615         guint32 mask;
6616         proto_item *item = NULL;
6617         proto_tree *tree = NULL;
6618
6619         mask = tvb_get_letohl(tvb, offset);
6620
6621         if(parent_tree){
6622                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6623                         "Create Flags: 0x%08x", mask);
6624                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6625         }
6626
6627         /*
6628          * XXX - it's 0x00000016 in at least one capture, but
6629          * Network Monitor doesn't say what the 0x00000010 bit is.
6630          * Does the Win32 API documentation, or NT Native API book,
6631          * suggest anything?
6632          */
6633         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6634                 tvb, offset, 4, mask);
6635         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6636                 tvb, offset, 4, mask);
6637         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6638                 tvb, offset, 4, mask);
6639
6640         offset += 4;
6641
6642         return offset;
6643 }
6644
6645 /*
6646  * XXX - there are some more flags in the description of "ZwOpenFile()"
6647  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6648  * the wire as well?  (The spec at
6649  *
6650  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6651  *
6652  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6653  * via the SMB protocol.  The NT redirector should convert this option
6654  * to FILE_WRITE_THROUGH."
6655  *
6656  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6657  * values one would infer from their position in the list of flags for
6658  * "ZwOpenFile()".  Most of the others probably have those values
6659  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6660  * which might go over the wire (for the benefit of backup/restore software).
6661  */
6662 static const true_false_string tfs_nt_create_options_directory = {
6663         "File being created/opened must be a directory",
6664         "File being created/opened must not be a directory"
6665 };
6666 static const true_false_string tfs_nt_create_options_write_through = {
6667         "Writes should flush buffered data before completing",
6668         "Writes need not flush buffered data before completing"
6669 };
6670 static const true_false_string tfs_nt_create_options_sequential_only = {
6671         "The file will only be accessed sequentially",
6672         "The file might not only be accessed sequentially"
6673 };
6674 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6675         "All operations SYNCHRONOUS, waits subject to termination from alert",
6676         "Operations NOT necessarily synchronous"
6677 };
6678 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6679         "All operations SYNCHRONOUS, waits not subject to alert",
6680         "Operations NOT necessarily synchronous"
6681 };
6682 static const true_false_string tfs_nt_create_options_non_directory = {
6683         "File being created/opened must not be a directory",
6684         "File being created/opened must be a directory"
6685 };
6686 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6687         "The client does not understand extended attributes",
6688         "The client understands extended attributes"
6689 };
6690 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6691         "The client understands only 8.3 file names",
6692         "The client understands long file names"
6693 };
6694 static const true_false_string tfs_nt_create_options_random_access = {
6695         "The file will be accessed randomly",
6696         "The file will not be accessed randomly"
6697 };
6698 static const true_false_string tfs_nt_create_options_delete_on_close = {
6699         "The file should be deleted when it is closed",
6700         "The file should not be deleted when it is closed"
6701 };
6702
6703 static int
6704 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6705 {
6706         guint32 mask;
6707         proto_item *item = NULL;
6708         proto_tree *tree = NULL;
6709
6710         mask = tvb_get_letohl(tvb, offset);
6711
6712         if(parent_tree){
6713                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6714                         "Create Options: 0x%08x", mask);
6715                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6716         }
6717
6718         /*
6719          * From
6720          *
6721          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6722          */
6723         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6724                 tvb, offset, 4, mask);
6725         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6726                 tvb, offset, 4, mask);
6727         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6728                 tvb, offset, 4, mask);
6729         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6730                 tvb, offset, 4, mask);
6731         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6732                 tvb, offset, 4, mask);
6733         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6734                 tvb, offset, 4, mask);
6735         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6736                 tvb, offset, 4, mask);
6737         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6738                 tvb, offset, 4, mask);
6739         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6740                 tvb, offset, 4, mask);
6741         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6742                 tvb, offset, 4, mask);
6743
6744         offset += 4;
6745
6746         return offset;
6747 }
6748  
6749 static int
6750 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6751 {
6752         guint32 mask;
6753         proto_item *item = NULL;
6754         proto_tree *tree = NULL;
6755
6756         mask = tvb_get_letohl(tvb, offset);
6757
6758         if(parent_tree){
6759                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6760                         "Completion Filter: 0x%08x", mask);
6761                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6762         }
6763  
6764         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6765                 tvb, offset, 4, mask);
6766         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6767                 tvb, offset, 4, mask);
6768         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6769                 tvb, offset, 4, mask);
6770         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6771                 tvb, offset, 4, mask);
6772         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6773                 tvb, offset, 4, mask);
6774         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6775                 tvb, offset, 4, mask);
6776         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6777                 tvb, offset, 4, mask);
6778         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6779                 tvb, offset, 4, mask);
6780         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6781                 tvb, offset, 4, mask);
6782         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6783                 tvb, offset, 4, mask);
6784         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6785                 tvb, offset, 4, mask);
6786         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6787                 tvb, offset, 4, mask);
6788
6789         offset += 4;
6790         return offset;
6791 }
6792  
6793 static int
6794 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6795 {
6796         guint8 mask;
6797         proto_item *item = NULL;
6798         proto_tree *tree = NULL;
6799
6800         mask = tvb_get_guint8(tvb, offset);
6801
6802         if(parent_tree){
6803                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6804                         "Completion Filter: 0x%02x", mask);
6805                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6806         }
6807
6808         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6809                 tvb, offset, 1, mask);
6810
6811         offset += 1;
6812         return offset;
6813 }
6814
6815 /*
6816  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6817  * Native API Reference".
6818  */
6819 static const true_false_string tfs_nt_qsd_owner = {
6820         "Requesting OWNER security information",
6821         "NOT requesting owner security information",
6822 };
6823
6824 static const true_false_string tfs_nt_qsd_group = {
6825         "Requesting GROUP security information",
6826         "NOT requesting group security information",
6827 };
6828
6829 static const true_false_string tfs_nt_qsd_dacl = {
6830         "Requesting DACL security information",
6831         "NOT requesting DACL security information",
6832 };
6833
6834 static const true_false_string tfs_nt_qsd_sacl = {
6835         "Requesting SACL security information",
6836         "NOT requesting SACL security information",
6837 };
6838
6839 #define NT_QSD_OWNER    0x00000001
6840 #define NT_QSD_GROUP    0x00000002
6841 #define NT_QSD_DACL     0x00000004
6842 #define NT_QSD_SACL     0x00000008
6843
6844 static int
6845 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6846 {
6847         guint32 mask;
6848         proto_item *item = NULL;
6849         proto_tree *tree = NULL;
6850
6851         mask = tvb_get_letohl(tvb, offset);
6852
6853         if(parent_tree){
6854                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6855                         "Security Information: 0x%08x", mask);
6856                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6857         }
6858
6859         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6860                 tvb, offset, 4, mask);
6861         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6862                 tvb, offset, 4, mask);
6863         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6864                 tvb, offset, 4, mask);
6865         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6866                 tvb, offset, 4, mask);
6867
6868         offset += 4;
6869
6870         return offset;
6871 }
6872
6873 static void
6874 free_g_string(void *arg)
6875 {
6876         g_string_free(arg, TRUE);
6877 }
6878
6879 int
6880 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
6881 {
6882         proto_item *item = NULL;
6883         proto_tree *tree = NULL;
6884         int old_offset = offset, sa_offset = offset;
6885         guint rid;
6886         guint8 revision;
6887         guint8 num_auth;
6888         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6889         int i;
6890         GString *gstr;
6891
6892         if(parent_tree){
6893                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6894                                            "NT %s SID", name);
6895                 tree = proto_item_add_subtree(item, ett_smb_sid);
6896         }
6897
6898         /* revision of sid */
6899         revision = tvb_get_guint8(tvb, offset);
6900         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6901         offset += 1;
6902
6903         switch(revision){
6904         case 1:  
6905         case 2:  /* Not sure what the different revision numbers mean */
6906           /* number of authorities*/
6907           num_auth = tvb_get_guint8(tvb, offset);
6908           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6909           offset += 1;
6910
6911           /* XXX perhaps we should have these thing searchable?
6912              a new FT_xxx thingie? SMB is quite common!*/
6913           /* identifier authorities */
6914
6915           for(i=0;i<6;i++){
6916             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
6917
6918             offset++;
6919           }
6920
6921           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
6922
6923           sa_offset = offset;
6924
6925           gstr = g_string_new("");
6926           
6927           CLEANUP_PUSH(free_g_string, gstr);
6928
6929           /* sub authorities, leave RID to last */
6930           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
6931             /*
6932              * XXX should not be letohl but native byteorder according to
6933              * Samba header files.
6934              *
6935              * However, considering that there were never any NT ports
6936              * to big-endian platforms (PowerPC and MIPS ran little-endian,
6937              * and IA-64 runs little-endian, as does x86-64), we can (?)
6938              * assume that non le byte encodings will be "uncommon"?
6939              */
6940              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
6941                   tvb_get_letohl(tvb, offset));
6942              offset+=4;
6943           }
6944
6945           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
6946
6947           if (num_auth > 4) {
6948             rid = tvb_get_letohl(tvb, offset);
6949             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
6950             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
6951             offset+=4;
6952           }
6953           else {
6954             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
6955           }
6956
6957           CLEANUP_CALL_AND_POP;
6958
6959         }
6960
6961         proto_item_set_len(item, offset-old_offset);
6962         return offset;
6963 }
6964
6965
6966 static const value_string ace_type_vals[] = {
6967   { 0, "Access Allowed"},
6968   { 1, "Access Denied"},
6969   { 2, "System Audit"},
6970   { 3, "System Alarm"},
6971   { 0, NULL}
6972 };
6973 static const true_false_string tfs_ace_flags_object_inherit = {
6974   "Subordinate files will inherit this ACE",
6975   "Subordinate files will not inherit this ACE"
6976 };
6977 static const true_false_string tfs_ace_flags_container_inherit = {
6978   "Subordinate containers will inherit this ACE",
6979   "Subordinate containers will not inherit this ACE"
6980 };
6981 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
6982   "Subordinate object will not propagate the inherited ACE further",
6983   "Subordinate object will propagate the inherited ACE further"
6984 };
6985 static const true_false_string tfs_ace_flags_inherit_only = {
6986   "This ACE does not apply to the current object",
6987   "This ACE applies to the current object"
6988 };
6989 static const true_false_string tfs_ace_flags_inherited_ace = {
6990   "This ACE was inherited from its parent object",
6991   "This ACE was not inherited from its parent object"
6992 };
6993 static const true_false_string tfs_ace_flags_successful_access = {
6994   "Successful accesses will be audited",
6995   "Successful accesses will not be audited"
6996 };
6997 static const true_false_string tfs_ace_flags_failed_access = {
6998   "Failed accesses will be audited",
6999   "Failed accesses will not be audited"
7000 };
7001
7002 #define APPEND_ACE_TEXT(flag, item, string) \
7003         if(flag){                                                       \
7004                 if(item)                                                \
7005                         proto_item_append_text(item, string, sep);      \
7006                 sep = ", ";                                             \
7007         }
7008
7009 static int
7010 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7011 {
7012         proto_item *item = NULL;
7013         proto_tree *tree = NULL;
7014         guint8 mask;
7015         char *sep = " ";
7016
7017         mask = tvb_get_guint8(tvb, offset);
7018         if(parent_tree){
7019                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7020                                            "NT ACE Flags: 0x%02x", mask);
7021                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7022         }
7023
7024         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7025                        tvb, offset, 1, mask);
7026         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7027
7028         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7029                        tvb, offset, 1, mask);
7030         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7031
7032         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7033                        tvb, offset, 1, mask);
7034         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7035
7036         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7037                        tvb, offset, 1, mask);
7038         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7039
7040         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7041                        tvb, offset, 1, mask);
7042         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7043
7044         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7045                        tvb, offset, 1, mask);
7046         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7047
7048         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7049                        tvb, offset, 1, mask);
7050         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7051
7052
7053         offset += 1;
7054         return offset;
7055 }
7056
7057 static int
7058 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7059 {
7060         proto_item *item = NULL;
7061         proto_tree *tree = NULL;
7062         int old_offset = offset;
7063         guint16 size;
7064         
7065         if(parent_tree){
7066                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7067                                            "NT ACE: ");
7068                 tree = proto_item_add_subtree(item, ett_smb_ace);
7069         }
7070
7071         /* type */
7072         if(item){
7073           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
7074         }
7075         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
7076         offset += 1;
7077
7078         /* flags */
7079         offset = dissect_nt_v2_ace_flags(tvb, offset, tree);
7080
7081         /* size */
7082         size = tvb_get_letohs(tvb, offset);
7083         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7084         offset += 2;
7085
7086         /* access mask */
7087         offset = dissect_nt_access_mask(tvb, tree, offset);
7088
7089         /* SID */
7090         offset = dissect_nt_sid(tvb, offset, tree, "ACE");
7091
7092         proto_item_set_len(item, offset-old_offset);
7093
7094         /* Sometimes there is some spare space at the end of the ACE so use
7095            the size field to work out where the end is. */
7096
7097         return old_offset + size;
7098 }
7099
7100 static int
7101 dissect_nt_acl(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
7102 {
7103         proto_item *item = NULL;
7104         proto_tree *tree = NULL;
7105         int old_offset = offset;
7106         guint16 revision;
7107         guint32 num_aces;
7108
7109         if(parent_tree){
7110                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7111                                            "NT %s ACL", name);
7112                 tree = proto_item_add_subtree(item, ett_smb_acl);
7113         }
7114
7115         /* revision */
7116         revision = tvb_get_letohs(tvb, offset);
7117         proto_tree_add_uint(tree, hf_smb_acl_revision,
7118                 tvb, offset, 2, revision);
7119         offset += 2;
7120
7121         switch(revision){
7122         case 2:  /* only version we will ever see of this structure?*/
7123         case 3:
7124           /* size */
7125           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7126           offset += 2;
7127
7128           /* number of ace structures */
7129           num_aces = tvb_get_letohl(tvb, offset);
7130           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7131                               tvb, offset, 4, num_aces);
7132           offset += 4;
7133
7134           while(num_aces--){
7135             offset=dissect_nt_v2_ace(tvb, offset, tree);
7136           }
7137         }
7138
7139         proto_item_set_len(item, offset-old_offset);
7140         return offset;
7141 }
7142
7143 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7144   "OWNER is DEFAULTED",
7145   "Owner is NOT defaulted"
7146 };
7147 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7148   "GROUP is DEFAULTED",
7149   "Group is NOT defaulted"
7150 };
7151 static const true_false_string tfs_sec_desc_type_dacl_present = {
7152   "DACL is PRESENT",
7153   "DACL is NOT present"
7154 };
7155 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7156   "DACL is DEFAULTED",
7157   "DACL is NOT defaulted"
7158 };
7159 static const true_false_string tfs_sec_desc_type_sacl_present = {
7160   "SACL is PRESENT",
7161   "SACL is NOT present"
7162 };
7163 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7164   "SACL is DEFAULTED",
7165   "SACL is NOT defaulted"
7166 };
7167 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7168   "DACL has AUTO INHERIT REQUIRED",
7169   "DACL does NOT require auto inherit"
7170 };
7171 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7172   "SACL has AUTO INHERIT REQUIRED",
7173   "SACL does NOT require auto inherit"
7174 };
7175 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7176   "DACL is AUTO INHERITED",
7177   "DACL is NOT auto inherited"
7178 };
7179 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7180   "SACL is AUTO INHERITED",
7181   "SACL is NOT auto inherited"
7182 };
7183 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7184   "The DACL is PROTECTED",
7185   "The DACL is NOT protected"
7186 };
7187 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7188   "The SACL is PROTECTED",
7189   "The SACL is NOT protected"
7190 };
7191 static const true_false_string tfs_sec_desc_type_self_relative = {
7192   "This SecDesc is SELF RELATIVE",
7193   "This SecDesc is NOT self relative"
7194 };
7195
7196
7197 static int
7198 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7199 {
7200         proto_item *item = NULL;
7201         proto_tree *tree = NULL;
7202         guint16 mask;
7203
7204         mask = tvb_get_letohs(tvb, offset);
7205         if(parent_tree){
7206                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7207                                            "Type: 0x%04x", mask);
7208                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7209         }
7210
7211         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7212                                tvb, offset, 2, mask);
7213         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7214                                tvb, offset, 2, mask);
7215         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7216                                tvb, offset, 2, mask);
7217         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7218                                tvb, offset, 2, mask);
7219         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7220                                tvb, offset, 2, mask);
7221         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7222                                tvb, offset, 2, mask);
7223         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7224                                tvb, offset, 2, mask);
7225         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7226                                tvb, offset, 2, mask);
7227         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7228                                tvb, offset, 2, mask);
7229         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7230                                tvb, offset, 2, mask);
7231         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7232                                tvb, offset, 2, mask);
7233         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7234                                tvb, offset, 2, mask);
7235         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7236                                tvb, offset, 2, mask);
7237
7238
7239         offset += 2;
7240         return offset;
7241 }
7242
7243 int
7244 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, int len)
7245 {
7246         proto_item *item = NULL;
7247         proto_tree *tree = NULL;
7248         guint16 revision;
7249         int old_offset = offset;
7250         guint32 owner_sid_offset;
7251         guint32 group_sid_offset;
7252         guint32 sacl_offset;
7253         guint32 dacl_offset;
7254
7255         if(parent_tree){
7256                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7257                                            "NT Security Descriptor");
7258                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7259         }
7260
7261         /* revision */
7262         revision = tvb_get_letohs(tvb, offset);
7263         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7264                 tvb, offset, 2, revision);
7265         offset += 2;
7266
7267         switch(revision){
7268         case 1:  /* only version we will ever see of this structure?*/
7269           /* type */
7270           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7271
7272           /* offset to owner sid */
7273           owner_sid_offset = tvb_get_letohl(tvb, offset);
7274           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
7275           offset += 4;
7276
7277           /* offset to group sid */
7278           group_sid_offset = tvb_get_letohl(tvb, offset);
7279           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
7280           offset += 4;
7281
7282           /* offset to sacl */
7283           sacl_offset = tvb_get_letohl(tvb, offset);
7284           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
7285           offset += 4;
7286
7287           /* offset to dacl */
7288           dacl_offset = tvb_get_letohl(tvb, offset);
7289           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
7290           offset += 4;
7291
7292           /*owner SID*/
7293           if(owner_sid_offset){
7294             if (len == -1)
7295               offset = dissect_nt_sid(tvb, offset, tree, "Owner");
7296             else
7297               dissect_nt_sid(tvb, old_offset+owner_sid_offset, tree, "Owner");
7298           }
7299
7300           /*group SID*/
7301           if(group_sid_offset){
7302             dissect_nt_sid(tvb, old_offset+group_sid_offset, tree, "Group");
7303           }
7304
7305           /* sacl */
7306           if(sacl_offset){
7307             dissect_nt_acl(tvb, old_offset+sacl_offset, tree, "System (SACL)");
7308           }
7309
7310           /* dacl */
7311           if(dacl_offset){
7312             dissect_nt_acl(tvb, old_offset+dacl_offset, tree, "User (DACL)");
7313           }
7314
7315         }
7316
7317         return offset+len;
7318 }
7319
7320 static int
7321 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7322 {
7323         int old_offset, old_sid_offset;
7324         guint32 qsize;
7325
7326         do {
7327                 old_offset=offset;
7328
7329                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7330                 qsize=tvb_get_letohl(tvb, offset);
7331                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7332                 COUNT_BYTES_TRANS_SUBR(4);
7333
7334                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7335                 /* length of SID */
7336                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7337                 COUNT_BYTES_TRANS_SUBR(4);
7338
7339                 /* 16 unknown bytes */
7340                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7341                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7342                             offset, 8, TRUE);
7343                 COUNT_BYTES_TRANS_SUBR(8);
7344
7345                 /* number of bytes for used quota */
7346                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7347                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7348                 COUNT_BYTES_TRANS_SUBR(8);
7349
7350                 /* number of bytes for quota warning */
7351                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7352                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7353                 COUNT_BYTES_TRANS_SUBR(8);
7354
7355                 /* number of bytes for quota limit */
7356                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7357                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7358                 COUNT_BYTES_TRANS_SUBR(8);
7359
7360                 /* SID of the user */
7361                 old_sid_offset=offset;
7362                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7363                 *bcp -= (offset-old_sid_offset);
7364
7365                 if(qsize){
7366                         offset = old_offset+qsize;
7367                 }
7368         }while(qsize);
7369
7370
7371         return offset;
7372 }
7373
7374
7375 static int
7376 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7377 {
7378         proto_item *item = NULL;
7379         proto_tree *tree = NULL;
7380         smb_info_t *si;
7381         int old_offset = offset;
7382         guint16 bcp=bc; /* XXX fixme */
7383
7384         si = (smb_info_t *)pinfo->private_data;
7385
7386         if(parent_tree){
7387                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7388                                 "%s Data",
7389                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7390                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7391         }
7392
7393         switch(ntd->subcmd){
7394         case NT_TRANS_CREATE:
7395                 /* security descriptor */
7396                 if(ntd->sd_len){
7397                         offset = dissect_nt_sec_desc(tvb, offset, tree, ntd->sd_len);
7398                 }
7399
7400                 /* extended attributes */
7401                 if(ntd->ea_len){
7402                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7403                         offset += ntd->ea_len;
7404                 }
7405
7406                 break;
7407         case NT_TRANS_IOCTL:
7408                 /* ioctl data */
7409                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7410                 offset += bc;
7411
7412                 break;
7413         case NT_TRANS_SSD:
7414                 offset = dissect_nt_sec_desc(tvb, offset, tree, bc);
7415                 break;
7416         case NT_TRANS_NOTIFY:
7417                 break;
7418         case NT_TRANS_RENAME:
7419                 /* XXX not documented */
7420                 break;
7421         case NT_TRANS_QSD:
7422                 break;
7423         case NT_TRANS_GET_USER_QUOTA:
7424                 /* unknown 4 bytes */
7425                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7426                             offset, 4, TRUE);
7427                 offset += 4;
7428
7429                 /* length of SID */
7430                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7431                 offset +=4;
7432
7433                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7434                 break;
7435         case NT_TRANS_SET_USER_QUOTA:
7436                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7437                 break;
7438         }
7439
7440         /* ooops there were data we didnt know how to process */
7441         if((offset-old_offset) < bc){
7442                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7443                     bc - (offset-old_offset), TRUE);
7444                 offset += bc - (offset-old_offset);
7445         }
7446
7447         return offset;
7448 }
7449
7450 static int
7451 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)
7452 {
7453         proto_item *item = NULL;
7454         proto_tree *tree = NULL;
7455         smb_info_t *si;
7456         guint32 fn_len;
7457         const char *fn;
7458
7459         si = (smb_info_t *)pinfo->private_data;
7460
7461         if(parent_tree){
7462                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7463                                 "%s Parameters",
7464                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7465                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7466         }
7467
7468         switch(ntd->subcmd){
7469         case NT_TRANS_CREATE:
7470                 /* Create flags */
7471                 offset = dissect_nt_create_bits(tvb, tree, offset);
7472                 bc -= 4;
7473
7474                 /* root directory fid */
7475                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7476                 COUNT_BYTES(4);
7477
7478                 /* nt access mask */
7479                 offset = dissect_nt_access_mask(tvb, tree, offset);
7480                 bc -= 4;
7481         
7482                 /* allocation size */
7483                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7484                 COUNT_BYTES(8);
7485         
7486                 /* Extended File Attributes */
7487                 offset = dissect_file_ext_attr(tvb, tree, offset);
7488                 bc -= 4;
7489
7490                 /* share access */
7491                 offset = dissect_nt_share_access(tvb, tree, offset);
7492                 bc -= 4;
7493         
7494                 /* create disposition */
7495                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7496                 COUNT_BYTES(4);
7497
7498                 /* create options */
7499                 offset = dissect_nt_create_options(tvb, tree, offset);
7500                 bc -= 4;
7501
7502                 /* sd length */
7503                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7504                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7505                 COUNT_BYTES(4);
7506
7507                 /* ea length */
7508                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7509                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7510                 COUNT_BYTES(4);
7511
7512                 /* file name len */
7513                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7514                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7515                 COUNT_BYTES(4);
7516
7517                 /* impersonation level */
7518                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7519                 COUNT_BYTES(4);
7520         
7521                 /* security flags */
7522                 offset = dissect_nt_security_flags(tvb, tree, offset);
7523                 bc -= 1;
7524
7525                 /* file name */
7526                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7527                 if (fn != NULL) {
7528                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7529                                 fn);
7530                         COUNT_BYTES(fn_len);
7531                 }
7532
7533                 break;
7534         case NT_TRANS_IOCTL:
7535                 break;
7536         case NT_TRANS_SSD: {
7537                 guint16 fid;
7538
7539                 /* fid */
7540                 fid = tvb_get_letohs(tvb, offset);
7541                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7542                 offset += 2;
7543
7544                 /* 2 reserved bytes */
7545                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7546                 offset += 2;
7547
7548                 /* security information */
7549                 offset = dissect_security_information_mask(tvb, tree, offset);
7550                 break;
7551         }
7552         case NT_TRANS_NOTIFY:
7553                 break;
7554         case NT_TRANS_RENAME:
7555                 /* XXX not documented */
7556                 break;
7557         case NT_TRANS_QSD: {
7558                 guint16 fid;
7559
7560                 /* fid */
7561                 fid = tvb_get_letohs(tvb, offset);
7562                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7563                 offset += 2;
7564
7565                 /* 2 reserved bytes */
7566                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7567                 offset += 2;
7568
7569                 /* security information */
7570                 offset = dissect_security_information_mask(tvb, tree, offset);
7571                 break;
7572         }
7573         case NT_TRANS_GET_USER_QUOTA:
7574                 /* not decoded yet */
7575                 break;
7576         case NT_TRANS_SET_USER_QUOTA:
7577                 /* not decoded yet */
7578                 break;
7579         }
7580
7581         return offset;
7582 }
7583
7584 static int
7585 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7586 {
7587         proto_item *item = NULL;
7588         proto_tree *tree = NULL;
7589         smb_info_t *si;
7590         int old_offset = offset;
7591
7592         si = (smb_info_t *)pinfo->private_data;
7593
7594         if(parent_tree){
7595                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7596                                 "%s Setup",
7597                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7598                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7599         }
7600  
7601         switch(ntd->subcmd){
7602         case NT_TRANS_CREATE:
7603                 break;
7604         case NT_TRANS_IOCTL: {
7605                 guint16 fid;
7606
7607                 /* function code */
7608                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7609                 offset += 4;
7610
7611                 /* fid */
7612                 fid = tvb_get_letohs(tvb, offset);
7613                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7614                 offset += 2;
7615
7616                 /* isfsctl */
7617                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7618                 offset += 1;
7619
7620                 /* isflags */
7621                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
7622
7623                 break;
7624         }
7625         case NT_TRANS_SSD:
7626                 break;
7627         case NT_TRANS_NOTIFY: {
7628                 guint16 fid;
7629
7630                 /* completion filter */
7631                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
7632
7633                 /* fid */
7634                 fid = tvb_get_letohs(tvb, offset);
7635                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7636                 offset += 2;
7637
7638                 /* watch tree */
7639                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7640                 offset += 1;
7641
7642                 /* reserved byte */
7643                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7644                 offset += 1;
7645
7646                 break;
7647         }
7648         case NT_TRANS_RENAME:
7649                 /* XXX not documented */
7650                 break;
7651         case NT_TRANS_QSD:
7652                 break;
7653         case NT_TRANS_GET_USER_QUOTA:
7654                 /* not decoded yet */
7655                 break;
7656         case NT_TRANS_SET_USER_QUOTA:
7657                 /* not decoded yet */
7658                 break;
7659         }
7660  
7661         return old_offset+len;
7662 }
7663
7664
7665 static int
7666 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
7667 {
7668         guint8 wc, sc;
7669         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7670         smb_info_t *si;
7671         smb_saved_info_t *sip;
7672         int subcmd;
7673         nt_trans_data ntd;
7674         guint16 bc;
7675         int padcnt;
7676         smb_nt_transact_info_t *nti;
7677
7678         si = (smb_info_t *)pinfo->private_data;
7679         sip = si->sip;
7680
7681         WORD_COUNT;
7682
7683         if(wc>=19){
7684                 /* primary request */
7685                 /* max setup count */
7686                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7687                 offset += 1;
7688
7689                 /* 2 reserved bytes */
7690                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7691                 offset += 2;
7692         } else {
7693                 /* secondary request */
7694                 /* 3 reserved bytes */
7695                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7696                 offset += 3;
7697         }
7698
7699
7700         /* total param count */
7701         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7702         offset += 4;
7703         
7704         /* total data count */
7705         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7706         offset += 4;
7707
7708         if(wc>=19){
7709                 /* primary request */
7710                 /* max param count */
7711                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7712                 offset += 4;
7713
7714                 /* max data count */
7715                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7716                 offset += 4;
7717         }
7718
7719         /* param count */
7720         pc = tvb_get_letohl(tvb, offset);
7721         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7722         offset += 4;
7723         
7724         /* param offset */
7725         po = tvb_get_letohl(tvb, offset);
7726         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7727         offset += 4;
7728
7729         /* param displacement */
7730         if(wc>=19){
7731                 /* primary request*/
7732                 pd = 0;
7733         } else {
7734                 /* secondary request */
7735                 pd = tvb_get_letohl(tvb, offset);
7736                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7737                 offset += 4;
7738         }
7739
7740         /* data count */
7741         dc = tvb_get_letohl(tvb, offset);
7742         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7743         offset += 4;
7744
7745         /* data offset */
7746         od = tvb_get_letohl(tvb, offset);
7747         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7748         offset += 4;
7749
7750         /* data displacement */
7751         if(wc>=19){
7752                 /* primary request */
7753                 dd = 0;
7754         } else {
7755                 /* secondary request */
7756                 dd = tvb_get_letohl(tvb, offset);
7757                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7758                 offset += 4;
7759         }
7760
7761         /* setup count */
7762         if(wc>=19){
7763                 /* primary request */
7764                 sc = tvb_get_guint8(tvb, offset);
7765                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7766                 offset += 1;
7767         } else {
7768                 /* secondary request */
7769                 sc = 0;
7770         }
7771
7772         /* function */
7773         if(wc>=19){
7774                 /* primary request */
7775                 subcmd = tvb_get_letohs(tvb, offset);
7776                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7777                 if(check_col(pinfo->cinfo, COL_INFO)){
7778                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7779                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7780                 }
7781                 ntd.subcmd = subcmd;
7782                 if (!si->unidir) {
7783                         if(!pinfo->fd->flags.visited){
7784                                 /* 
7785                                  * Allocate a new smb_nt_transact_info_t
7786                                  * structure.
7787                                  */
7788                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7789                                 nti->subcmd = subcmd;
7790                                 sip->extra_info = nti;
7791                         }
7792                 }
7793         } else {
7794                 /* secondary request */
7795                 if(check_col(pinfo->cinfo, COL_INFO)){
7796                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7797                 }
7798         }
7799         offset += 2;
7800
7801         /* this is a padding byte */
7802         if(offset%1){
7803                 /* pad byte */
7804                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7805                 offset += 1;
7806         }
7807
7808         /* if there were any setup bytes, decode them */
7809         if(sc){
7810                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7811                 offset += sc*2;
7812         }
7813
7814         BYTE_COUNT;
7815         
7816         /* parameters */
7817         if(po>(guint32)offset){
7818                 /* We have some initial padding bytes.
7819                 */
7820                 padcnt = po-offset;
7821                 if (padcnt > bc)
7822                         padcnt = bc;
7823                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7824                 COUNT_BYTES(padcnt);
7825         }
7826         if(pc){
7827                 CHECK_BYTE_COUNT(pc);
7828                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7829                 COUNT_BYTES(pc);
7830         }
7831
7832         /* data */
7833         if(od>(guint32)offset){
7834                 /* We have some initial padding bytes.
7835                 */
7836                 padcnt = od-offset;
7837                 if (padcnt > bc)
7838                         padcnt = bc;
7839                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7840                 COUNT_BYTES(padcnt);
7841         }
7842         if(dc){
7843                 CHECK_BYTE_COUNT(dc);
7844                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7845                 COUNT_BYTES(dc);
7846         }
7847
7848         END_OF_SMB
7849
7850         return offset;
7851 }
7852
7853
7854
7855 static int
7856 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7857 {
7858         proto_item *item = NULL;
7859         proto_tree *tree = NULL;
7860         smb_info_t *si;
7861         smb_nt_transact_info_t *nti;
7862         guint16 bcp;
7863
7864         si = (smb_info_t *)pinfo->private_data;
7865         if (si->sip != NULL)
7866                 nti = si->sip->extra_info;
7867         else
7868                 nti = NULL;
7869
7870         if(parent_tree){
7871                 if(nti != NULL){
7872                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7873                                 "%s Data",
7874                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7875                 } else {
7876                         /*
7877                          * We never saw the request to which this is a
7878                          * response.
7879                          */
7880                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7881                                 "Unknown NT Transaction Data (matching request not seen)");
7882                 }
7883                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7884         }
7885
7886         if (nti == NULL) {
7887                 offset += len;
7888                 return offset;
7889         }
7890         switch(nti->subcmd){
7891         case NT_TRANS_CREATE:
7892                 break;
7893         case NT_TRANS_IOCTL:
7894                 /* ioctl data */
7895                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7896                 offset += len;
7897
7898                 break;
7899         case NT_TRANS_SSD:
7900                 break;
7901         case NT_TRANS_NOTIFY:
7902                 break;
7903         case NT_TRANS_RENAME:
7904                 /* XXX not documented */
7905                 break;
7906         case NT_TRANS_QSD:
7907                 /*
7908                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7909                  * which may be documented in the Win32 documentation
7910                  * somewhere.
7911                  */
7912                 offset = dissect_nt_sec_desc(tvb, offset, tree, len);
7913                 break;
7914         case NT_TRANS_GET_USER_QUOTA:
7915                 bcp=len;
7916                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7917                 break;
7918         case NT_TRANS_SET_USER_QUOTA:
7919                 /* not decoded yet */
7920                 break;
7921         }
7922
7923         return offset;
7924 }
7925  
7926 static int
7927 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)
7928 {
7929         proto_item *item = NULL;
7930         proto_tree *tree = NULL;
7931         guint32 fn_len;
7932         const char *fn;
7933         smb_info_t *si;
7934         smb_nt_transact_info_t *nti;
7935         guint16 fid;
7936         int old_offset;
7937         guint32 neo;
7938         int padcnt;
7939
7940         si = (smb_info_t *)pinfo->private_data;
7941         if (si->sip != NULL)
7942                 nti = si->sip->extra_info;
7943         else
7944                 nti = NULL;
7945
7946         if(parent_tree){
7947                 if(nti != NULL){
7948                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7949                                 "%s Parameters",
7950                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7951                 } else {
7952                         /*
7953                          * We never saw the request to which this is a
7954                          * response.
7955                          */
7956                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7957                                 "Unknown NT Transaction Parameters (matching request not seen)");
7958                 }
7959                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7960         }
7961
7962         if (nti == NULL) {
7963                 offset += len;
7964                 return offset;
7965         }
7966         switch(nti->subcmd){
7967         case NT_TRANS_CREATE:
7968                 /* oplock level */
7969                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7970                 offset += 1;
7971
7972                 /* reserved byte */
7973                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7974                 offset += 1;
7975                 
7976                 /* fid */
7977                 fid = tvb_get_letohs(tvb, offset);
7978                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7979                 offset += 2;
7980
7981                 /* create action */
7982                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7983                 offset += 4;
7984
7985                 /* ea error offset */
7986                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7987                 offset += 4;
7988
7989                 /* create time */
7990                 offset = dissect_smb_64bit_time(tvb, tree, offset,
7991                         hf_smb_create_time);
7992         
7993                 /* access time */
7994                 offset = dissect_smb_64bit_time(tvb, tree, offset,
7995                         hf_smb_access_time);
7996         
7997                 /* last write time */
7998                 offset = dissect_smb_64bit_time(tvb, tree, offset,
7999                         hf_smb_last_write_time);
8000         
8001                 /* last change time */
8002                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8003                         hf_smb_change_time);
8004         
8005                 /* Extended File Attributes */
8006                 offset = dissect_file_ext_attr(tvb, tree, offset);
8007
8008                 /* allocation size */
8009                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8010                 offset += 8;
8011
8012                 /* end of file */
8013                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8014                 offset += 8;
8015
8016                 /* File Type */
8017                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8018                 offset += 2;
8019
8020                 /* device state */
8021                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8022
8023                 /* is directory */
8024                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8025                 offset += 1;
8026                 break;
8027         case NT_TRANS_IOCTL:
8028                 break;
8029         case NT_TRANS_SSD:
8030                 break;
8031         case NT_TRANS_NOTIFY:
8032                 while(len){
8033                         old_offset = offset;
8034
8035                         /* next entry offset */
8036                         neo = tvb_get_letohl(tvb, offset);
8037                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8038                         COUNT_BYTES(4);
8039                         len -= 4;
8040                         /* broken implementations */
8041                         if(len<0)break;
8042         
8043                         /* action */
8044                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8045                         COUNT_BYTES(4);
8046                         len -= 4;
8047                         /* broken implementations */
8048                         if(len<0)break;
8049
8050                         /* file name len */
8051                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8052                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8053                         COUNT_BYTES(4);
8054                         len -= 4;
8055                         /* broken implementations */
8056                         if(len<0)break;
8057
8058                         /* file name */
8059                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
8060                         if (fn == NULL)
8061                                 break;
8062                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8063                                 fn);
8064                         COUNT_BYTES(fn_len);
8065                         len -= fn_len;
8066                         /* broken implementations */
8067                         if(len<0)break;
8068
8069                         if (neo == 0)
8070                                 break;  /* no more structures */
8071
8072                         /* skip to next structure */
8073                         padcnt = (old_offset + neo) - offset;
8074                         if (padcnt < 0) {
8075                                 /*
8076                                  * XXX - this is bogus; flag it?
8077                                  */
8078                                 padcnt = 0;
8079                         }
8080                         if (padcnt != 0) {
8081                                 COUNT_BYTES(padcnt);
8082                                 len -= padcnt;
8083                                 /* broken implementations */
8084                                 if(len<0)break;
8085                         }
8086                 }
8087                 break;
8088         case NT_TRANS_RENAME:
8089                 /* XXX not documented */
8090                 break;
8091         case NT_TRANS_QSD:
8092                 /*
8093                  * This appears to be the size of the security
8094                  * descriptor; the calling sequence of
8095                  * "ZwQuerySecurityObject()" suggests that it would
8096                  * be.  The actual security descriptor wouldn't
8097                  * follow if the max data count in the request
8098                  * was smaller; this lets the client know how
8099                  * big a buffer it needs to provide.
8100                  */
8101                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8102                 offset += 4;
8103                 break;
8104         case NT_TRANS_GET_USER_QUOTA:
8105                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8106                         tvb_get_letohl(tvb, offset));
8107                 offset += 4;
8108                 break;
8109         case NT_TRANS_SET_USER_QUOTA:
8110                 /* not decoded yet */
8111                 break;
8112         }
8113
8114         return offset;
8115 }
8116  
8117 static int
8118 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8119 {
8120         proto_item *item = NULL;
8121         proto_tree *tree = NULL;
8122         smb_info_t *si;
8123         smb_nt_transact_info_t *nti;
8124
8125         si = (smb_info_t *)pinfo->private_data;
8126         if (si->sip != NULL)
8127                 nti = si->sip->extra_info;
8128         else
8129                 nti = NULL;
8130
8131         if(parent_tree){
8132                 if(nti != NULL){
8133                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8134                                 "%s Setup",
8135                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8136                 } else {
8137                         /*
8138                          * We never saw the request to which this is a
8139                          * response.
8140                          */
8141                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8142                                 "Unknown NT Transaction Setup (matching request not seen)");
8143                 }
8144                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8145         }
8146
8147         if (nti == NULL) {
8148                 offset += len;
8149                 return offset;
8150         }
8151         switch(nti->subcmd){
8152         case NT_TRANS_CREATE:
8153                 break;
8154         case NT_TRANS_IOCTL:
8155                 break;
8156         case NT_TRANS_SSD:
8157                 break;
8158         case NT_TRANS_NOTIFY:
8159                 break;
8160         case NT_TRANS_RENAME:
8161                 /* XXX not documented */
8162                 break;
8163         case NT_TRANS_QSD:
8164                 break;
8165         case NT_TRANS_GET_USER_QUOTA:
8166                 /* not decoded yet */
8167                 break;
8168         case NT_TRANS_SET_USER_QUOTA:
8169                 /* not decoded yet */
8170                 break;
8171         }
8172
8173         return offset;
8174 }
8175
8176 static int
8177 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8178 {
8179         guint8 wc, sc;
8180         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8181         guint32 td=0, tp=0;
8182         smb_info_t *si;
8183         smb_nt_transact_info_t *nti;
8184         static nt_trans_data ntd;
8185         guint16 bc;
8186         int padcnt;
8187         fragment_data *r_fd = NULL;
8188         tvbuff_t *pd_tvb=NULL;
8189         gboolean save_fragmented;
8190
8191         si = (smb_info_t *)pinfo->private_data;
8192         if (si->sip != NULL)
8193                 nti = si->sip->extra_info;
8194         else
8195                 nti = NULL;
8196
8197         /* primary request */
8198         if(nti != NULL){
8199                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8200                 if(check_col(pinfo->cinfo, COL_INFO)){
8201                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8202                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8203                 }
8204         } else {
8205                 proto_tree_add_text(tree, tvb, offset, 0,
8206                         "Function: <unknown function - could not find matching request>");
8207                 if(check_col(pinfo->cinfo, COL_INFO)){
8208                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8209                 }
8210         }
8211
8212         WORD_COUNT;
8213
8214         /* 3 reserved bytes */
8215         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8216         offset += 3;
8217
8218         /* total param count */
8219         tp = tvb_get_letohl(tvb, offset);
8220         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8221         offset += 4;
8222         
8223         /* total data count */
8224         td = tvb_get_letohl(tvb, offset);
8225         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8226         offset += 4;
8227
8228         /* param count */
8229         pc = tvb_get_letohl(tvb, offset);
8230         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8231         offset += 4;
8232         
8233         /* param offset */
8234         po = tvb_get_letohl(tvb, offset);
8235         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8236         offset += 4;
8237
8238         /* param displacement */
8239         pd = tvb_get_letohl(tvb, offset);
8240         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8241         offset += 4;
8242
8243         /* data count */
8244         dc = tvb_get_letohl(tvb, offset);
8245         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8246         offset += 4;
8247
8248         /* data offset */
8249         od = tvb_get_letohl(tvb, offset);
8250         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8251         offset += 4;
8252
8253         /* data displacement */
8254         dd = tvb_get_letohl(tvb, offset);
8255         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8256         offset += 4;
8257
8258         /* setup count */
8259         sc = tvb_get_guint8(tvb, offset);
8260         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8261         offset += 1;
8262
8263         /* setup data */        
8264         if(sc){
8265                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8266                 offset += sc*2;
8267         }
8268
8269         BYTE_COUNT;
8270
8271         /* reassembly of SMB NT Transaction data payload.
8272            In this section we do reassembly of both the data and parameters
8273            blocks of the SMB transaction command.
8274         */
8275         save_fragmented = pinfo->fragmented;
8276         /* do we need reassembly? */
8277         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8278                 /* oh yeah, either data or parameter section needs 
8279                    reassembly...
8280                 */
8281                 pinfo->fragmented = TRUE;
8282                 if(smb_trans_reassembly){
8283                         /* ...and we were told to do reassembly */
8284                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8285                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8286                                                              po, pc, pd, td+tp);
8287                                 
8288                         }
8289                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8290                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8291                                                              od, dc, dd+tp, td+tp);
8292                         }
8293                 }
8294         }
8295
8296         /* if we got a reassembled fd structure from the reassembly routine we
8297            must create pd_tvb from it 
8298         */
8299         if(r_fd){
8300                 proto_tree *tr;
8301                 proto_item *it;
8302                 fragment_data *fd;
8303                 
8304                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8305                                              r_fd->datalen);
8306                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8307                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
8308                 pinfo->fragmented = FALSE;
8309
8310                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
8311                 tr = proto_item_add_subtree(it, ett_smb_segments);
8312                 for(fd=r_fd->next;fd;fd=fd->next){
8313                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
8314                                             "Frame:%u Data:%u-%u",
8315                                             fd->frame, fd->offset,
8316                                             fd->offset+fd->len-1);
8317                 }
8318         }
8319
8320
8321         if(pd_tvb){
8322           /* we have reassembled data, grab param and data from there */
8323           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8324                                           &ntd, tvb_length(pd_tvb));
8325           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8326         } else {
8327           /* we do not have reassembled data, just use what we have in the 
8328              packet as well as we can */
8329           /* parameters */
8330           if(po>(guint32)offset){
8331             /* We have some initial padding bytes.
8332              */
8333             padcnt = po-offset;
8334             if (padcnt > bc)
8335               padcnt = bc;
8336             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8337             COUNT_BYTES(padcnt);
8338           }
8339           if(pc){
8340             CHECK_BYTE_COUNT(pc);
8341             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8342             COUNT_BYTES(pc);
8343           }
8344           
8345           /* data */
8346           if(od>(guint32)offset){
8347             /* We have some initial padding bytes.
8348              */
8349             padcnt = od-offset;
8350             if (padcnt > bc)
8351               padcnt = bc;
8352             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8353             COUNT_BYTES(padcnt);
8354           }
8355           if(dc){
8356             CHECK_BYTE_COUNT(dc);
8357             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8358             COUNT_BYTES(dc);
8359           }
8360         }
8361         pinfo->fragmented = save_fragmented;
8362
8363         END_OF_SMB
8364
8365         return offset;
8366 }
8367
8368 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8369    NT Transaction command  ends here
8370    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8371
8372 static const value_string print_mode_vals[] = {
8373         {0,     "Text Mode"},
8374         {1,     "Graphics Mode"},
8375         {0, NULL}
8376 };
8377  
8378 static int
8379 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8380 {
8381         int fn_len;
8382         const char *fn;
8383         guint8 wc;
8384         guint16 bc;
8385
8386         WORD_COUNT;
8387
8388         /* setup len */
8389         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8390         offset += 2;
8391
8392         /* print mode */
8393         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8394         offset += 2;
8395
8396         BYTE_COUNT;
8397
8398         /* buffer format */
8399         CHECK_BYTE_COUNT(1);
8400         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8401         COUNT_BYTES(1);
8402
8403         /* print identifier */
8404         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
8405         if (fn == NULL)
8406                 goto endofcommand;
8407         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8408                 fn);
8409         COUNT_BYTES(fn_len);
8410
8411         END_OF_SMB
8412
8413         return offset;
8414 }
8415
8416
8417 static int
8418 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8419 {
8420         int cnt;
8421         guint8 wc;
8422         guint16 bc, fid;
8423
8424         WORD_COUNT;
8425
8426         /* fid */
8427         fid = tvb_get_letohs(tvb, offset);
8428         add_fid(tvb, pinfo, tree, offset, 2, fid);
8429         offset += 2;
8430
8431         BYTE_COUNT;
8432
8433         /* buffer format */
8434         CHECK_BYTE_COUNT(1);
8435         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8436         COUNT_BYTES(1);
8437
8438         /* data len */
8439         CHECK_BYTE_COUNT(2);
8440         cnt = tvb_get_letohs(tvb, offset);
8441         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8442         COUNT_BYTES(2);
8443
8444         /* file data */
8445         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8446
8447         END_OF_SMB
8448
8449         return offset;
8450 }
8451
8452
8453 static const value_string print_status_vals[] = {
8454         {1,     "Held or Stopped"},
8455         {2,     "Printing"},
8456         {3,     "Awaiting print"},
8457         {4,     "In intercept"},
8458         {5,     "File had error"},
8459         {6,     "Printer error"},
8460         {0, NULL}
8461 };
8462  
8463 static int
8464 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8465 {
8466         guint8 wc;
8467         guint16 bc;
8468
8469         WORD_COUNT;
8470
8471         /* max count */
8472         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8473         offset += 2;
8474
8475         /* start index */
8476         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8477         offset += 2;
8478
8479         BYTE_COUNT;
8480
8481         END_OF_SMB
8482
8483         return offset;
8484 }
8485
8486 static int
8487 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8488     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8489 {
8490         proto_item *item = NULL;
8491         proto_tree *tree = NULL;
8492         int fn_len;
8493         const char *fn;
8494
8495         if(parent_tree){
8496                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8497                         "Queue entry");
8498                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8499         }
8500
8501         /* queued time */
8502         CHECK_BYTE_COUNT_SUBR(4);
8503         offset = dissect_smb_datetime(tvb, tree, offset,
8504                 hf_smb_print_queue_date,
8505                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8506         *bcp -= 4;
8507
8508         /* status */
8509         CHECK_BYTE_COUNT_SUBR(1);
8510         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8511         COUNT_BYTES_SUBR(1);
8512
8513         /* spool file number */
8514         CHECK_BYTE_COUNT_SUBR(2);
8515         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8516         COUNT_BYTES_SUBR(2);
8517
8518         /* spool file size */
8519         CHECK_BYTE_COUNT_SUBR(4);
8520         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8521         COUNT_BYTES_SUBR(4);
8522
8523         /* reserved byte */
8524         CHECK_BYTE_COUNT_SUBR(1);
8525         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8526         COUNT_BYTES_SUBR(1);
8527
8528         /* file name */
8529         fn_len = 16;
8530         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
8531         CHECK_STRING_SUBR(fn);
8532         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8533                 fn);
8534         COUNT_BYTES_SUBR(fn_len);
8535
8536         *trunc = FALSE;
8537         return offset;
8538 }
8539
8540 static int
8541 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8542 {
8543         guint16 cnt=0, len;
8544         guint8 wc;
8545         guint16 bc;
8546         gboolean trunc;
8547
8548         WORD_COUNT;
8549
8550         /* count */
8551         cnt = tvb_get_letohs(tvb, offset);
8552         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8553         offset += 2;
8554
8555         /* restart index */
8556         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8557         offset += 2;
8558
8559         BYTE_COUNT;
8560
8561         /* buffer format */
8562         CHECK_BYTE_COUNT(1);
8563         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8564         COUNT_BYTES(1);
8565
8566         /* data len */
8567         CHECK_BYTE_COUNT(2);
8568         len = tvb_get_letohs(tvb, offset);
8569         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8570         COUNT_BYTES(2);
8571
8572         /* queue elements */
8573         while(cnt--){
8574                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8575                     &bc, &trunc);
8576                 if (trunc)
8577                         goto endofcommand;
8578         }
8579
8580         END_OF_SMB
8581
8582         return offset;
8583 }
8584
8585
8586 static int
8587 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8588 {
8589         int name_len;
8590         guint16 bc;
8591         guint8 wc;
8592         guint16 message_len;
8593
8594         WORD_COUNT;
8595
8596         BYTE_COUNT;
8597
8598         /* buffer format */
8599         CHECK_BYTE_COUNT(1);
8600         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8601         COUNT_BYTES(1);
8602
8603         /* originator name */
8604         /* XXX - what if this runs past bc? */
8605         name_len = tvb_strsize(tvb, offset);
8606         CHECK_BYTE_COUNT(name_len);
8607         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8608             name_len, TRUE);
8609         COUNT_BYTES(name_len);
8610
8611         /* buffer format */
8612         CHECK_BYTE_COUNT(1);
8613         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8614         COUNT_BYTES(1);
8615
8616         /* destination name */
8617         /* XXX - what if this runs past bc? */
8618         name_len = tvb_strsize(tvb, offset);
8619         CHECK_BYTE_COUNT(name_len);
8620         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8621             name_len, TRUE);
8622         COUNT_BYTES(name_len);
8623
8624         /* buffer format */
8625         CHECK_BYTE_COUNT(1);
8626         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8627         COUNT_BYTES(1);
8628
8629         /* message len */
8630         CHECK_BYTE_COUNT(2);
8631         message_len = tvb_get_letohs(tvb, offset);
8632         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8633             message_len);
8634         COUNT_BYTES(2);
8635
8636         /* message */
8637         CHECK_BYTE_COUNT(message_len);
8638         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8639             TRUE);
8640         COUNT_BYTES(message_len);
8641
8642         END_OF_SMB
8643
8644         return offset;
8645 }
8646
8647 static int
8648 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8649 {
8650         int name_len;
8651         guint16 bc;
8652         guint8 wc;
8653
8654         WORD_COUNT;
8655
8656         BYTE_COUNT;
8657
8658         /* buffer format */
8659         CHECK_BYTE_COUNT(1);
8660         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8661         COUNT_BYTES(1);
8662
8663         /* originator name */
8664         /* XXX - what if this runs past bc? */
8665         name_len = tvb_strsize(tvb, offset);
8666         CHECK_BYTE_COUNT(name_len);
8667         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8668             name_len, TRUE);
8669         COUNT_BYTES(name_len);
8670
8671         /* buffer format */
8672         CHECK_BYTE_COUNT(1);
8673         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8674         COUNT_BYTES(1);
8675
8676         /* destination name */
8677         /* XXX - what if this runs past bc? */
8678         name_len = tvb_strsize(tvb, offset);
8679         CHECK_BYTE_COUNT(name_len);
8680         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8681             name_len, TRUE);
8682         COUNT_BYTES(name_len);
8683
8684         END_OF_SMB
8685
8686         return offset;
8687 }
8688
8689 static int
8690 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8691 {
8692         guint16 bc;
8693         guint8 wc;
8694
8695         WORD_COUNT;
8696
8697         /* message group ID */
8698         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
8699         offset += 2;
8700
8701         BYTE_COUNT;
8702
8703         END_OF_SMB
8704
8705         return offset;
8706 }
8707
8708 static int
8709 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8710 {
8711         guint16 bc;
8712         guint8 wc;
8713         guint16 message_len;
8714
8715         WORD_COUNT;
8716
8717         BYTE_COUNT;
8718
8719         /* buffer format */
8720         CHECK_BYTE_COUNT(1);
8721         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8722         COUNT_BYTES(1);
8723
8724         /* message len */
8725         CHECK_BYTE_COUNT(2);
8726         message_len = tvb_get_letohs(tvb, offset);
8727         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8728             message_len);
8729         COUNT_BYTES(2);
8730
8731         /* message */
8732         CHECK_BYTE_COUNT(message_len);
8733         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8734             TRUE);
8735         COUNT_BYTES(message_len);
8736
8737         END_OF_SMB
8738
8739         return offset;
8740 }
8741
8742 static int
8743 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8744 {
8745         int name_len;
8746         guint16 bc;
8747         guint8 wc;
8748
8749         WORD_COUNT;
8750
8751         BYTE_COUNT;
8752
8753         /* buffer format */
8754         CHECK_BYTE_COUNT(1);
8755         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8756         COUNT_BYTES(1);
8757
8758         /* forwarded name */
8759         /* XXX - what if this runs past bc? */
8760         name_len = tvb_strsize(tvb, offset);
8761         CHECK_BYTE_COUNT(name_len);
8762         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
8763             name_len, TRUE);
8764         COUNT_BYTES(name_len);
8765
8766         END_OF_SMB
8767
8768         return offset;
8769 }
8770
8771 static int
8772 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8773 {
8774         int name_len;
8775         guint16 bc;
8776         guint8 wc;
8777
8778         WORD_COUNT;
8779
8780         BYTE_COUNT;
8781
8782         /* buffer format */
8783         CHECK_BYTE_COUNT(1);
8784         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8785         COUNT_BYTES(1);
8786
8787         /* machine name */
8788         /* XXX - what if this runs past bc? */
8789         name_len = tvb_strsize(tvb, offset);
8790         CHECK_BYTE_COUNT(name_len);
8791         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
8792             name_len, TRUE);
8793         COUNT_BYTES(name_len);
8794
8795         END_OF_SMB
8796
8797         return offset;
8798 }
8799
8800
8801 static int
8802 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8803 {
8804         guint8  wc, cmd=0xff;
8805         guint16 andxoffset=0;
8806         guint16 bc;
8807         int fn_len;
8808         const char *fn;
8809
8810         WORD_COUNT;
8811
8812         /* next smb command */
8813         cmd = tvb_get_guint8(tvb, offset);
8814         if(cmd!=0xff){
8815                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8816         } else {
8817                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8818         }
8819         offset += 1;
8820
8821         /* reserved byte */
8822         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8823         offset += 1;
8824
8825         /* andxoffset */
8826         andxoffset = tvb_get_letohs(tvb, offset);
8827         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8828         offset += 2;
8829
8830         /* reserved byte */
8831         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8832         offset += 1;
8833
8834         /* file name len */
8835         fn_len = tvb_get_letohs(tvb, offset);
8836         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8837         offset += 2;
8838
8839         /* Create flags */
8840         offset = dissect_nt_create_bits(tvb, tree, offset);
8841
8842         /* root directory fid */
8843         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8844         offset += 4;
8845
8846         /* nt access mask */
8847         offset = dissect_nt_access_mask(tvb, tree, offset);
8848
8849         /* allocation size */
8850         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8851         offset += 8;
8852
8853         /* Extended File Attributes */
8854         offset = dissect_file_ext_attr(tvb, tree, offset);
8855
8856         /* share access */
8857         offset = dissect_nt_share_access(tvb, tree, offset);
8858
8859         /* create disposition */
8860         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8861         offset += 4;
8862
8863         /* create options */
8864         offset = dissect_nt_create_options(tvb, tree, offset);
8865
8866         /* impersonation level */
8867         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8868         offset += 4;
8869
8870         /* security flags */
8871         offset = dissect_nt_security_flags(tvb, tree, offset);
8872
8873         BYTE_COUNT;
8874
8875         /* file name */
8876         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8877         if (fn == NULL)
8878                 goto endofcommand;
8879         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8880                 fn);
8881         COUNT_BYTES(fn_len);
8882
8883         if (check_col(pinfo->cinfo, COL_INFO)) {
8884                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8885         }
8886
8887         END_OF_SMB
8888
8889         /* call AndXCommand (if there are any) */
8890         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
8891
8892         return offset;
8893 }
8894  
8895
8896 static int
8897 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8898 {
8899         guint8  wc, cmd=0xff;
8900         guint16 andxoffset=0;
8901         guint16 bc;
8902         guint16 fid;
8903
8904         WORD_COUNT;
8905
8906         /* next smb command */
8907         cmd = tvb_get_guint8(tvb, offset);
8908         if(cmd!=0xff){
8909                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8910         } else {
8911                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8912         }
8913         offset += 1;
8914
8915         /* reserved byte */
8916         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8917         offset += 1;
8918
8919         /* andxoffset */
8920         andxoffset = tvb_get_letohs(tvb, offset);
8921         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8922         offset += 2;
8923
8924         /* oplock level */
8925         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8926         offset += 1;
8927
8928         /* fid */
8929         fid = tvb_get_letohs(tvb, offset);
8930         add_fid(tvb, pinfo, tree, offset, 2, fid);
8931         offset += 2;
8932
8933         /* create action */
8934         /*XXX is this really the same as create disposition in the request? it looks so*/
8935         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8936         offset += 4;
8937
8938         /* create time */
8939         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
8940         
8941         /* access time */
8942         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
8943         
8944         /* last write time */
8945         offset = dissect_smb_64bit_time(tvb, tree, offset,
8946                 hf_smb_last_write_time);
8947
8948         /* last change time */
8949         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
8950         
8951         /* Extended File Attributes */
8952         offset = dissect_file_ext_attr(tvb, tree, offset);
8953
8954         /* allocation size */
8955         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8956         offset += 8;
8957
8958         /* end of file */
8959         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8960         offset += 8;
8961
8962         /* File Type */
8963         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8964         offset += 2;
8965
8966         /* IPC State */
8967         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8968
8969         /* is directory */
8970         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8971         offset += 1;
8972
8973         BYTE_COUNT;
8974
8975         END_OF_SMB
8976
8977         /* call AndXCommand (if there are any) */
8978         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
8979
8980         return offset;
8981 }
8982
8983
8984 static int
8985 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8986 {
8987         guint8 wc;
8988         guint16 bc;
8989
8990         WORD_COUNT;
8991  
8992         BYTE_COUNT;
8993
8994         END_OF_SMB
8995
8996         return offset;
8997 }
8998
8999 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9000    BEGIN Transaction/Transaction2 Primary and secondary requests
9001    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9002
9003
9004 static const value_string trans2_cmd_vals[] = {
9005         { 0x00,         "OPEN2" },
9006         { 0x01,         "FIND_FIRST2" },
9007         { 0x02,         "FIND_NEXT2" },
9008         { 0x03,         "QUERY_FS_INFORMATION" },
9009         { 0x04,         "SET_FS_QUOTA" },
9010         { 0x05,         "QUERY_PATH_INFORMATION" },
9011         { 0x06,         "SET_PATH_INFORMATION" },
9012         { 0x07,         "QUERY_FILE_INFORMATION" },
9013         { 0x08,         "SET_FILE_INFORMATION" },
9014         { 0x09,         "FSCTL" },
9015         { 0x0A,         "IOCTL2" },
9016         { 0x0B,         "FIND_NOTIFY_FIRST" },
9017         { 0x0C,         "FIND_NOTIFY_NEXT" },
9018         { 0x0D,         "CREATE_DIRECTORY" },
9019         { 0x0E,         "SESSION_SETUP" },
9020         { 0x10,         "GET_DFS_REFERRAL" },
9021         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9022         { 0,    NULL }
9023 };
9024
9025 static const true_false_string tfs_tf_dtid = {
9026         "Also DISCONNECT TID",
9027         "Do NOT disconnect TID"
9028 };
9029 static const true_false_string tfs_tf_owt = {
9030         "One Way Transaction (NO RESPONSE)",
9031         "Two way transaction"
9032 };
9033
9034 static const true_false_string tfs_ff2_backup = {
9035         "Find WITH backup intent",
9036         "No backup intent"
9037 };
9038 static const true_false_string tfs_ff2_continue = {
9039         "CONTINUE search from previous position",
9040         "New search, do NOT continue from previous position"
9041 };
9042 static const true_false_string tfs_ff2_resume = {
9043         "Return RESUME keys",
9044         "Do NOT return resume keys"
9045 };
9046 static const true_false_string tfs_ff2_close_eos = {
9047         "CLOSE search if END OF SEARCH is reached",
9048         "Do NOT close search if end of search reached"
9049 };
9050 static const true_false_string tfs_ff2_close = {
9051         "CLOSE search after this request",
9052         "Do NOT close search after this request"
9053 };
9054
9055 /* used by
9056    TRANS2_FIND_FIRST2
9057 */
9058 static const value_string ff2_il_vals[] = {
9059         { 1,            "Info Standard  (4.3.4.1)"},
9060         { 2,            "Info Query EA Size  (4.3.4.2)"},
9061         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9062         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9063         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9064         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9065         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9066         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9067         {0, NULL}
9068 };
9069
9070 /* values used by :
9071         TRANS2_QUERY_PATH_INFORMATION
9072         TRANS2_SET_PATH_INFORMATION
9073 */
9074 static const value_string qpi_loi_vals[] = {
9075         { 1,            "Info Standard  (4.2.14.1)"},
9076         { 2,            "Info Query EA Size  (4.2.14.1)"},
9077         { 3,            "Info Query EAs From List  (4.2.14.2)"},
9078         { 4,            "Info Query All EAs  (4.2.14.2)"},
9079         { 6,            "Info Is Name Valid  (4.2.14.3)"},
9080         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
9081         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
9082         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
9083         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
9084         { 0x0107,       "Query File All Info  (4.2.14.8)"},
9085         { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
9086         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
9087         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
9088         { 0x0200,       "Set File Unix Basic"},
9089         { 0x0201,       "Set File Unix Link"},
9090         { 0x0202,       "Set File Unix HardLink"},
9091         { 1004,         "Query File Basic Info  (4.2.14.4)"},
9092         { 1005,         "Query File Standard Info  (4.2.14.5)"},
9093         { 1006,         "Query File Internal Info  (4.2.14.?)"},
9094         { 1007,         "Query File EA Info  (4.2.14.6)"},
9095         { 1009,         "Query File Name Info  (4.2.14.7)"},
9096         { 1010,         "Query File Rename Info  (4.2.14.?)"},
9097         { 1011,         "Query File Link Info  (4.2.14.?)"},
9098         { 1012,         "Query File Names Info  (4.2.14.?)"},
9099         { 1013,         "Query File Disposition Info  (4.2.14.?)"},
9100         { 1014,         "Query File Position Info  (4.2.14.?)"},
9101         { 1015,         "Query File Full EA Info  (4.2.14.?)"},
9102         { 1016,         "Query File Mode Info  (4.2.14.?)"},
9103         { 1017,         "Query File Alignment Info  (4.2.14.?)"},
9104         { 1018,         "Query File All Info  (4.2.14.8)"},
9105         { 1019,         "Query File Allocation Info  (4.2.14.?)"},
9106         { 1020,         "Query File End of File Info  (4.2.14.?)"},
9107         { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
9108         { 1022,         "Query File Stream Info  (4.2.14.10)"},
9109         { 1023,         "Query File Pipe Info  (4.2.14.?)"},
9110         { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
9111         { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
9112         { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
9113         { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
9114         { 1028,         "Query File Compression Info  (4.2.14.11)"},
9115         { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
9116         { 1030,         "Query File Completion Info  (4.2.14.?)"},
9117         { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
9118         { 1032,         "Query File Quota Info  (4.2.14.?)"},
9119         { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
9120         { 1034,         "Query File Network Open Info  (4.2.14.?)"},
9121         { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
9122         { 1036,         "Query File Tracking Info  (4.2.14.?)"},
9123         { 1037,         "Query File Maximum Info  (4.2.14.?)"},
9124         {0, NULL}
9125 };
9126
9127 static const value_string qfsi_vals[] = {
9128         { 1,            "Info Allocation"},
9129         { 2,            "Info Volume"},
9130         { 0x0101,       "Query FS Label Info"},
9131         { 0x0102,       "Query FS Volume Info"},
9132         { 0x0103,       "Query FS Size Info"},
9133         { 0x0104,       "Query FS Device Info"},
9134         { 0x0105,       "Query FS Attribute Info"},
9135         { 1001,         "Query FS Label Info"},
9136         { 1002,         "Query FS Volume Info"},
9137         { 1003,         "Query FS Size Info"},
9138         { 1004,         "Query FS Device Info"},
9139         { 1005,         "Query FS Attribute Info"},
9140         { 1006,         "Query FS Quota Info"},
9141         { 1007,         "Query Full FS Size Info"},
9142         {0, NULL}
9143 };
9144
9145 static const value_string nt_rename_vals[] = {
9146         { 0x0103,       "Create Hard Link"},
9147         {0, NULL}
9148 };
9149
9150
9151 static const value_string delete_pending_vals[] = {
9152         {0,     "Normal, no pending delete"},
9153         {1,     "This object has DELETE PENDING"},
9154         {0, NULL}
9155 };
9156
9157 static const value_string alignment_vals[] = {
9158         {0,     "Byte alignment"},
9159         {1,     "Word (16bit) alignment"},
9160         {3,     "Long (32bit) alignment"},
9161         {7,     "8 byte boundary alignment"},
9162         {0x0f,  "16 byte boundary alignment"},
9163         {0x1f,  "32 byte boundary alignment"},
9164         {0x3f,  "64 byte boundary alignment"},
9165         {0x7f,  "128 byte boundary alignment"},
9166         {0xff,  "256 byte boundary alignment"},
9167         {0x1ff, "512 byte boundary alignment"},
9168         {0, NULL}
9169 };
9170
9171
9172 static const true_false_string tfs_get_dfs_server_hold_storage = {
9173         "Referral SERVER HOLDS STORAGE for the file",
9174         "Referral server does NOT hold storage for the file"
9175 };
9176 static const true_false_string tfs_get_dfs_fielding = {
9177         "The server in referral is FIELDING CAPABLE",
9178         "The server in referrals is NOT fielding capable"
9179 };
9180
9181 static const true_false_string tfs_dfs_referral_flags_strip = {
9182         "STRIP off pathconsumed characters before submitting",
9183         "Do NOT strip off any characters"
9184 };
9185
9186 static const value_string dfs_referral_server_type_vals[] = {
9187         {0,     "Don't know"},
9188         {1,     "SMB Server"},
9189         {2,     "Netware Server"},
9190         {3,     "Domain Server"},
9191         {0, NULL}
9192 };
9193
9194
9195 static const true_false_string tfs_device_char_removable = {
9196         "This is a REMOVABLE device",
9197         "This is NOT a removable device"
9198 };
9199 static const true_false_string tfs_device_char_read_only = {
9200         "This is a READ-ONLY device",
9201         "This is NOT a read-only device"
9202 };
9203 static const true_false_string tfs_device_char_floppy = {
9204         "This is a FLOPPY DISK device",
9205         "This is NOT a floppy disk device"
9206 };
9207 static const true_false_string tfs_device_char_write_once = {
9208         "This is a WRITE-ONCE device",
9209         "This is NOT a write-once device"
9210 };
9211 static const true_false_string tfs_device_char_remote = {
9212         "This is a REMOTE device",
9213         "This is NOT a remote device"
9214 };
9215 static const true_false_string tfs_device_char_mounted = {
9216         "This device is MOUNTED",
9217         "This device is NOT mounted"
9218 };
9219 static const true_false_string tfs_device_char_virtual = {
9220         "This is a VIRTUAL device",
9221         "This is NOT a virtual device"
9222 };
9223
9224
9225 static const true_false_string tfs_fs_attr_css = {
9226         "This FS supports CASE SENSITIVE SEARCHes",
9227         "This FS does NOT support case sensitive searches"
9228 };
9229 static const true_false_string tfs_fs_attr_cpn = {
9230         "This FS supports CASE PRESERVED NAMES",
9231         "This FS does NOT support case preserved names"
9232 };
9233 static const true_false_string tfs_fs_attr_pacls = {
9234         "This FS supports PERSISTENT ACLs",
9235         "This FS does NOT support persistent acls"
9236 };
9237 static const true_false_string tfs_fs_attr_fc = {
9238         "This FS supports COMPRESSED FILES",
9239         "This FS does NOT support compressed files"
9240 };
9241 static const true_false_string tfs_fs_attr_vq = {
9242         "This FS supports VOLUME QUOTAS",
9243         "This FS does NOT support volume quotas"
9244 };
9245 static const true_false_string tfs_fs_attr_dim = {
9246         "This FS is on a MOUNTED DEVICE",
9247         "This FS is NOT on a mounted device"
9248 };
9249 static const true_false_string tfs_fs_attr_vic = {
9250         "This FS is on a COMPRESSED VOLUME",
9251         "This FS is NOT on a compressed volume"
9252 };
9253
9254 #define FF2_RESUME      0x0004
9255
9256 static int
9257 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9258 {
9259         guint16 mask;
9260         proto_item *item = NULL;
9261         proto_tree *tree = NULL;
9262         smb_info_t *si;
9263         smb_transact2_info_t *t2i;
9264
9265         mask = tvb_get_letohs(tvb, offset);
9266
9267         si = (smb_info_t *)pinfo->private_data;
9268         if (si->sip != NULL) {
9269                 t2i = si->sip->extra_info;
9270                 if (t2i != NULL) {
9271                         if (!pinfo->fd->flags.visited)
9272                                 t2i->resume_keys = (mask & FF2_RESUME);
9273                 }
9274         }
9275
9276         if(parent_tree){
9277                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9278                         "Flags: 0x%04x", mask);
9279                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9280         }
9281
9282         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9283                 tvb, offset, 2, mask);
9284         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9285                 tvb, offset, 2, mask);
9286         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9287                 tvb, offset, 2, mask);
9288         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9289                 tvb, offset, 2, mask);
9290         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9291                 tvb, offset, 2, mask);
9292
9293         offset += 2;
9294
9295         return offset;
9296 }
9297
9298 #if 0
9299 static int
9300 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9301 {
9302         guint16 mask;
9303         proto_item *item = NULL;
9304         proto_tree *tree = NULL;
9305
9306         mask = tvb_get_letohs(tvb, offset);
9307
9308         if(parent_tree){
9309                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9310                         "IO Flag: 0x%04x", mask);
9311                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9312         }
9313
9314         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9315                 tvb, offset, 2, mask);
9316         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9317                 tvb, offset, 2, mask);
9318
9319         offset += 2;
9320
9321         return offset;
9322 }
9323 #endif
9324
9325 static int
9326 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9327     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9328 {
9329         proto_item *item = NULL;
9330         proto_tree *tree = NULL;
9331         smb_info_t *si;
9332         smb_transact2_info_t *t2i;
9333         int fn_len;
9334         const char *fn;
9335         int old_offset = offset;
9336
9337         si = (smb_info_t *)pinfo->private_data;
9338         if (si->sip != NULL)
9339                 t2i = si->sip->extra_info;
9340         else
9341                 t2i = NULL;
9342
9343         if(parent_tree){
9344                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9345                                 "%s Parameters",
9346                                 val_to_str(subcmd, trans2_cmd_vals, 
9347                                            "Unknown (0x%02x)"));
9348                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9349         }
9350
9351         switch(subcmd){
9352         case 0x00:      /*TRANS2_OPEN2*/
9353                 /* open flags */
9354                 CHECK_BYTE_COUNT_TRANS(2);
9355                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9356                 bc -= 2;
9357
9358                 /* desired access */
9359                 CHECK_BYTE_COUNT_TRANS(2);
9360                 offset = dissect_access(tvb, tree, offset, "Desired");
9361                 bc -= 2;
9362
9363                 /* Search Attributes */
9364                 CHECK_BYTE_COUNT_TRANS(2);
9365                 offset = dissect_search_attributes(tvb, tree, offset);
9366                 bc -= 2;
9367
9368                 /* File Attributes */
9369                 CHECK_BYTE_COUNT_TRANS(2);
9370                 offset = dissect_file_attributes(tvb, tree, offset);
9371                 bc -= 2;
9372
9373                 /* create time */
9374                 CHECK_BYTE_COUNT_TRANS(4);
9375                 offset = dissect_smb_datetime(tvb, tree, offset,
9376                         hf_smb_create_time,
9377                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9378                         TRUE);
9379                 bc -= 4;
9380
9381                 /* open function */
9382                 CHECK_BYTE_COUNT_TRANS(2);
9383                 offset = dissect_open_function(tvb, tree, offset);
9384                 bc -= 2;
9385
9386                 /* allocation size */
9387                 CHECK_BYTE_COUNT_TRANS(4);
9388                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9389                 COUNT_BYTES_TRANS(4);
9390
9391                 /* 10 reserved bytes */
9392                 CHECK_BYTE_COUNT_TRANS(10);
9393                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9394                 COUNT_BYTES_TRANS(10);
9395
9396                 /* file name */
9397                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9398                 CHECK_STRING_TRANS(fn);
9399                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9400                         fn);
9401                 COUNT_BYTES_TRANS(fn_len);
9402
9403                 if (check_col(pinfo->cinfo, COL_INFO)) {
9404                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9405                         fn);
9406                 }
9407                 break;
9408         case 0x01:      /*TRANS2_FIND_FIRST2*/
9409                 /* Search Attributes */
9410                 CHECK_BYTE_COUNT_TRANS(2);
9411                 offset = dissect_search_attributes(tvb, tree, offset);
9412                 bc -= 2;
9413
9414                 /* search count */
9415                 CHECK_BYTE_COUNT_TRANS(2);
9416                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9417                 COUNT_BYTES_TRANS(2);
9418
9419                 /* Find First2 flags */
9420                 CHECK_BYTE_COUNT_TRANS(2);
9421                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9422                 bc -= 2;
9423
9424                 /* Find First2 information level */
9425                 CHECK_BYTE_COUNT_TRANS(2);
9426                 si->info_level = tvb_get_letohs(tvb, offset);
9427                 if (!pinfo->fd->flags.visited)
9428                         t2i->info_level = si->info_level;
9429                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9430                 COUNT_BYTES_TRANS(2);
9431
9432                 /* storage type */
9433                 CHECK_BYTE_COUNT_TRANS(4);
9434                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9435                 COUNT_BYTES_TRANS(4);
9436
9437                 /* search pattern */
9438                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9439                 CHECK_STRING_TRANS(fn);
9440                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9441                         fn);
9442                 COUNT_BYTES_TRANS(fn_len);
9443
9444                 if (check_col(pinfo->cinfo, COL_INFO)) {
9445                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9446                         fn);
9447                 }
9448
9449                 break;
9450         case 0x02:      /*TRANS2_FIND_NEXT2*/
9451                 /* sid */
9452                 CHECK_BYTE_COUNT_TRANS(2);
9453                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
9454                 COUNT_BYTES_TRANS(2);
9455
9456                 /* search count */
9457                 CHECK_BYTE_COUNT_TRANS(2);
9458                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9459                 COUNT_BYTES_TRANS(2);
9460
9461                 /* Find First2 information level */
9462                 CHECK_BYTE_COUNT_TRANS(2);
9463                 si->info_level = tvb_get_letohs(tvb, offset);
9464                 if (!pinfo->fd->flags.visited)
9465                         t2i->info_level = si->info_level;
9466                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9467                 COUNT_BYTES_TRANS(2);
9468
9469                 /* resume key */
9470                 CHECK_BYTE_COUNT_TRANS(4);
9471                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9472                 COUNT_BYTES_TRANS(4);
9473
9474                 /* Find First2 flags */
9475                 CHECK_BYTE_COUNT_TRANS(2);
9476                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9477                 bc -= 2;
9478
9479                 /* file name */
9480                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9481                 CHECK_STRING_TRANS(fn);
9482                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9483                         fn);
9484                 COUNT_BYTES_TRANS(fn_len);
9485
9486                 if (check_col(pinfo->cinfo, COL_INFO)) {
9487                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9488                         fn);
9489                 }
9490
9491                 break;
9492         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9493                 /* level of interest */
9494                 CHECK_BYTE_COUNT_TRANS(2);
9495                 si->info_level = tvb_get_letohs(tvb, offset);
9496                 if (!pinfo->fd->flags.visited)
9497                         t2i->info_level = si->info_level;
9498                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9499                 COUNT_BYTES_TRANS(2);
9500
9501                 break;
9502         case 0x05:      /*TRANS2_QUERY_PATH_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_qpi_loi, tvb, offset, 2, si->info_level);
9509                 COUNT_BYTES_TRANS(2);
9510                 
9511                 /* 4 reserved bytes */
9512                 CHECK_BYTE_COUNT_TRANS(4);
9513                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9514                 COUNT_BYTES_TRANS(4);
9515
9516                 /* file name */
9517                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9518                 CHECK_STRING_TRANS(fn);
9519                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9520                         fn);
9521                 COUNT_BYTES_TRANS(fn_len);
9522
9523                 if (check_col(pinfo->cinfo, COL_INFO)) {
9524                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9525                         fn);
9526                 }
9527
9528                 break;
9529         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9530                 /* level of interest */
9531                 CHECK_BYTE_COUNT_TRANS(2);
9532                 si->info_level = tvb_get_letohs(tvb, offset);
9533                 if (!pinfo->fd->flags.visited)
9534                         t2i->info_level = si->info_level;
9535                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9536                 COUNT_BYTES_TRANS(2);
9537                 
9538                 /* 4 reserved bytes */
9539                 CHECK_BYTE_COUNT_TRANS(4);
9540                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9541                 COUNT_BYTES_TRANS(4);
9542
9543                 /* file name */
9544                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9545                 CHECK_STRING_TRANS(fn);
9546                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9547                         fn);
9548                 COUNT_BYTES_TRANS(fn_len);
9549
9550                 if (check_col(pinfo->cinfo, COL_INFO)) {
9551                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9552                         fn);
9553                 }
9554
9555                 break;
9556         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9557                 guint16 fid;
9558
9559                 /* fid */
9560                 CHECK_BYTE_COUNT_TRANS(2);
9561                 fid = tvb_get_letohs(tvb, offset);
9562                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9563                 COUNT_BYTES_TRANS(2);
9564
9565                 /* level of interest */
9566                 CHECK_BYTE_COUNT_TRANS(2);
9567                 si->info_level = tvb_get_letohs(tvb, offset);
9568                 if (!pinfo->fd->flags.visited)
9569                         t2i->info_level = si->info_level;
9570                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9571                 COUNT_BYTES_TRANS(2);
9572                 
9573                 break;
9574         }
9575         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9576                 guint16 fid;
9577
9578                 /* fid */
9579                 CHECK_BYTE_COUNT_TRANS(2);
9580                 fid = tvb_get_letohs(tvb, offset);
9581                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9582                 COUNT_BYTES_TRANS(2);
9583
9584                 /* level of interest */
9585                 CHECK_BYTE_COUNT_TRANS(2);
9586                 si->info_level = tvb_get_letohs(tvb, offset);
9587                 if (!pinfo->fd->flags.visited)
9588                         t2i->info_level = si->info_level;
9589                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9590                 COUNT_BYTES_TRANS(2);
9591                 
9592 #if 0
9593                 /*
9594                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9595                  * Extensions Version 3.0, Document Version 1.11,
9596                  * July 19, 1990" says this is I/O flags, but it's
9597                  * reserved in the SNIA spec, and some clients appear
9598                  * to leave junk in it.
9599                  *
9600                  * Is this some field used only if a particular
9601                  * dialect was negotiated, so that clients can feel
9602                  * safe not setting it if they haven't negotiated that
9603                  * dialect?  Or do the (non-OS/2) clients simply not care
9604                  * about that particular OS/2-oriented dialect?
9605                  */
9606
9607                 /* IO Flag */
9608                 CHECK_BYTE_COUNT_TRANS(2);
9609                 offset = dissect_sfi_ioflag(tvb, tree, offset);
9610                 bc -= 2;
9611 #else
9612                 /* 2 reserved bytes */
9613                 CHECK_BYTE_COUNT_TRANS(2);
9614                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9615                 COUNT_BYTES_TRANS(2);
9616 #endif
9617
9618                 break;
9619         }
9620         case 0x09:      /*TRANS2_FSCTL*/
9621                 /* this call has no parameter block in the request */
9622
9623                 /*
9624                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9625                  * Extensions Version 3.0, Document Version 1.11,
9626                  * July 19, 1990" says this this contains a
9627                  * "File system specific parameter block".  (That means
9628                  * we may not be able to dissect it in any case.)
9629                  */
9630                 break;
9631         case 0x0a:      /*TRANS2_IOCTL2*/
9632                 /* this call has no parameter block in the request */
9633
9634                 /*
9635                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9636                  * Extensions Version 3.0, Document Version 1.11,
9637                  * July 19, 1990" says this this contains a
9638                  * "Device/function specific parameter block".  (That
9639                  * means we may not be able to dissect it in any case.)
9640                  */
9641                 break;
9642         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
9643                 /* Search Attributes */
9644                 CHECK_BYTE_COUNT_TRANS(2);
9645                 offset = dissect_search_attributes(tvb, tree, offset);
9646                 bc -= 2;
9647
9648                 /* Number of changes to wait for */
9649                 CHECK_BYTE_COUNT_TRANS(2);
9650                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9651                 COUNT_BYTES_TRANS(2);
9652
9653                 /* Find Notify information level */
9654                 CHECK_BYTE_COUNT_TRANS(2);
9655                 si->info_level = tvb_get_letohs(tvb, offset);
9656                 if (!pinfo->fd->flags.visited)
9657                         t2i->info_level = si->info_level;
9658                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
9659                 COUNT_BYTES_TRANS(2);
9660
9661                 /* 4 reserved bytes */
9662                 CHECK_BYTE_COUNT_TRANS(4);
9663                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9664                 COUNT_BYTES_TRANS(4);
9665
9666                 /* file name */
9667                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9668                 CHECK_STRING_TRANS(fn);
9669                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9670                         fn);
9671                 COUNT_BYTES_TRANS(fn_len);
9672
9673                 if (check_col(pinfo->cinfo, COL_INFO)) {
9674                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9675                         fn);
9676                 }
9677
9678                 break;
9679         }
9680         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
9681                 /* Monitor handle */
9682                 CHECK_BYTE_COUNT_TRANS(2);
9683                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
9684                 COUNT_BYTES_TRANS(2);
9685
9686                 /* Number of changes to wait for */
9687                 CHECK_BYTE_COUNT_TRANS(2);
9688                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9689                 COUNT_BYTES_TRANS(2);
9690
9691                 break;
9692         }
9693         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9694                 /* 4 reserved bytes */
9695                 CHECK_BYTE_COUNT_TRANS(4);
9696                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9697                 COUNT_BYTES_TRANS(4);
9698
9699                 /* dir name */
9700                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
9701                         FALSE, FALSE, &bc);
9702                 CHECK_STRING_TRANS(fn);
9703                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9704                         fn);
9705                 COUNT_BYTES_TRANS(fn_len);
9706
9707                 if (check_col(pinfo->cinfo, COL_INFO)) {
9708                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9709                         fn);
9710                 }
9711                 break;
9712         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9713                 /* XXX unknown structure*/
9714                 break;
9715         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9716                 /* referral level */
9717                 CHECK_BYTE_COUNT_TRANS(2);
9718                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9719                 COUNT_BYTES_TRANS(2);
9720                 
9721                 /* file name */
9722                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9723                 CHECK_STRING_TRANS(fn);
9724                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9725                         fn);
9726                 COUNT_BYTES_TRANS(fn_len);
9727
9728                 if (check_col(pinfo->cinfo, COL_INFO)) {
9729                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9730                         fn);
9731                 }
9732
9733                 break;
9734         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9735                 /* file name */
9736                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9737                 CHECK_STRING_TRANS(fn);
9738                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9739                         fn);
9740                 COUNT_BYTES_TRANS(fn_len);
9741
9742                 if (check_col(pinfo->cinfo, COL_INFO)) {
9743                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9744                         fn);
9745                 }
9746
9747                 break;
9748         }
9749
9750         /* ooops there were data we didnt know how to process */
9751         if((offset-old_offset) < bc){
9752                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9753                     bc - (offset-old_offset), TRUE);
9754                 offset += bc - (offset-old_offset);
9755         }
9756
9757         return offset;
9758 }
9759
9760 /*
9761  * XXX - just use "dissect_connect_flags()" here?
9762  */
9763 static guint16
9764 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9765 {
9766         guint16 mask;
9767         proto_item *item = NULL;
9768         proto_tree *tree = NULL;
9769
9770         mask = tvb_get_letohs(tvb, offset);
9771
9772         if(parent_tree){
9773                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9774                         "Flags: 0x%04x", mask);
9775                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9776         }
9777
9778         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9779                 tvb, offset, 2, mask);
9780         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9781                 tvb, offset, 2, mask);
9782
9783         return mask;
9784 }
9785  
9786
9787 static int
9788 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9789 {
9790         guint16 mask;
9791         proto_item *item = NULL;
9792         proto_tree *tree = NULL;
9793
9794         mask = tvb_get_letohs(tvb, offset);
9795
9796         if(parent_tree){
9797                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9798                         "Flags: 0x%04x", mask);
9799                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9800         }
9801
9802         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9803                 tvb, offset, 2, mask);
9804         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9805                 tvb, offset, 2, mask);
9806
9807         offset += 2;
9808         return offset;
9809 }
9810
9811 static int
9812 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9813 {
9814         guint16 mask;
9815         proto_item *item = NULL;
9816         proto_tree *tree = NULL;
9817
9818         mask = tvb_get_letohs(tvb, offset);
9819
9820         if(parent_tree){
9821                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9822                         "Flags: 0x%04x", mask);
9823                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9824         }
9825
9826         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9827                 tvb, offset, 2, mask);
9828
9829         offset += 2;
9830
9831         return offset;
9832 }
9833
9834
9835 /* dfs inconsistency data  (4.4.2)
9836 */
9837 static int
9838 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9839     proto_tree *tree, int offset, guint16 *bcp)
9840 {
9841         int fn_len;
9842         const char *fn;
9843
9844         /*XXX shouldn this data hold version and size? unclear from doc*/
9845         /* referral version */
9846         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9847         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9848         COUNT_BYTES_TRANS_SUBR(2);
9849
9850         /* referral size */
9851         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9852         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9853         COUNT_BYTES_TRANS_SUBR(2);
9854
9855         /* referral server type */
9856         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9857         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9858         COUNT_BYTES_TRANS_SUBR(2);
9859
9860         /* referral flags */
9861         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9862         offset = dissect_dfs_referral_flags(tvb, tree, offset);
9863         *bcp -= 2;
9864
9865         /* node name */
9866         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9867         CHECK_STRING_TRANS_SUBR(fn);
9868         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9869                 fn);
9870         COUNT_BYTES_TRANS_SUBR(fn_len);
9871
9872         return offset;
9873 }
9874
9875 /* get dfs referral data  (4.4.1)
9876 */
9877 static int
9878 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9879     proto_tree *tree, int offset, guint16 *bcp)
9880 {
9881         guint16 numref;
9882         guint16 refsize;
9883         guint16 pathoffset;
9884         guint16 altpathoffset;
9885         guint16 nodeoffset;
9886         int fn_len;
9887         int stroffset;
9888         int offsetoffset;
9889         guint16 save_bc;
9890         const char *fn;
9891         int unklen;
9892         int ucstring_end;
9893         int ucstring_len;
9894
9895         /* path consumed */
9896         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9897         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9898         COUNT_BYTES_TRANS_SUBR(2);
9899
9900         /* num referrals */
9901         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9902         numref = tvb_get_letohs(tvb, offset);
9903         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9904         COUNT_BYTES_TRANS_SUBR(2);
9905
9906         /* get dfs flags */
9907         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9908         offset = dissect_get_dfs_flags(tvb, tree, offset);
9909         *bcp -= 2;
9910
9911         /* XXX - in at least one capture there appears to be 2 bytes
9912            of stuff after the Dfs flags, perhaps so that the header
9913            in front of the referral list is a multiple of 4 bytes long. */
9914         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9915         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9916         COUNT_BYTES_TRANS_SUBR(2);
9917
9918         /* if there are any referrals */
9919         if(numref){
9920                 proto_item *ref_item = NULL;
9921                 proto_tree *ref_tree = NULL;
9922                 int old_offset=offset;
9923
9924                 if(tree){
9925                         ref_item = proto_tree_add_text(tree,
9926                                 tvb, offset, *bcp, "Referrals");
9927                         ref_tree = proto_item_add_subtree(ref_item,
9928                                 ett_smb_dfs_referrals);
9929                 }
9930                 ucstring_end = -1;
9931
9932                 while(numref--){
9933                         proto_item *ri = NULL;
9934                         proto_tree *rt = NULL;
9935                         int old_offset=offset;
9936                         guint16 version;
9937
9938                         if(tree){
9939                                 ri = proto_tree_add_text(ref_tree,
9940                                         tvb, offset, *bcp, "Referral");
9941                                 rt = proto_item_add_subtree(ri,
9942                                         ett_smb_dfs_referral);
9943                         }
9944                 
9945                         /* referral version */
9946                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9947                         version = tvb_get_letohs(tvb, offset);
9948                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9949                                 tvb, offset, 2, version);
9950                         COUNT_BYTES_TRANS_SUBR(2);
9951
9952                         /* referral size */
9953                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9954                         refsize = tvb_get_letohs(tvb, offset);
9955                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9956                         COUNT_BYTES_TRANS_SUBR(2);
9957
9958                         /* referral server type */
9959                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9960                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9961                         COUNT_BYTES_TRANS_SUBR(2);
9962
9963                         /* referral flags */
9964                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9965                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
9966                         *bcp -= 2;
9967
9968                         switch(version){
9969
9970                         case 1:
9971                                 /* node name */
9972                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9973                                 CHECK_STRING_TRANS_SUBR(fn);
9974                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9975                                         fn);
9976                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9977                                 break;
9978
9979                         case 2:
9980                         case 3: /* XXX - like version 2, but not identical;
9981                                    seen in a capture, but the format isn't
9982                                    documented */
9983                                 /* proximity */
9984                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9985                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9986                                 COUNT_BYTES_TRANS_SUBR(2);
9987
9988                                 /* ttl */
9989                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9990                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9991                                 COUNT_BYTES_TRANS_SUBR(2);
9992
9993                                 /* path offset */
9994                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9995                                 pathoffset = tvb_get_letohs(tvb, offset);
9996                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9997                                 COUNT_BYTES_TRANS_SUBR(2);
9998
9999                                 /* alt path offset */
10000                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10001                                 altpathoffset = tvb_get_letohs(tvb, offset);
10002                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10003                                 COUNT_BYTES_TRANS_SUBR(2);
10004
10005                                 /* node offset */
10006                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10007                                 nodeoffset = tvb_get_letohs(tvb, offset);
10008                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10009                                 COUNT_BYTES_TRANS_SUBR(2);
10010
10011                                 /* path */
10012                                 if (pathoffset != 0) {
10013                                         stroffset = old_offset + pathoffset;
10014                                         offsetoffset = stroffset - offset;
10015                                         if (offsetoffset > 0 &&
10016                                             *bcp > offsetoffset) {
10017                                                 save_bc = *bcp;
10018                                                 *bcp -= offsetoffset;
10019                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10020                                                 CHECK_STRING_TRANS_SUBR(fn);
10021                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10022                                                         fn);
10023                                                 stroffset += fn_len;
10024                                                 if (ucstring_end < stroffset)
10025                                                         ucstring_end = stroffset;
10026                                                 *bcp = save_bc;
10027                                         }
10028                                 }
10029                         
10030                                 /* alt path */
10031                                 if (altpathoffset != 0) {
10032                                         stroffset = old_offset + altpathoffset;
10033                                         offsetoffset = stroffset - offset;
10034                                         if (offsetoffset > 0 &&
10035                                             *bcp > offsetoffset) {
10036                                                 save_bc = *bcp;
10037                                                 *bcp -= offsetoffset;
10038                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10039                                                 CHECK_STRING_TRANS_SUBR(fn);
10040                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10041                                                         fn);
10042                                                 stroffset += fn_len;
10043                                                 if (ucstring_end < stroffset)
10044                                                         ucstring_end = stroffset;
10045                                                 *bcp = save_bc;
10046                                         }
10047                                 }
10048                         
10049                                 /* node */
10050                                 if (nodeoffset != 0) {
10051                                         stroffset = old_offset + nodeoffset;
10052                                         offsetoffset = stroffset - offset;
10053                                         if (offsetoffset > 0 &&
10054                                             *bcp > offsetoffset) {
10055                                                 save_bc = *bcp;
10056                                                 *bcp -= offsetoffset;
10057                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
10058                                                 CHECK_STRING_TRANS_SUBR(fn);
10059                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10060                                                         fn);
10061                                                 stroffset += fn_len;
10062                                                 if (ucstring_end < stroffset)
10063                                                         ucstring_end = stroffset;
10064                                                 *bcp = save_bc;
10065                                         }
10066                                 }
10067                                 break;
10068                         }
10069
10070                         /*
10071                          * Show anything beyond the length of the referral
10072                          * as unknown data.
10073                          */
10074                         unklen = (old_offset + refsize) - offset;
10075                         if (unklen < 0) {
10076                                 /*
10077                                  * XXX - the length is bogus.
10078                                  */
10079                                 unklen = 0;
10080                         }
10081                         if (unklen != 0) {
10082                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10083                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10084                                     offset, unklen, TRUE);
10085                                 COUNT_BYTES_TRANS_SUBR(unklen);
10086                         }
10087
10088                         proto_item_set_len(ri, offset-old_offset);
10089                 }
10090
10091                 /*
10092                  * Treat the offset past the end of the last Unicode
10093                  * string after the referrals (if any) as the last
10094                  * offset.
10095                  */
10096                 if (ucstring_end > offset) {
10097                         ucstring_len = ucstring_end - offset;
10098                         if (*bcp < ucstring_len)
10099                                 ucstring_len = *bcp;
10100                         offset += ucstring_len;
10101                         *bcp -= ucstring_len;
10102                 }
10103                 proto_item_set_len(ref_item, offset-old_offset);
10104         }
10105
10106         return offset;
10107 }
10108
10109
10110 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10111    as described in 4.2.14.1
10112 */
10113 static int
10114 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10115     int offset, guint16 *bcp, gboolean *trunc)
10116 {
10117         /* create time */
10118         CHECK_BYTE_COUNT_SUBR(4);
10119         offset = dissect_smb_datetime(tvb, tree, offset,
10120                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10121                 FALSE);
10122         *bcp -= 4;
10123
10124         /* access time */
10125         CHECK_BYTE_COUNT_SUBR(4);
10126         offset = dissect_smb_datetime(tvb, tree, offset,
10127                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10128                 FALSE);
10129         *bcp -= 4;
10130
10131         /* last write time */
10132         CHECK_BYTE_COUNT_SUBR(4);
10133         offset = dissect_smb_datetime(tvb, tree, offset,
10134                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10135                 FALSE);
10136         *bcp -= 4;
10137
10138         /* data size */
10139         CHECK_BYTE_COUNT_SUBR(4);
10140         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10141         COUNT_BYTES_SUBR(4);
10142
10143         /* allocation size */
10144         CHECK_BYTE_COUNT_SUBR(4);
10145         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10146         COUNT_BYTES_SUBR(4);
10147
10148         /* File Attributes */
10149         CHECK_BYTE_COUNT_SUBR(2);
10150         offset = dissect_file_attributes(tvb, tree, offset);
10151         *bcp -= 2;
10152
10153         /* ea size */
10154         CHECK_BYTE_COUNT_SUBR(4);
10155         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10156         COUNT_BYTES_SUBR(4);
10157
10158         *trunc = FALSE;
10159         return offset;
10160 }
10161
10162 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10163    as described in 4.2.14.2
10164 */
10165 static int
10166 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10167     int offset, guint16 *bcp, gboolean *trunc)
10168 {
10169         /* list length */
10170         CHECK_BYTE_COUNT_SUBR(4);
10171         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
10172         COUNT_BYTES_SUBR(4);
10173
10174         *trunc = FALSE;
10175         return offset;
10176 }
10177
10178 /* this dissects the SMB_INFO_IS_NAME_VALID
10179    as described in 4.2.14.3
10180 */
10181 static int
10182 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10183     int offset, guint16 *bcp, gboolean *trunc)
10184 {
10185         int fn_len;
10186         const char *fn;
10187
10188         /* file name */
10189         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10190         CHECK_STRING_SUBR(fn);
10191         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10192                 fn);
10193         COUNT_BYTES_SUBR(fn_len);
10194
10195         *trunc = FALSE;
10196         return offset;
10197 }
10198
10199 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10200    as described in 4.2.14.4
10201 */
10202 static int
10203 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10204     int offset, guint16 *bcp, gboolean *trunc)
10205 {
10206         /* create time */
10207         CHECK_BYTE_COUNT_SUBR(8);
10208         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10209         *bcp -= 8;
10210         
10211         /* access time */
10212         CHECK_BYTE_COUNT_SUBR(8);
10213         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10214         *bcp -= 8;
10215         
10216         /* last write time */
10217         CHECK_BYTE_COUNT_SUBR(8);
10218         offset = dissect_smb_64bit_time(tvb, tree, offset,
10219                 hf_smb_last_write_time);
10220         *bcp -= 8;
10221         
10222         /* last change time */
10223         CHECK_BYTE_COUNT_SUBR(8);
10224         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10225         *bcp -= 8;
10226         
10227         /* File Attributes */
10228         CHECK_BYTE_COUNT_SUBR(2);
10229         offset = dissect_file_attributes(tvb, tree, offset);
10230         *bcp -= 2;
10231
10232         *trunc = FALSE;
10233         return offset;
10234 }
10235
10236 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10237    as described in 4.2.14.5
10238 */
10239 static int
10240 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10241     int offset, guint16 *bcp, gboolean *trunc)
10242 {
10243         /* allocation size */
10244         CHECK_BYTE_COUNT_SUBR(8);
10245         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10246         COUNT_BYTES_SUBR(8);
10247
10248         /* end of file */
10249         CHECK_BYTE_COUNT_SUBR(8);
10250         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10251         COUNT_BYTES_SUBR(8);
10252
10253         /* number of links */
10254         CHECK_BYTE_COUNT_SUBR(4);
10255         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10256         COUNT_BYTES_SUBR(4);
10257
10258         /* delete pending */
10259         CHECK_BYTE_COUNT_SUBR(2);
10260         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
10261         COUNT_BYTES_SUBR(2);
10262
10263         /* is directory */
10264         CHECK_BYTE_COUNT_SUBR(1);
10265         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10266         COUNT_BYTES_SUBR(1);
10267
10268         *trunc = FALSE;
10269         return offset;
10270 }
10271
10272 /* this dissects the SMB_QUERY_FILE_EA_INFO
10273    as described in 4.2.14.6
10274 */
10275 static int
10276 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10277     int offset, guint16 *bcp, gboolean *trunc)
10278 {
10279         /* ea size */
10280         CHECK_BYTE_COUNT_SUBR(4);
10281         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10282         COUNT_BYTES_SUBR(4);
10283
10284         *trunc = FALSE;
10285         return offset;
10286 }
10287
10288 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10289    as described in 4.2.14.7
10290    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10291    as described in 4.2.14.9
10292 */
10293 static int
10294 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10295     int offset, guint16 *bcp, gboolean *trunc)
10296 {
10297         int fn_len;
10298         const char *fn;
10299
10300         /* file name len */
10301         CHECK_BYTE_COUNT_SUBR(4);
10302         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10303         COUNT_BYTES_SUBR(4);
10304
10305         /* file name */
10306         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10307         CHECK_STRING_SUBR(fn);
10308         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10309                 fn);
10310         COUNT_BYTES_SUBR(fn_len);
10311
10312         *trunc = FALSE;
10313         return offset;
10314 }
10315
10316 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10317    as described in 4.2.14.8
10318 */
10319 static int
10320 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10321     int offset, guint16 *bcp, gboolean *trunc)
10322 {
10323
10324         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
10325         if (trunc)
10326                 return offset;
10327         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
10328         if (trunc)
10329                 return offset;
10330
10331         /* index number */
10332         CHECK_BYTE_COUNT_SUBR(8);
10333         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10334         COUNT_BYTES_SUBR(8);
10335
10336         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10337         if (trunc)
10338                 return offset;
10339
10340         /* access flags */
10341         CHECK_BYTE_COUNT_SUBR(4);
10342         offset = dissect_nt_access_mask(tvb, tree, offset);
10343         COUNT_BYTES_SUBR(4);
10344
10345         /* index number */
10346         CHECK_BYTE_COUNT_SUBR(8);
10347         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10348         COUNT_BYTES_SUBR(8);
10349
10350         /* current offset */
10351         CHECK_BYTE_COUNT_SUBR(8);
10352         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10353         COUNT_BYTES_SUBR(8);
10354
10355         /* mode */
10356         CHECK_BYTE_COUNT_SUBR(4);
10357         offset = dissect_nt_create_options(tvb, tree, offset);
10358         *bcp -= 4;
10359
10360         /* alignment */
10361         CHECK_BYTE_COUNT_SUBR(4);
10362         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10363         COUNT_BYTES_SUBR(4);
10364         
10365         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10366
10367         return offset;
10368 }
10369
10370 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10371    as described in 4.2.14.10
10372 */
10373 static int
10374 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10375     int offset, guint16 *bcp, gboolean *trunc)
10376 {
10377         proto_item *item;
10378         proto_tree *tree;
10379         int old_offset;
10380         guint32 neo;
10381         int fn_len;
10382         const char *fn;
10383         int padcnt;
10384
10385         for (;;) {
10386                 old_offset = offset;
10387
10388                 /* next entry offset */
10389                 CHECK_BYTE_COUNT_SUBR(4);
10390                 if(parent_tree){
10391                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10392                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10393                 } else {
10394                         item = NULL;
10395                         tree = NULL;
10396                 }
10397
10398                 neo = tvb_get_letohl(tvb, offset);
10399                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10400                 COUNT_BYTES_SUBR(4);
10401         
10402                 /* stream name len */
10403                 CHECK_BYTE_COUNT_SUBR(4);
10404                 fn_len = tvb_get_letohl(tvb, offset);
10405                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10406                 COUNT_BYTES_SUBR(4);
10407         
10408                 /* stream size */
10409                 CHECK_BYTE_COUNT_SUBR(8);
10410                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10411                 COUNT_BYTES_SUBR(8);
10412
10413                 /* allocation size */
10414                 CHECK_BYTE_COUNT_SUBR(8);
10415                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10416                 COUNT_BYTES_SUBR(8);
10417
10418                 /* stream name */
10419                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10420                 CHECK_STRING_SUBR(fn);
10421                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10422                         fn);
10423                 COUNT_BYTES_SUBR(fn_len);
10424  
10425                 proto_item_append_text(item, ": %s", fn);
10426                 proto_item_set_len(item, offset-old_offset);
10427
10428                 if (neo == 0)
10429                         break;  /* no more structures */
10430
10431                 /* skip to next structure */
10432                 padcnt = (old_offset + neo) - offset;
10433                 if (padcnt < 0) {
10434                         /*
10435                          * XXX - this is bogus; flag it?
10436                          */
10437                         padcnt = 0;
10438                 }
10439                 if (padcnt != 0) {
10440                         CHECK_BYTE_COUNT_SUBR(padcnt);
10441                         COUNT_BYTES_SUBR(padcnt);
10442                 }
10443         }
10444
10445         *trunc = FALSE;
10446         return offset;
10447 }
10448
10449 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10450    as described in 4.2.14.11
10451 */
10452 static int
10453 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10454     int offset, guint16 *bcp, gboolean *trunc)
10455 {
10456         /* compressed file size */
10457         CHECK_BYTE_COUNT_SUBR(8);
10458         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10459         COUNT_BYTES_SUBR(8);
10460
10461         /* compression format */
10462         CHECK_BYTE_COUNT_SUBR(2);
10463         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10464         COUNT_BYTES_SUBR(2);
10465         
10466         /* compression unit shift */
10467         CHECK_BYTE_COUNT_SUBR(1);
10468         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10469         COUNT_BYTES_SUBR(1);
10470         
10471         /* compression chunk shift */
10472         CHECK_BYTE_COUNT_SUBR(1);
10473         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10474         COUNT_BYTES_SUBR(1);
10475         
10476         /* compression cluster shift */
10477         CHECK_BYTE_COUNT_SUBR(1);
10478         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10479         COUNT_BYTES_SUBR(1);
10480         
10481         /* 3 reserved bytes */
10482         CHECK_BYTE_COUNT_SUBR(3);
10483         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10484         COUNT_BYTES_SUBR(3);
10485
10486         *trunc = FALSE;
10487         return offset;
10488 }
10489
10490
10491
10492 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
10493 static int
10494 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10495     int offset, guint16 *bcp)
10496 {
10497         smb_info_t *si;
10498         gboolean trunc;
10499
10500         if(!*bcp){
10501                 return offset;
10502         }
10503         
10504         si = (smb_info_t *)pinfo->private_data;
10505         switch(si->info_level){
10506         case 1:         /*Info Standard*/
10507         case 2:         /*Info Query EA Size*/
10508                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
10509                     &trunc);
10510                 break;
10511         case 3:         /*Info Query EAs From List*/
10512         case 4:         /*Info Query All EAs*/
10513                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
10514                     &trunc);
10515                 break;
10516         case 6:         /*Info Is Name Valid*/
10517                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
10518                     &trunc);
10519                 break;
10520         case 0x0101:    /*Query File Basic Info*/
10521         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10522                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
10523                     &trunc);
10524                 break;
10525         case 0x0102:    /*Query File Standard Info*/
10526         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
10527                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
10528                     &trunc);
10529                 break;
10530         case 0x0103:    /*Query File EA Info*/
10531         case 1007:      /* SMB_FILE_EA_INFORMATION */
10532                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
10533                     &trunc);
10534                 break;
10535         case 0x0104:    /*Query File Name Info*/
10536         case 1009:      /* SMB_FILE_NAME_INFORMATION */
10537                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10538                     &trunc);
10539                 break;
10540         case 0x0107:    /*Query File All Info*/
10541         case 1018:      /* SMB_FILE_ALL_INFORMATION */
10542                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
10543                     &trunc);
10544                 break;
10545         case 0x0108:    /*Query File Alt File Info*/
10546         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
10547                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10548                     &trunc);
10549                 break;
10550         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
10551                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
10552         case 0x0109:    /*Query File Stream Info*/
10553                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
10554                     &trunc);
10555                 break;
10556         case 0x010b:    /*Query File Compression Info*/
10557         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
10558                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
10559                     &trunc);
10560                 break;
10561         case 0x0200:    /*Set File Unix Basic*/
10562                 /* XXX add this from the SNIA doc */
10563                 break;
10564         case 0x0201:    /*Set File Unix Link*/
10565                 /* XXX add this from the SNIA doc */
10566                 break;
10567         case 0x0202:    /*Set File Unix HardLink*/
10568                 /* XXX add this from the SNIA doc */
10569                 break;
10570         }
10571         
10572         return offset;
10573 }
10574
10575
10576 static const true_false_string tfs_quota_flags_deny_disk = {
10577         "DENY DISK SPACE for users exceeding quota limit",
10578         "Do NOT deny disk space for users exceeding quota limit"
10579 };
10580 static const true_false_string tfs_quota_flags_log_limit = {
10581         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10582         "Do NOT log event when a user exceeds their quota limit"
10583 };
10584 static const true_false_string tfs_quota_flags_log_warning = {
10585         "LOG EVENT when a user exceeds their WARNING LEVEL",
10586         "Do NOT log event when a user exceeds their warning level"
10587 };
10588 static const true_false_string tfs_quota_flags_enabled = {
10589         "Quotas are ENABLED of this fs",
10590         "Quotas are NOT enabled on this fs"
10591 };
10592 static void
10593 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10594 {
10595         guint8 mask;
10596         proto_item *item = NULL;
10597         proto_tree *tree = NULL;
10598
10599         mask = tvb_get_guint8(tvb, offset);
10600
10601         if(parent_tree){
10602                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10603                         "Quota Flags: 0x%02x %s", mask,
10604                         mask?"Enabled":"Disabled");
10605                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10606         }
10607
10608         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10609                 tvb, offset, 1, mask);
10610         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10611                 tvb, offset, 1, mask);
10612         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10613                 tvb, offset, 1, mask);
10614
10615         if(mask && (!(mask&0x01))){
10616                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10617                         tvb, offset, 1, 0x01);
10618         } else {
10619                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10620                         tvb, offset, 1, mask);
10621         }
10622
10623 }
10624
10625 static int
10626 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
10627 {
10628         /* first 24 bytes are unknown */
10629         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10630         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10631                     offset, 24, TRUE);
10632         COUNT_BYTES_TRANS_SUBR(24);
10633
10634         /* number of bytes for quota warning */
10635         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10636         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10637         COUNT_BYTES_TRANS_SUBR(8);
10638
10639         /* number of bytes for quota limit */
10640         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10641         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10642         COUNT_BYTES_TRANS_SUBR(8);
10643
10644         /* one byte of quota flags */
10645         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10646         dissect_quota_flags(tvb, tree, offset);
10647         COUNT_BYTES_TRANS_SUBR(1);
10648
10649         /* these 7 bytes are unknown */
10650         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10651         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10652                     offset, 7, TRUE);
10653         COUNT_BYTES_TRANS_SUBR(7);
10654
10655         return offset;
10656 }
10657
10658 static int
10659 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10660     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10661 {
10662         proto_item *item = NULL;
10663         proto_tree *tree = NULL;
10664         smb_info_t *si;
10665
10666         si = (smb_info_t *)pinfo->private_data;
10667
10668         if(parent_tree){
10669                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10670                                 "%s Data",
10671                                 val_to_str(subcmd, trans2_cmd_vals, 
10672                                                 "Unknown (0x%02x)"));
10673                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10674         }
10675
10676         switch(subcmd){
10677         case 0x00:      /*TRANS2_OPEN2*/
10678                 /* XXX dont know how to decode FEAList */
10679                 break;
10680         case 0x01:      /*TRANS2_FIND_FIRST2*/
10681                 /* XXX dont know how to decode FEAList */
10682                 break;
10683         case 0x02:      /*TRANS2_FIND_NEXT2*/
10684                 /* XXX dont know how to decode FEAList */
10685                 break;
10686         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10687                 /* no data field in this request */
10688                 break;
10689         case 0x04:      /* TRANS2_SET_QUOTA */
10690                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
10691                 break;
10692         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10693                 /* no data field in this request */
10694                 /*
10695                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10696                  * Extensions Version 3.0, Document Version 1.11,
10697                  * July 19, 1990" says there may be "Additional
10698                  * FileInfoLevel dependent information" here.
10699                  *
10700                  * Was that just a cut-and-pasteo?
10701                  * TRANS2_SET_PATH_INFORMATION *does* have that information
10702                  * here.
10703                  */
10704                 break;
10705         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10706                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10707                 break;
10708         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10709                 /* no data field in this request */
10710                 /*
10711                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10712                  * Extensions Version 3.0, Document Version 1.11,
10713                  * July 19, 1990" says there may be "Additional
10714                  * FileInfoLevel dependent information" here.
10715                  *
10716                  * Was that just a cut-and-pasteo?
10717                  * TRANS2_SET_FILE_INFORMATION *does* have that information
10718                  * here.
10719                  */
10720                 break;
10721         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10722                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10723                 break;
10724         case 0x09:      /*TRANS2_FSCTL*/
10725                 /*XXX dont know how to decode this yet */
10726
10727                 /*
10728                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10729                  * Extensions Version 3.0, Document Version 1.11,
10730                  * July 19, 1990" says this this contains a
10731                  * "File system specific data block".  (That means we
10732                  * may not be able to dissect it in any case.)
10733                  */
10734                 break;
10735         case 0x0a:      /*TRANS2_IOCTL2*/
10736                 /*XXX dont know how to decode this yet */
10737
10738                 /*
10739                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10740                  * Extensions Version 3.0, Document Version 1.11,
10741                  * July 19, 1990" says this this contains a
10742                  * "Device/function specific data block".  (That
10743                  * means we may not be able to dissect it in any case.)
10744                  */
10745                 break;
10746         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10747                 /*XXX dont know how to decode this yet */
10748
10749                 /*
10750                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10751                  * Extensions Version 3.0, Document Version 1.11,
10752                  * July 19, 1990" says this this contains "additional
10753                  * level dependent match data".
10754                  */
10755                 break;
10756         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
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 monitor information".
10764                  */
10765                 break;
10766         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10767                 /* XXX optional FEAList, unknown what FEAList looks like*/
10768                 break;
10769         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10770                 /*XXX dont know how to decode this yet */
10771                 break;
10772         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10773                 /* no data field in this request */
10774                 break;
10775         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10776                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10777                 break;
10778         }
10779
10780         /* ooops there were data we didnt know how to process */
10781         if(dc != 0){
10782                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10783                 offset += dc;
10784         }
10785
10786         return offset;
10787 }
10788
10789
10790 static void
10791 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10792     proto_tree *tree)
10793 {
10794         int i;
10795         int offset;
10796         guint length;
10797
10798         /*
10799          * Show the setup words.
10800          */
10801         if (s_tvb != NULL) {
10802                 length = tvb_reported_length(s_tvb);
10803                 for (i = 0, offset = 0; length >= 2;
10804                     i++, offset += 2, length -= 2) {
10805                         /*
10806                          * XXX - add a setup word filterable field?
10807                          */
10808                         proto_tree_add_text(tree, s_tvb, offset, 2,
10809                             "Setup Word %d: 0x%04x", i,
10810                             tvb_get_letohs(s_tvb, offset));
10811                 }
10812         }
10813
10814         /*
10815          * Show the parameters, if any.
10816          */
10817         if (p_tvb != NULL) {
10818                 length = tvb_reported_length(p_tvb);
10819                 if (length != 0) {
10820                         proto_tree_add_text(tree, p_tvb, 0, length,
10821                             "Parameters: %s",
10822                             tvb_bytes_to_str(p_tvb, 0, length));
10823                 }
10824         }
10825
10826         /*
10827          * Show the data, if any.
10828          */
10829         if (d_tvb != NULL) {
10830                 length = tvb_reported_length(d_tvb);
10831                 if (length != 0) {
10832                         proto_tree_add_text(tree, d_tvb, 0, length,
10833                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10834                 }
10835         }
10836 }
10837
10838 /* This routine handles the following 4 calls
10839    Transaction  0x25
10840    Transaction Secondary 0x26
10841    Transaction2 0x32
10842    Transaction2 Secondary 0x33
10843 */
10844 static int
10845 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
10846 {
10847         guint8 wc, sc=0;
10848         int so=offset;
10849         int sl=0;
10850         int spo=offset;
10851         int spc=0;
10852         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10853         int subcmd = -1;
10854         guint32 to;
10855         int an_len;
10856         const char *an = NULL;
10857         smb_info_t *si;
10858         smb_transact2_info_t *t2i;
10859         smb_transact_info_t *tri;
10860         guint16 bc;
10861         int padcnt;
10862         gboolean dissected_trans;
10863
10864         si = (smb_info_t *)pinfo->private_data;
10865
10866         WORD_COUNT;
10867
10868         if(wc==8){
10869                 /*secondary client request*/
10870
10871                 /* total param count, only a 16bit integer here*/
10872                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10873                 offset += 2;
10874         
10875                 /* total data count , only 16bit integer here*/
10876                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10877                 offset += 2;
10878
10879                 /* param count */
10880                 pc = tvb_get_letohs(tvb, offset);
10881                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10882                 offset += 2;
10883
10884                 /* param offset */
10885                 po = tvb_get_letohs(tvb, offset);
10886                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10887                 offset += 2;
10888
10889                 /* param disp */
10890                 pd = tvb_get_letohs(tvb, offset);
10891                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10892                 offset += 2;
10893         
10894                 /* data count */
10895                 dc = tvb_get_letohs(tvb, offset);
10896                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10897                 offset += 2;
10898
10899                 /* data offset */
10900                 od = tvb_get_letohs(tvb, offset);
10901                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10902                 offset += 2;
10903         
10904                 /* data disp */
10905                 dd = tvb_get_letohs(tvb, offset);
10906                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10907                 offset += 2;
10908
10909                 if(si->cmd==SMB_COM_TRANSACTION2){
10910                         guint16 fid;
10911
10912                         /* fid */
10913                         fid = tvb_get_letohs(tvb, offset);
10914                         add_fid(tvb, pinfo, tree, offset, 2, fid);
10915
10916                         offset += 2;
10917                 }
10918
10919                 /* There are no setup words. */
10920                 so = offset;
10921                 sc = 0;
10922                 sl = 0;
10923         } else {
10924                 /* it is not a secondary request */
10925
10926                 /* total param count , only a 16 bit integer here*/
10927                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10928                 offset += 2;
10929
10930                 /* total data count , only 16bit integer here*/
10931                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10932                 offset += 2;
10933
10934                 /* max param count , only 16bit integer here*/
10935                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10936                 offset += 2;
10937
10938                 /* max data count, only 16bit integer here*/
10939                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10940                 offset += 2;
10941
10942                 /* max setup count, only 16bit integer here*/
10943                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10944                 offset += 1;
10945
10946                 /* reserved byte */
10947                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10948                 offset += 1;
10949
10950                 /* transaction flags */
10951                 tf = dissect_transaction_flags(tvb, tree, offset);
10952                 offset += 2;
10953
10954                 /* timeout */
10955                 to = tvb_get_letohl(tvb, offset);
10956                 if (to == 0)
10957                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
10958                 else if (to == 0xffffffff)
10959                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
10960                 else
10961                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
10962                 offset += 4;
10963
10964                 /* 2 reserved bytes */
10965                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10966                 offset += 2;
10967
10968                 /* param count */
10969                 pc = tvb_get_letohs(tvb, offset);
10970                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10971                 offset += 2;
10972         
10973                 /* param offset */
10974                 po = tvb_get_letohs(tvb, offset);
10975                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10976                 offset += 2;
10977
10978                 /* param displacement is zero here */
10979                 pd = 0;
10980
10981                 /* data count */
10982                 dc = tvb_get_letohs(tvb, offset);
10983                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10984                 offset += 2;
10985
10986                 /* data offset */
10987                 od = tvb_get_letohs(tvb, offset);
10988                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10989                 offset += 2;
10990
10991                 /* data displacement is zero here */
10992                 dd = 0;
10993
10994                 /* setup count */
10995                 sc = tvb_get_guint8(tvb, offset);
10996                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10997                 offset += 1;
10998
10999                 /* reserved byte */
11000                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11001                 offset += 1;
11002                 
11003                 /* this is where the setup bytes, if any start */       
11004                 so = offset;
11005                 sl = sc*2;
11006
11007                 /* if there were any setup bytes, decode them */
11008                 if(sc){
11009                         switch(si->cmd){
11010
11011                         case SMB_COM_TRANSACTION2:
11012                                 /* TRANSACTION2 only has one setup word and
11013                                    that is the subcommand code.
11014
11015                                    XXX - except for TRANS2_FSCTL
11016                                    and TRANS2_IOCTL. */
11017                                 subcmd = tvb_get_letohs(tvb, offset);
11018                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11019                                     tvb, offset, 2, subcmd);
11020                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11021                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11022                                             val_to_str(subcmd, trans2_cmd_vals, 
11023                                                 "Unknown (0x%02x)"));
11024                                 }
11025                                 if (!si->unidir) {
11026                                         if(!pinfo->fd->flags.visited){
11027                                                 /* 
11028                                                  * Allocate a new
11029                                                  * smb_transact2_info_t
11030                                                  * structure.
11031                                                  */
11032                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11033                                                 t2i->subcmd = subcmd;
11034                                                 t2i->info_level = -1;
11035                                                 t2i->resume_keys = FALSE;
11036                                                 si->sip->extra_info = t2i;
11037                                         }
11038                                 }
11039
11040                                 /*
11041                                  * XXX - process TRANS2_FSCTL and
11042                                  * TRANS2_IOCTL setup words here.
11043                                  */
11044                                 break;
11045
11046                         case SMB_COM_TRANSACTION:
11047                                 /* TRANSACTION setup words processed below */
11048                                 break;
11049                         }
11050
11051                         offset += sl;
11052                 }
11053         }
11054
11055         BYTE_COUNT;
11056         
11057         if(wc!=8){
11058                 /* primary request */
11059                 /* name is NULL if transaction2 */
11060                 if(si->cmd == SMB_COM_TRANSACTION){
11061                         /* Transaction Name */
11062                         an = get_unicode_or_ascii_string(tvb, &offset,
11063                                 pinfo, &an_len, FALSE, FALSE, &bc);
11064                         if (an == NULL)
11065                                 goto endofcommand;
11066                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11067                                 offset, an_len, an);
11068                         COUNT_BYTES(an_len);
11069                 }
11070         }
11071
11072         /*
11073          * The pipe or mailslot arguments for Transaction start with
11074          * the first setup word (or where the first setup word would
11075          * be if there were any setup words), and run to the current
11076          * offset (which could mean that there aren't any).
11077          */
11078         spo = so;
11079         spc = offset - spo;
11080
11081         /* parameters */
11082         if(po>offset){
11083                 /* We have some initial padding bytes.
11084                 */
11085                 padcnt = po-offset;
11086                 if (padcnt > bc)
11087                         padcnt = bc;
11088                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11089                 COUNT_BYTES(padcnt);
11090         }
11091         if(pc){
11092                 CHECK_BYTE_COUNT(pc);
11093                 switch(si->cmd) {
11094
11095                 case SMB_COM_TRANSACTION2:
11096                         /* TRANSACTION2 parameters*/
11097                         offset = dissect_transaction2_request_parameters(tvb,
11098                             pinfo, tree, offset, subcmd, pc);
11099                         bc -= pc;
11100                         break;
11101
11102                 case SMB_COM_TRANSACTION:
11103                         /* TRANSACTION parameters processed below */
11104                         COUNT_BYTES(pc);
11105                         break;
11106                 }
11107         }
11108
11109         /* data */
11110         if(od>offset){
11111                 /* We have some initial padding bytes.
11112                 */
11113                 padcnt = od-offset;
11114                 if (padcnt > bc)
11115                         padcnt = bc;
11116                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11117                 COUNT_BYTES(padcnt);
11118         }
11119         if(dc){
11120                 CHECK_BYTE_COUNT(dc);
11121                 switch(si->cmd){
11122
11123                 case SMB_COM_TRANSACTION2:
11124                         /* TRANSACTION2 data*/
11125                         offset = dissect_transaction2_request_data(tvb, pinfo,
11126                             tree, offset, subcmd, dc);
11127                         bc -= dc;
11128                         break;
11129
11130                 case SMB_COM_TRANSACTION:
11131                         /* TRANSACTION data processed below */
11132                         COUNT_BYTES(dc);
11133                         break;
11134                 }
11135         }
11136
11137         /*TRANSACTION request parameters */
11138         if(si->cmd==SMB_COM_TRANSACTION){
11139                 /*XXX replace this block with a function and use that one 
11140                      for both requests/responses*/
11141                 if(dd==0){
11142                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11143                         tvbuff_t *sp_tvb, *pd_tvb;
11144
11145                         if(pc>0){
11146                                 if(pc>tvb_length_remaining(tvb, po)){
11147                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11148                                 } else {
11149                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11150                                 }
11151                         } else {
11152                                 p_tvb = NULL;
11153                         }
11154                         if(dc>0){
11155                                 if(dc>tvb_length_remaining(tvb, od)){
11156                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11157                                 } else {
11158                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11159                                 }
11160                         } else {
11161                                 d_tvb = NULL;
11162                         }
11163                         if(sl){
11164                                 if(sl>tvb_length_remaining(tvb, so)){
11165                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11166                                 } else {
11167                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11168                                 }
11169                         } else {
11170                                 s_tvb = NULL;
11171                         }
11172
11173                         if (!si->unidir) {
11174                                 if(!pinfo->fd->flags.visited){
11175                                         /* 
11176                                          * Allocate a new smb_transact_info_t
11177                                          * structure.
11178                                          */
11179                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11180                                         tri->subcmd = -1;
11181                                         tri->trans_subcmd = -1;
11182                                         tri->function = -1;
11183                                         tri->fid = -1;
11184                                         tri->lanman_cmd = 0;
11185                                         tri->param_descrip = NULL;
11186                                         tri->data_descrip = NULL;
11187                                         tri->aux_data_descrip = NULL;
11188                                         tri->info_level = -1;
11189                                         si->sip->extra_info = tri;
11190                                 } else {
11191                                         /*
11192                                          * We already filled the structure
11193                                          * in; don't bother doing so again.
11194                                          */
11195                                         tri = NULL;
11196                                 }
11197                         } else {
11198                                 /*
11199                                  * This is a unidirectional message, for
11200                                  * which there will be no reply; don't
11201                                  * bother allocating an "smb_transact_info_t"
11202                                  * structure for it.
11203                                  */
11204                                 tri = NULL;
11205                         }
11206                         dissected_trans = FALSE;
11207                         if(strncmp("\\PIPE\\", an, 6) == 0){
11208                                 if (tri != NULL)
11209                                         tri->subcmd=TRANSACTION_PIPE;
11210
11211                                 /*
11212                                  * A tvbuff containing the setup words and
11213                                  * the pipe path.
11214                                  */
11215                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11216
11217                                 /*
11218                                  * A tvbuff containing the parameters and the
11219                                  * data.
11220                                  */
11221                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11222
11223                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11224                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11225                                     top_tree);
11226                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11227                                 if (tri != NULL)
11228                                         tri->subcmd=TRANSACTION_MAILSLOT;
11229
11230                                 /*
11231                                  * A tvbuff containing the setup words and
11232                                  * the mailslot path.
11233                                  */
11234                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11235                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11236                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11237                         }
11238                         if (!dissected_trans)
11239                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11240                 } else {
11241                         if(check_col(pinfo->cinfo, COL_INFO)){
11242                                 col_append_str(pinfo->cinfo, COL_INFO,
11243                                         "[transact continuation]");
11244                         }
11245                 }
11246         }
11247
11248         END_OF_SMB
11249
11250         return offset;
11251 }
11252
11253  
11254
11255 static int
11256 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11257     int offset, guint16 *bcp, gboolean *trunc)
11258 {
11259         int fn_len;
11260         const char *fn;
11261         int old_offset = offset;
11262         proto_item *item = NULL;
11263         proto_tree *tree = NULL;
11264         smb_info_t *si;
11265         smb_transact2_info_t *t2i;
11266         gboolean resume_keys = FALSE;
11267
11268         si = (smb_info_t *)pinfo->private_data;
11269         if (si->sip != NULL) {
11270                 t2i = si->sip->extra_info;
11271                 if (t2i != NULL)
11272                         resume_keys = t2i->resume_keys;
11273         }
11274
11275         if(parent_tree){
11276                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11277                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11278                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11279         }
11280
11281         if (resume_keys) {
11282                 /* resume key */
11283                 CHECK_BYTE_COUNT_SUBR(4);
11284                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11285                 COUNT_BYTES_SUBR(4);
11286         }
11287
11288         /* create time */
11289         CHECK_BYTE_COUNT_SUBR(4);
11290         offset = dissect_smb_datetime(tvb, tree, offset,
11291                 hf_smb_create_time,
11292                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11293         *bcp -= 4;
11294
11295         /* access time */
11296         CHECK_BYTE_COUNT_SUBR(4);
11297         offset = dissect_smb_datetime(tvb, tree, offset,
11298                 hf_smb_access_time,
11299                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11300         *bcp -= 4;
11301
11302         /* last write time */
11303         CHECK_BYTE_COUNT_SUBR(4);
11304         offset = dissect_smb_datetime(tvb, tree, offset,
11305                 hf_smb_last_write_time,
11306                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11307         *bcp -= 4;
11308
11309         /* data size */
11310         CHECK_BYTE_COUNT_SUBR(4);
11311         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11312         COUNT_BYTES_SUBR(4);
11313
11314         /* allocation size */
11315         CHECK_BYTE_COUNT_SUBR(4);
11316         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11317         COUNT_BYTES_SUBR(4);
11318
11319         /* File Attributes */
11320         CHECK_BYTE_COUNT_SUBR(2);
11321         offset = dissect_file_attributes(tvb, tree, offset);
11322         *bcp -= 2;
11323
11324         /* file name len */
11325         CHECK_BYTE_COUNT_SUBR(1);
11326         fn_len = tvb_get_guint8(tvb, offset);
11327         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11328         COUNT_BYTES_SUBR(1);
11329         if (si->unicode)
11330                 fn_len += 2;    /* include terminating '\0' */
11331         else
11332                 fn_len++;       /* include terminating '\0' */
11333
11334         /* file name */
11335         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11336         CHECK_STRING_SUBR(fn);
11337         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11338                 fn);
11339         COUNT_BYTES_SUBR(fn_len);
11340
11341         if (check_col(pinfo->cinfo, COL_INFO)) {
11342                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11343                 fn);
11344         }
11345  
11346         proto_item_append_text(item, " File: %s", fn);
11347         proto_item_set_len(item, offset-old_offset);
11348
11349         *trunc = FALSE;
11350         return offset;
11351 }
11352
11353 static int
11354 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11355     int offset, guint16 *bcp, gboolean *trunc)
11356 {
11357         int fn_len;
11358         const char *fn;
11359         int old_offset = offset;
11360         proto_item *item = NULL;
11361         proto_tree *tree = NULL;
11362         smb_info_t *si;
11363         smb_transact2_info_t *t2i;
11364         gboolean resume_keys = FALSE;
11365
11366         si = (smb_info_t *)pinfo->private_data;
11367         if (si->sip != NULL) {
11368                 t2i = si->sip->extra_info;
11369                 if (t2i != NULL)
11370                         resume_keys = t2i->resume_keys;
11371         }
11372
11373         if(parent_tree){
11374                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11375                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11376                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11377         }
11378
11379         if (resume_keys) {
11380                 /* resume key */
11381                 CHECK_BYTE_COUNT_SUBR(4);
11382                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11383                 COUNT_BYTES_SUBR(4);
11384         }
11385  
11386         /* create time */
11387         CHECK_BYTE_COUNT_SUBR(4);
11388         offset = dissect_smb_datetime(tvb, tree, offset,
11389                 hf_smb_create_time,
11390                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11391         *bcp -= 4;
11392
11393         /* access time */
11394         CHECK_BYTE_COUNT_SUBR(4);
11395         offset = dissect_smb_datetime(tvb, tree, offset,
11396                 hf_smb_access_time,
11397                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11398         *bcp -= 4;
11399
11400         /* last write time */
11401         CHECK_BYTE_COUNT_SUBR(4);
11402         offset = dissect_smb_datetime(tvb, tree, offset,
11403                 hf_smb_last_write_time,
11404                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11405         *bcp -= 4;
11406
11407         /* data size */
11408         CHECK_BYTE_COUNT_SUBR(4);
11409         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11410         COUNT_BYTES_SUBR(4);
11411
11412         /* allocation size */
11413         CHECK_BYTE_COUNT_SUBR(4);
11414         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11415         COUNT_BYTES_SUBR(4);
11416
11417         /* File Attributes */
11418         CHECK_BYTE_COUNT_SUBR(2);
11419         offset = dissect_file_attributes(tvb, tree, offset);
11420         *bcp -= 2;
11421
11422         /* ea size */
11423         CHECK_BYTE_COUNT_SUBR(4);
11424         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11425         COUNT_BYTES_SUBR(4);
11426
11427         /* file name len */
11428         CHECK_BYTE_COUNT_SUBR(1);
11429         fn_len = tvb_get_guint8(tvb, offset);
11430         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11431         COUNT_BYTES_SUBR(1);
11432
11433         /* file name */
11434         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11435         CHECK_STRING_SUBR(fn);
11436         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11437                 fn);
11438         COUNT_BYTES_SUBR(fn_len);
11439         if (si->unicode)
11440                 fn_len += 2;    /* include terminating '\0' */
11441         else
11442                 fn_len++;       /* include terminating '\0' */
11443
11444         if (check_col(pinfo->cinfo, COL_INFO)) {
11445                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11446                 fn);
11447         }
11448
11449         proto_item_append_text(item, " File: %s", fn);
11450         proto_item_set_len(item, offset-old_offset);
11451
11452         *trunc = FALSE;
11453         return offset;
11454 }
11455
11456 static int
11457 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11458     int offset, guint16 *bcp, gboolean *trunc)
11459 {
11460         int fn_len;
11461         const char *fn;
11462         int old_offset = offset;
11463         proto_item *item = NULL;
11464         proto_tree *tree = NULL;
11465         smb_info_t *si;
11466         guint32 neo;
11467         int padcnt;
11468
11469         si = (smb_info_t *)pinfo->private_data;
11470
11471         if(parent_tree){
11472                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11473                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11474                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11475         }
11476
11477         /*
11478          * We assume that the presence of a next entry offset implies the
11479          * absence of a resume key, as appears to be the case for 4.3.4.6.
11480          */
11481
11482         /* next entry offset */
11483         CHECK_BYTE_COUNT_SUBR(4);
11484         neo = tvb_get_letohl(tvb, offset);
11485         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11486         COUNT_BYTES_SUBR(4);
11487         
11488         /* file index */
11489         CHECK_BYTE_COUNT_SUBR(4);
11490         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11491         COUNT_BYTES_SUBR(4);
11492
11493         /* create time */
11494         CHECK_BYTE_COUNT_SUBR(8);
11495         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11496         *bcp -= 8;
11497         
11498         /* access time */
11499         CHECK_BYTE_COUNT_SUBR(8);
11500         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11501         *bcp -= 8;
11502         
11503         /* last write time */
11504         CHECK_BYTE_COUNT_SUBR(8);
11505         offset = dissect_smb_64bit_time(tvb, tree, offset,
11506                 hf_smb_last_write_time);
11507         *bcp -= 8;
11508         
11509         /* last change time */
11510         CHECK_BYTE_COUNT_SUBR(8);
11511         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11512         *bcp -= 8;
11513         
11514         /* end of file */
11515         CHECK_BYTE_COUNT_SUBR(8);
11516         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11517         COUNT_BYTES_SUBR(8);
11518
11519         /* allocation size */
11520         CHECK_BYTE_COUNT_SUBR(8);
11521         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11522         COUNT_BYTES_SUBR(8);
11523
11524         /* Extended File Attributes */
11525         CHECK_BYTE_COUNT_SUBR(4);
11526         offset = dissect_file_ext_attr(tvb, tree, offset);
11527         *bcp -= 4;
11528
11529         /* file name len */
11530         CHECK_BYTE_COUNT_SUBR(4);
11531         fn_len = tvb_get_letohl(tvb, offset);
11532         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11533         COUNT_BYTES_SUBR(4);
11534
11535         /* file name */
11536         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11537         CHECK_STRING_SUBR(fn);
11538         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11539                 fn);
11540         COUNT_BYTES_SUBR(fn_len);
11541
11542         if (check_col(pinfo->cinfo, COL_INFO)) {
11543                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11544                 fn);
11545         }
11546
11547         /* skip to next structure */
11548         if(neo){
11549                 padcnt = (old_offset + neo) - offset;
11550                 if (padcnt < 0) {
11551                         /*
11552                          * XXX - this is bogus; flag it?
11553                          */
11554                         padcnt = 0;
11555                 }
11556                 if (padcnt != 0) {
11557                         CHECK_BYTE_COUNT_SUBR(padcnt);
11558                         COUNT_BYTES_SUBR(padcnt);
11559                 }
11560         }
11561
11562         proto_item_append_text(item, " File: %s", fn);
11563         proto_item_set_len(item, offset-old_offset);
11564
11565         *trunc = FALSE;
11566         return offset;
11567 }
11568
11569 static int
11570 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11571     int offset, guint16 *bcp, gboolean *trunc)
11572 {
11573         int fn_len;
11574         const char *fn;
11575         int old_offset = offset;
11576         proto_item *item = NULL;
11577         proto_tree *tree = NULL;
11578         smb_info_t *si;
11579         guint32 neo;
11580         int padcnt;
11581
11582         si = (smb_info_t *)pinfo->private_data;
11583
11584         if(parent_tree){
11585                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11586                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11587                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11588         }
11589
11590         /*
11591          * We assume that the presence of a next entry offset implies the
11592          * absence of a resume key, as appears to be the case for 4.3.4.6.
11593          */
11594
11595         /* next entry offset */
11596         CHECK_BYTE_COUNT_SUBR(4);
11597         neo = tvb_get_letohl(tvb, offset);
11598         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11599         COUNT_BYTES_SUBR(4);
11600         
11601         /* file index */
11602         CHECK_BYTE_COUNT_SUBR(4);
11603         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11604         COUNT_BYTES_SUBR(4);
11605
11606         /* create time */
11607         CHECK_BYTE_COUNT_SUBR(8);
11608         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11609         *bcp -= 8;
11610         
11611         /* access time */
11612         CHECK_BYTE_COUNT_SUBR(8);
11613         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11614         *bcp -= 8;
11615         
11616         /* last write time */
11617         CHECK_BYTE_COUNT_SUBR(8);
11618         offset = dissect_smb_64bit_time(tvb, tree, offset,
11619                 hf_smb_last_write_time);
11620         *bcp -= 8;
11621         
11622         /* last change time */
11623         CHECK_BYTE_COUNT_SUBR(8);
11624         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11625         *bcp -= 8;
11626         
11627         /* end of file */
11628         CHECK_BYTE_COUNT_SUBR(8);
11629         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11630         COUNT_BYTES_SUBR(8);
11631
11632         /* allocation size */
11633         CHECK_BYTE_COUNT_SUBR(8);
11634         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11635         COUNT_BYTES_SUBR(8);
11636
11637         /* Extended File Attributes */
11638         CHECK_BYTE_COUNT_SUBR(4);
11639         offset = dissect_file_ext_attr(tvb, tree, offset);
11640         *bcp -= 4;
11641
11642         /* file name len */
11643         CHECK_BYTE_COUNT_SUBR(4);
11644         fn_len = tvb_get_letohl(tvb, offset);
11645         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11646         COUNT_BYTES_SUBR(4);
11647
11648         /* ea size */
11649         CHECK_BYTE_COUNT_SUBR(4);
11650         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11651         COUNT_BYTES_SUBR(4);
11652
11653         /* file name */
11654         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11655         CHECK_STRING_SUBR(fn);
11656         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11657                 fn);
11658         COUNT_BYTES_SUBR(fn_len);
11659
11660         if (check_col(pinfo->cinfo, COL_INFO)) {
11661                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11662                 fn);
11663         }
11664
11665         /* skip to next structure */
11666         if(neo){
11667                 padcnt = (old_offset + neo) - offset;
11668                 if (padcnt < 0) {
11669                         /*
11670                          * XXX - this is bogus; flag it?
11671                          */
11672                         padcnt = 0;
11673                 }
11674                 if (padcnt != 0) {
11675                         CHECK_BYTE_COUNT_SUBR(padcnt);
11676                         COUNT_BYTES_SUBR(padcnt);
11677                 }
11678         }
11679
11680         proto_item_append_text(item, " File: %s", fn);
11681         proto_item_set_len(item, offset-old_offset);
11682
11683         *trunc = FALSE;
11684         return offset;
11685 }
11686
11687 static int
11688 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11689     int offset, guint16 *bcp, gboolean *trunc)
11690 {
11691         int fn_len, sfn_len;
11692         const char *fn, *sfn;
11693         int old_offset = offset;
11694         proto_item *item = NULL;
11695         proto_tree *tree = NULL;
11696         smb_info_t *si;
11697         guint32 neo;
11698         int padcnt;
11699
11700         si = (smb_info_t *)pinfo->private_data;
11701
11702         if(parent_tree){
11703                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11704                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11705                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11706         }
11707
11708         /*
11709          * XXX - I have not seen any of these that contain a resume
11710          * key, even though some of the requests had the "return resume
11711          * key" flag set.
11712          */
11713
11714         /* next entry offset */
11715         CHECK_BYTE_COUNT_SUBR(4);
11716         neo = tvb_get_letohl(tvb, offset);
11717         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11718         COUNT_BYTES_SUBR(4);
11719         
11720         /* file index */
11721         CHECK_BYTE_COUNT_SUBR(4);
11722         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11723         COUNT_BYTES_SUBR(4);
11724
11725         /* create time */
11726         CHECK_BYTE_COUNT_SUBR(8);
11727         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11728         *bcp -= 8;
11729         
11730         /* access time */
11731         CHECK_BYTE_COUNT_SUBR(8);
11732         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11733         *bcp -= 8;
11734         
11735         /* last write time */
11736         CHECK_BYTE_COUNT_SUBR(8);
11737         offset = dissect_smb_64bit_time(tvb, tree, offset,
11738                 hf_smb_last_write_time);
11739         *bcp -= 8;
11740         
11741         /* last change time */
11742         CHECK_BYTE_COUNT_SUBR(8);
11743         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11744         *bcp -= 8;
11745         
11746         /* end of file */
11747         CHECK_BYTE_COUNT_SUBR(8);
11748         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11749         COUNT_BYTES_SUBR(8);
11750
11751         /* allocation size */
11752         CHECK_BYTE_COUNT_SUBR(8);
11753         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11754         COUNT_BYTES_SUBR(8);
11755
11756         /* Extended File Attributes */
11757         CHECK_BYTE_COUNT_SUBR(4);
11758         offset = dissect_file_ext_attr(tvb, tree, offset);
11759         *bcp -= 4;
11760
11761         /* file name len */
11762         CHECK_BYTE_COUNT_SUBR(4);
11763         fn_len = tvb_get_letohl(tvb, offset);
11764         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11765         COUNT_BYTES_SUBR(4);
11766
11767         /* ea size */
11768         CHECK_BYTE_COUNT_SUBR(4);
11769         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11770         COUNT_BYTES_SUBR(4);
11771
11772         /* short file name len */
11773         CHECK_BYTE_COUNT_SUBR(1);
11774         sfn_len = tvb_get_guint8(tvb, offset);
11775         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11776         COUNT_BYTES_SUBR(1);
11777
11778         /* reserved byte */
11779         CHECK_BYTE_COUNT_SUBR(1);
11780         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11781         COUNT_BYTES_SUBR(1);
11782  
11783         /* short file name */
11784         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
11785         CHECK_STRING_SUBR(sfn);
11786         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11787                 sfn);
11788         COUNT_BYTES_SUBR(24);
11789
11790         /* file name */
11791         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11792         CHECK_STRING_SUBR(fn);
11793         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11794                 fn);
11795         COUNT_BYTES_SUBR(fn_len);
11796
11797         if (check_col(pinfo->cinfo, COL_INFO)) {
11798                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11799                 fn);
11800         }
11801
11802         /* skip to next structure */
11803         if(neo){
11804                 padcnt = (old_offset + neo) - offset;
11805                 if (padcnt < 0) {
11806                         /*
11807                          * XXX - this is bogus; flag it?
11808                          */
11809                         padcnt = 0;
11810                 }
11811                 if (padcnt != 0) {
11812                         CHECK_BYTE_COUNT_SUBR(padcnt);
11813                         COUNT_BYTES_SUBR(padcnt);
11814                 }
11815         }
11816
11817         proto_item_append_text(item, " File: %s", fn);
11818         proto_item_set_len(item, offset-old_offset);
11819
11820         *trunc = FALSE;
11821         return offset;
11822 }
11823
11824 static int
11825 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11826     int offset, guint16 *bcp, gboolean *trunc)
11827 {
11828         int fn_len;
11829         const char *fn;
11830         int old_offset = offset;
11831         proto_item *item = NULL;
11832         proto_tree *tree = NULL;
11833         smb_info_t *si;
11834         guint32 neo;
11835         int padcnt;
11836
11837         si = (smb_info_t *)pinfo->private_data;
11838
11839         if(parent_tree){
11840                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11841                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11842                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11843         }
11844
11845         /*
11846          * We assume that the presence of a next entry offset implies the
11847          * absence of a resume key, as appears to be the case for 4.3.4.6.
11848          */
11849
11850         /* next entry offset */
11851         CHECK_BYTE_COUNT_SUBR(4);
11852         neo = tvb_get_letohl(tvb, offset);
11853         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11854         COUNT_BYTES_SUBR(4);
11855         
11856         /* file index */
11857         CHECK_BYTE_COUNT_SUBR(4);
11858         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11859         COUNT_BYTES_SUBR(4);
11860
11861         /* file name len */
11862         CHECK_BYTE_COUNT_SUBR(4);
11863         fn_len = tvb_get_letohl(tvb, offset);
11864         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11865         COUNT_BYTES_SUBR(4);
11866
11867         /* file name */
11868         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11869         CHECK_STRING_SUBR(fn);
11870         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11871                 fn);
11872         COUNT_BYTES_SUBR(fn_len);
11873
11874         if (check_col(pinfo->cinfo, COL_INFO)) {
11875                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11876                 fn);
11877         }
11878
11879         /* skip to next structure */
11880         if(neo){
11881                 padcnt = (old_offset + neo) - offset;
11882                 if (padcnt < 0) {
11883                         /*
11884                          * XXX - this is bogus; flag it?
11885                          */
11886                         padcnt = 0;
11887                 }
11888                 if (padcnt != 0) {
11889                         CHECK_BYTE_COUNT_SUBR(padcnt);
11890                         COUNT_BYTES_SUBR(padcnt);
11891                 }
11892         }
11893
11894         proto_item_append_text(item, " File: %s", fn);
11895         proto_item_set_len(item, offset-old_offset);
11896
11897         *trunc = FALSE;
11898         return offset;
11899 }
11900  
11901 static int
11902 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11903     int offset, guint16 *bcp, gboolean *trunc)
11904 {
11905 /*XXX im lazy. i havnt implemented this */
11906         offset += *bcp;
11907         *bcp = 0;
11908         *trunc = FALSE;
11909         return offset;
11910 }
11911
11912 /*dissect the data block for TRANS2_FIND_FIRST2*/
11913 static int
11914 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
11915     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
11916 {
11917         smb_info_t *si;
11918
11919         if(!*bcp){
11920                 return offset;
11921         }
11922         
11923         si = (smb_info_t *)pinfo->private_data;
11924         switch(si->info_level){
11925         case 1:         /*Info Standard*/
11926                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
11927                     trunc);
11928                 break;
11929         case 2:         /*Info Query EA Size*/
11930                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11931                     trunc);
11932                 break;
11933         case 3:         /*Info Query EAs From List same as 
11934                                 InfoQueryEASize*/
11935                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11936                     trunc);
11937                 break;
11938         case 0x0101:    /*Find File Directory Info*/
11939                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
11940                     trunc);
11941                 break;
11942         case 0x0102:    /*Find File Full Directory Info*/
11943                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
11944                     trunc);
11945                 break;
11946         case 0x0103:    /*Find File Names Info*/
11947                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
11948                     trunc);
11949                 break;
11950         case 0x0104:    /*Find File Both Directory Info*/
11951                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
11952                     trunc);
11953                 break;
11954         case 0x0202:    /*Find File UNIX*/
11955                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
11956                     trunc);
11957                 break;
11958         default:        /* unknown info level */
11959                 *trunc = FALSE;
11960                 break;
11961         }
11962         return offset;
11963 }
11964
11965
11966 static int
11967 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11968 {
11969         guint32 mask;
11970         proto_item *item = NULL;
11971         proto_tree *tree = NULL;
11972
11973         mask = tvb_get_letohl(tvb, offset);
11974
11975         if(parent_tree){
11976                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11977                         "FS Attributes: 0x%08x", mask);
11978                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
11979         }
11980
11981         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
11982                 tvb, offset, 4, mask);
11983         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
11984                 tvb, offset, 4, mask);
11985         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
11986                 tvb, offset, 4, mask);
11987         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
11988                 tvb, offset, 4, mask);
11989         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
11990                 tvb, offset, 4, mask);
11991         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
11992                 tvb, offset, 4, mask);
11993         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
11994                 tvb, offset, 4, mask);
11995
11996         offset += 4;
11997         return offset;
11998 }
11999  
12000
12001 static int
12002 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12003 {
12004         guint32 mask;
12005         proto_item *item = NULL;
12006         proto_tree *tree = NULL;
12007
12008         mask = tvb_get_letohl(tvb, offset);
12009
12010         if(parent_tree){
12011                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12012                         "Device Characteristics: 0x%08x", mask);
12013                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12014         }
12015
12016         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12017                 tvb, offset, 4, mask);
12018         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12019                 tvb, offset, 4, mask);
12020         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12021                 tvb, offset, 4, mask);
12022         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12023                 tvb, offset, 4, mask);
12024         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12025                 tvb, offset, 4, mask);
12026         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12027                 tvb, offset, 4, mask);
12028         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12029                 tvb, offset, 4, mask);
12030
12031         offset += 4;
12032         return offset;
12033 }
12034
12035 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12036 static int
12037 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12038     int offset, guint16 *bcp)
12039 {
12040         smb_info_t *si;
12041         int fn_len, vll, fnl;
12042         const char *fn;
12043
12044         if(!*bcp){
12045                 return offset;
12046         }
12047         
12048         si = (smb_info_t *)pinfo->private_data;
12049         switch(si->info_level){
12050         case 1:         /* SMB_INFO_ALLOCATION */
12051                 /* filesystem id */
12052                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12053                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12054                 COUNT_BYTES_TRANS_SUBR(4);
12055
12056                 /* sectors per unit */
12057                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12058                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12059                 COUNT_BYTES_TRANS_SUBR(4);
12060
12061                 /* units */
12062                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12063                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12064                 COUNT_BYTES_TRANS_SUBR(4);
12065
12066                 /* avail units */
12067                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12068                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12069                 COUNT_BYTES_TRANS_SUBR(4);
12070
12071                 /* bytes per sector, only 16bit integer here */
12072                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12073                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12074                 COUNT_BYTES_TRANS_SUBR(2);
12075
12076                 break;
12077         case 2:         /* SMB_INFO_VOLUME */
12078                 /* volume serial number */
12079                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12080                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12081                 COUNT_BYTES_TRANS_SUBR(4);
12082
12083                 /* volume label length, only one byte here */
12084                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12085                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12086                 COUNT_BYTES_TRANS_SUBR(1);
12087
12088                 /* label */
12089                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
12090                 CHECK_STRING_TRANS_SUBR(fn);
12091                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12092                         fn);
12093                 COUNT_BYTES_TRANS_SUBR(fn_len);
12094
12095                 break;
12096         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12097         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12098                 /* volume label length */
12099                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12100                 vll = tvb_get_letohl(tvb, offset);
12101                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12102                 COUNT_BYTES_TRANS_SUBR(4);
12103
12104                 /* label */
12105                 fn_len = vll;
12106                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12107                 CHECK_STRING_TRANS_SUBR(fn);
12108                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12109                         fn);
12110                 COUNT_BYTES_TRANS_SUBR(fn_len);
12111
12112                 break;
12113         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12114         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12115                 /* create time */
12116                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12117                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12118                         hf_smb_create_time);
12119                 *bcp -= 8;
12120         
12121                 /* volume serial number */
12122                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12123                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12124                 COUNT_BYTES_TRANS_SUBR(4);
12125
12126                 /* volume label length */
12127                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12128                 vll = tvb_get_letohl(tvb, offset);
12129                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12130                 COUNT_BYTES_TRANS_SUBR(4);
12131
12132                 /* 2 reserved bytes */
12133                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12134                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12135                 COUNT_BYTES_TRANS_SUBR(2);
12136
12137                 /* label */
12138                 fn_len = vll;
12139                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12140                 CHECK_STRING_TRANS_SUBR(fn);
12141                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12142                         fn);
12143                 COUNT_BYTES_TRANS_SUBR(fn_len);
12144
12145                 break;
12146         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12147         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12148                 /* allocation size */
12149                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12150                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12151                 COUNT_BYTES_TRANS_SUBR(8);
12152
12153                 /* free allocation units */
12154                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12155                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12156                 COUNT_BYTES_TRANS_SUBR(8);
12157
12158                 /* sectors per unit */
12159                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12160                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12161                 COUNT_BYTES_TRANS_SUBR(4);
12162
12163                 /* bytes per sector */
12164                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12165                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12166                 COUNT_BYTES_TRANS_SUBR(4);
12167
12168                 break;
12169         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12170         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12171                 /* device type */
12172                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12173                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12174                 COUNT_BYTES_TRANS_SUBR(4);
12175  
12176                 /* device characteristics */
12177                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12178                 offset = dissect_device_characteristics(tvb, tree, offset);
12179                 *bcp -= 4;
12180         
12181                 break;
12182         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12183         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12184                 /* FS attributes */
12185                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12186                 offset = dissect_fs_attributes(tvb, tree, offset);
12187                 *bcp -= 4;
12188         
12189                 /* max name len */
12190                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12191                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12192                 COUNT_BYTES_TRANS_SUBR(4);
12193
12194                 /* fs name length */
12195                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12196                 fnl = tvb_get_letohl(tvb, offset);
12197                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12198                 COUNT_BYTES_TRANS_SUBR(4);
12199
12200                 /* label */
12201                 fn_len = fnl;
12202                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
12203                 CHECK_STRING_TRANS_SUBR(fn);
12204                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12205                         fn);
12206                 COUNT_BYTES_TRANS_SUBR(fn_len);
12207
12208                 break;
12209         case 1006:      /* QUERY_FS_QUOTA_INFO */
12210                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12211                 break;
12212         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12213                 /* allocation size */
12214                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12215                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12216                 COUNT_BYTES_TRANS_SUBR(8);
12217
12218                 /* caller free allocation units */
12219                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12220                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12221                 COUNT_BYTES_TRANS_SUBR(8);
12222
12223                 /* actual free allocation units */
12224                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12225                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12226                 COUNT_BYTES_TRANS_SUBR(8);
12227
12228                 /* sectors per unit */
12229                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12230                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12231                 COUNT_BYTES_TRANS_SUBR(4);
12232
12233                 /* bytes per sector */
12234                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12235                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12236                 COUNT_BYTES_TRANS_SUBR(4);
12237                 break;
12238         }
12239  
12240         return offset;
12241 }
12242  
12243 static int
12244 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12245     proto_tree *parent_tree)
12246 {
12247         proto_item *item = NULL;
12248         proto_tree *tree = NULL;
12249         smb_info_t *si;
12250         smb_transact2_info_t *t2i;
12251         int count;
12252         gboolean trunc;
12253         int offset = 0;
12254         guint16 dc;
12255
12256         dc = tvb_reported_length(tvb);
12257
12258         si = (smb_info_t *)pinfo->private_data;
12259         if (si->sip != NULL)
12260                 t2i = si->sip->extra_info;
12261         else
12262                 t2i = NULL;
12263
12264         if(parent_tree){
12265                 if (t2i != NULL && t2i->subcmd != -1) {
12266                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12267                                 "%s Data",
12268                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
12269                                         "Unknown (0x%02x)"));
12270                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12271                 } else {
12272                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12273                                 "Unknown Transaction2 Data");
12274                 }
12275         }
12276
12277         if (t2i == NULL) {
12278                 offset += dc;
12279                 return offset;
12280         }
12281         switch(t2i->subcmd){
12282         case 0x00:      /*TRANS2_OPEN2*/
12283                 /* XXX not implemented yet. See SNIA doc */
12284                 break;
12285         case 0x01:      /*TRANS2_FIND_FIRST2*/
12286                 /* returned data */
12287                 count = si->info_count;
12288
12289                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12290                         col_append_fstr(pinfo->cinfo, COL_INFO,
12291                         ", Files:");
12292                 }
12293
12294                 while(count--){
12295                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12296                                 offset, &dc, &trunc);
12297                         if (trunc)
12298                                 break;
12299                 }
12300                 break;
12301         case 0x02:      /*TRANS2_FIND_NEXT2*/
12302                 /* returned data */
12303                 count = si->info_count;
12304
12305                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12306                         col_append_fstr(pinfo->cinfo, COL_INFO,
12307                         ", Files:");
12308                 }
12309
12310                 while(count--){
12311                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12312                                 offset, &dc, &trunc);
12313                         if (trunc)
12314                                 break;
12315                 }
12316                 break;
12317         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12318                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12319                 break;
12320         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12321                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12322                 break;
12323         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12324                 /* no data in this response */
12325                 break;
12326         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12327                 /* identical to QUERY_PATH_INFO */
12328                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12329                 break;
12330         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12331                 /* no data in this response */
12332                 break;
12333         case 0x09:      /*TRANS2_FSCTL*/
12334                 /* XXX dont know how to dissect this one (yet)*/
12335
12336                 /*
12337                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12338                  * Extensions Version 3.0, Document Version 1.11,
12339                  * July 19, 1990" says this this contains a
12340                  * "File system specific return data block".
12341                  * (That means we may not be able to dissect it in any
12342                  * case.)
12343                  */
12344                 break;
12345         case 0x0a:      /*TRANS2_IOCTL2*/
12346                 /* XXX dont know how to dissect this one (yet)*/
12347
12348                 /*
12349                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12350                  * Extensions Version 3.0, Document Version 1.11,
12351                  * July 19, 1990" says this this contains a
12352                  * "Device/function specific return data block".
12353                  * (That means we may not be able to dissect it in any
12354                  * case.)
12355                  */
12356                 break;
12357         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12358                 /* XXX dont know how to dissect this one (yet)*/
12359
12360                 /*
12361                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12362                  * Extensions Version 3.0, Document Version 1.11,
12363                  * July 19, 1990" says this this contains "the level
12364                  * dependent information about the changes which
12365                  * occurred".
12366                  */
12367                 break;
12368         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12369                 /* XXX dont know how to dissect this one (yet)*/
12370
12371                 /*
12372                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12373                  * Extensions Version 3.0, Document Version 1.11,
12374                  * July 19, 1990" says this this contains "the level
12375                  * dependent information about the changes which
12376                  * occurred".
12377                  */
12378                 break;
12379         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12380                 /* no data in this response */
12381                 break;
12382         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12383                 /* XXX dont know how to dissect this one (yet)*/
12384                 break;
12385         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12386                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12387                 break;
12388         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12389                 /* the SNIA spec appears to say the response has no data */
12390                 break;
12391         case -1:
12392                 /*
12393                  * We don't know what the matching request was; don't
12394                  * bother putting anything else into the tree for the data.
12395                  */
12396                 offset += dc;
12397                 dc = 0;
12398                 break;
12399         }
12400
12401         /* ooops there were data we didnt know how to process */
12402         if(dc != 0){
12403                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12404                 offset += dc;
12405         }
12406
12407         return offset;
12408 }
12409
12410
12411 static void
12412 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12413 {
12414         proto_item *item = NULL;
12415         proto_tree *tree = NULL;
12416         smb_info_t *si;
12417         smb_transact2_info_t *t2i;
12418         guint16 fid;
12419         int lno;
12420         int offset = 0;
12421         int pc;
12422
12423         pc = tvb_reported_length(tvb);
12424
12425         si = (smb_info_t *)pinfo->private_data;
12426         if (si->sip != NULL)
12427                 t2i = si->sip->extra_info;
12428         else
12429                 t2i = NULL;
12430
12431         if(parent_tree){
12432                 if (t2i != NULL && t2i->subcmd != -1) {
12433                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12434                                 "%s Parameters",
12435                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
12436                                                 "Unknown (0x%02x)"));
12437                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
12438                 } else {
12439                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12440                                 "Unknown Transaction2 Parameters");
12441                 }
12442         }
12443
12444         if (t2i == NULL) {
12445                 offset += pc;
12446                 return;
12447         }
12448         switch(t2i->subcmd){
12449         case 0x00:      /*TRANS2_OPEN2*/
12450                 /* fid */
12451                 fid = tvb_get_letohs(tvb, offset);
12452                 add_fid(tvb, pinfo, tree, offset, 2, fid);
12453                 offset += 2;
12454
12455                 /*
12456                  * XXX - Microsoft Networks SMB File Sharing Protocol
12457                  * Extensions Version 3.0, Document Version 1.11,
12458                  * July 19, 1990 says that the file attributes, create
12459                  * time (which it says is the last modification time),
12460                  * data size, granted access, file type, and IPC state
12461                  * are returned only if bit 0 is set in the open flags,
12462                  * and that the EA length is returned only if bit 3
12463                  * is set in the open flags.  Does that mean that,
12464                  * at least in that SMB dialect, those fields are not
12465                  * present in the reply parameters if the bits in
12466                  * question aren't set?
12467                  */
12468
12469                 /* File Attributes */
12470                 offset = dissect_file_attributes(tvb, tree, offset);
12471
12472                 /* create time */
12473                 offset = dissect_smb_datetime(tvb, tree, offset,
12474                         hf_smb_create_time, 
12475                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
12476
12477                 /* data size */
12478                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12479                 offset += 4;
12480
12481                 /* granted access */
12482                 offset = dissect_access(tvb, tree, offset, "Granted");
12483
12484                 /* File Type */
12485                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
12486                 offset += 2;
12487
12488                 /* IPC State */
12489                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
12490
12491                 /* open_action */
12492                 offset = dissect_open_action(tvb, tree, offset);
12493
12494                 /* server unique file ID */
12495                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
12496                 offset += 4;
12497
12498                 /* ea error offset, only a 16 bit integer here */
12499                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12500                 offset += 2;
12501
12502                 /* ea length */
12503                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
12504                 offset += 4;
12505
12506                 break;
12507         case 0x01:      /*TRANS2_FIND_FIRST2*/
12508                 /* Find First2 information level */
12509                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
12510
12511                 /* sid */
12512                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
12513                 offset += 2;
12514
12515                 /* search count */
12516                 si->info_count = tvb_get_letohs(tvb, offset);
12517                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12518                 offset += 2;
12519
12520                 /* end of search */
12521                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12522                 offset += 2;
12523
12524                 /* ea error offset, only a 16 bit integer here */
12525                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12526                 offset += 2;
12527
12528                 /* last name offset */
12529                 lno = tvb_get_letohs(tvb, offset);
12530                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12531                 offset += 2;
12532
12533                 break;
12534         case 0x02:      /*TRANS2_FIND_NEXT2*/
12535                 /* search count */
12536                 si->info_count = tvb_get_letohs(tvb, offset);
12537                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12538                 offset += 2;
12539
12540                 /* end of search */
12541                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12542                 offset += 2;
12543
12544                 /* ea_error_offset, only a 16 bit integer here*/
12545                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12546                 offset += 2;
12547
12548                 /* last name offset */
12549                 lno = tvb_get_letohs(tvb, offset);
12550                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12551                 offset += 2;
12552
12553                 break;
12554         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12555                 /* no parameter block here */
12556                 break;
12557         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12558                 /* ea_error_offset, only a 16 bit integer here*/
12559                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12560                 offset += 2;
12561
12562                 break;
12563         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12564                 /* ea_error_offset, only a 16 bit integer here*/
12565                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12566                 offset += 2;
12567
12568                 break;
12569         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12570                 /* ea_error_offset, only a 16 bit integer here*/
12571                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12572                 offset += 2;
12573
12574                 break;
12575         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12576                 /* ea_error_offset, only a 16 bit integer here*/
12577                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12578                 offset += 2;
12579
12580                 break;
12581         case 0x09:      /*TRANS2_FSCTL*/
12582                 /* XXX dont know how to dissect this one (yet)*/
12583
12584                 /*
12585                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12586                  * Extensions Version 3.0, Document Version 1.11,
12587                  * July 19, 1990" says this this contains a
12588                  * "File system specific return parameter block".
12589                  * (That means we may not be able to dissect it in any
12590                  * case.)
12591                  */
12592                 break;
12593         case 0x0a:      /*TRANS2_IOCTL2*/
12594                 /* XXX dont know how to dissect this one (yet)*/
12595
12596                 /*
12597                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12598                  * Extensions Version 3.0, Document Version 1.11,
12599                  * July 19, 1990" says this this contains a
12600                  * "Device/function specific return parameter block".
12601                  * (That means we may not be able to dissect it in any
12602                  * case.)
12603                  */
12604                 break;
12605         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12606                 /* Find Notify information level */
12607                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12608
12609                 /* Monitor handle */
12610                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
12611                 offset += 2;
12612
12613                 /* Change count */
12614                 si->info_count = tvb_get_letohs(tvb, offset);
12615                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12616                 offset += 2;
12617
12618                 /* ea_error_offset, only a 16 bit integer here*/
12619                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12620                 offset += 2;
12621
12622                 break;
12623         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12624                 /* Find Notify information level */
12625                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12626
12627                 /* Change count */
12628                 si->info_count = tvb_get_letohs(tvb, offset);
12629                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12630                 offset += 2;
12631
12632                 /* ea_error_offset, only a 16 bit integer here*/
12633                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12634                 offset += 2;
12635
12636                 break;
12637         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12638                 /* ea error offset, only a 16 bit integer here */
12639                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12640                 offset += 2;
12641
12642                 break;
12643         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12644                 /* XXX dont know how to dissect this one (yet)*/
12645                 break;
12646         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12647                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12648                 break;
12649         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12650                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12651                 break;
12652         case -1:
12653                 /*
12654                  * We don't know what the matching request was; don't
12655                  * bother putting anything else into the tree for the data.
12656                  */
12657                 offset += pc;
12658                 break;
12659         }
12660
12661         /* ooops there were data we didnt know how to process */
12662         if(offset<pc){
12663                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
12664                 offset += pc-offset;
12665         }
12666 }
12667
12668
12669 static int
12670 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12671 {
12672         guint8 sc, wc;
12673         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
12674         smb_info_t *si;
12675         smb_transact2_info_t *t2i = NULL;
12676         guint16 bc;
12677         int padcnt;
12678         gboolean dissected_trans;
12679         fragment_data *r_fd = NULL;
12680         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
12681         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
12682         gboolean save_fragmented;
12683
12684         si = (smb_info_t *)pinfo->private_data;
12685
12686         switch(si->cmd){
12687         case SMB_COM_TRANSACTION2:
12688                 /* transaction2 */
12689                 if (si->sip != NULL) {
12690                         t2i = si->sip->extra_info;
12691                 } else
12692                         t2i = NULL;
12693                 if (t2i == NULL) {
12694                         /*
12695                          * We didn't see the matching request, so we don't
12696                          * know what type of transaction this is.
12697                          */
12698                         proto_tree_add_text(tree, tvb, 0, 0,
12699                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
12700                         if (check_col(pinfo->cinfo, COL_INFO)) {
12701                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12702                         }
12703                 } else {
12704                         si->info_level = t2i->info_level;
12705                         if (t2i->subcmd == -1) {
12706                                 /*
12707                                  * We didn't manage to extract the subcommand
12708                                  * from the matching request (perhaps because
12709                                  * the frame was short), so we don't know what
12710                                  * type of transaction this is.
12711                                  */
12712                                 proto_tree_add_text(tree, tvb, 0, 0,
12713                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
12714                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12715                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12716                                 }
12717                         } else {
12718                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
12719                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12720                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12721                                                 val_to_str(t2i->subcmd,
12722                                                         trans2_cmd_vals, 
12723                                                         "<unknown (0x%02x)>"));
12724                                 }
12725                         }
12726                 }
12727                 break;
12728         }
12729
12730         WORD_COUNT;
12731
12732         /* total param count, only a 16bit integer here */
12733         tp = tvb_get_letohs(tvb, offset);
12734         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
12735         offset += 2;
12736
12737         /* total data count, only a 16 bit integer here */
12738         td = tvb_get_letohs(tvb, offset);
12739         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
12740         offset += 2;
12741
12742         /* 2 reserved bytes */
12743         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12744         offset += 2;
12745
12746         /* param count */
12747         pc = tvb_get_letohs(tvb, offset);
12748         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12749         offset += 2;
12750
12751         /* param offset */
12752         po = tvb_get_letohs(tvb, offset);
12753         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12754         offset += 2;
12755
12756         /* param disp */
12757         pd = tvb_get_letohs(tvb, offset);
12758         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12759         offset += 2;
12760
12761         /* data count */
12762         dc = tvb_get_letohs(tvb, offset);
12763         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12764         offset += 2;
12765
12766         /* data offset */
12767         od = tvb_get_letohs(tvb, offset);
12768         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12769         offset += 2;
12770
12771         /* data disp */
12772         dd = tvb_get_letohs(tvb, offset);
12773         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12774         offset += 2;
12775
12776         /* setup count */
12777         sc = tvb_get_guint8(tvb, offset);
12778         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12779         offset += 1;
12780
12781         /* reserved byte */
12782         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12783         offset += 1;
12784
12785
12786         /* if there were any setup bytes, put them in a tvb for later */
12787         if(sc){
12788                 if((2*sc)>tvb_length_remaining(tvb, offset)){
12789                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
12790                 } else {
12791                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
12792                 }
12793                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
12794         } else {
12795                 s_tvb = NULL;
12796                 sp_tvb=NULL;
12797         }
12798         offset += 2*sc;
12799
12800
12801         BYTE_COUNT;
12802
12803
12804         /* reassembly of SMB Transaction data payload.
12805            In this section we do reassembly of both the data and parameters
12806            blocks of the SMB transaction command.
12807         */
12808         save_fragmented = pinfo->fragmented;
12809         /* do we need reassembly? */
12810         if( (td!=dc) || (tp!=pc) ){
12811                 /* oh yeah, either data or parameter section needs 
12812                    reassembly
12813                 */
12814                 pinfo->fragmented = TRUE;
12815                 if(smb_trans_reassembly){
12816                         /* ...and we were told to do reassembly */
12817                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
12818                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12819                                                              po, pc, pd, td+tp);
12820                                 
12821                         }
12822                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
12823                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12824                                                              od, dc, dd+tp, td+tp);
12825                         }
12826                 }
12827         }
12828
12829         /* if we got a reassembled fd structure from the reassembly routine we must
12830            create pd_tvb from it 
12831         */
12832         if(r_fd){
12833                 proto_tree *tr;
12834                 proto_item *it;
12835                 fragment_data *fd;
12836
12837                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
12838                                              r_fd->datalen);
12839                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
12840                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
12841                 pinfo->fragmented = FALSE;
12842
12843                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
12844                 tr = proto_item_add_subtree(it, ett_smb_segments);
12845                 for(fd=r_fd->next;fd;fd=fd->next){
12846                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
12847                                             "Frame:%u Data:%u-%u",
12848                                             fd->frame, fd->offset,
12849                                             fd->offset+fd->len-1);
12850                 }
12851         }
12852
12853
12854         if(pd_tvb){
12855                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
12856                 if(tp){
12857                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
12858                 }
12859                 if(td){
12860                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
12861                 }
12862         } else {
12863                 /* It was not reassembled. Do as best as we can.
12864                  * in this case we always try to dissect the stuff if 
12865                  * data and param displacement is 0. i.e. for the first
12866                  * (and maybe only) packet.
12867                  */
12868                 if( (pd==0) && (dd==0) ){
12869                         int min;
12870                         int reported_min;
12871                         min = MIN(pc,tvb_length_remaining(tvb,po));
12872                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
12873                         if(min && reported_min) {
12874                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
12875                         }
12876                         min = MIN(dc,tvb_length_remaining(tvb,od));
12877                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
12878                         if(min && reported_min) {
12879                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
12880                         }
12881                         /*
12882                          * A tvbuff containing the parameters
12883                          * and the data.
12884                          * XXX - check pc and dc as well?
12885                          */
12886                         if (tvb_length_remaining(tvb, po)){
12887                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12888                         }
12889                 }
12890         }
12891
12892
12893
12894         /* parameters */
12895         if(po>offset){
12896                 /* We have some padding bytes.
12897                 */
12898                 padcnt = po-offset;
12899                 if (padcnt > bc)
12900                         padcnt = bc;
12901                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12902                 COUNT_BYTES(padcnt);
12903         }
12904         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
12905                 /* TRANSACTION2 parameters*/
12906                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
12907         }
12908         COUNT_BYTES(pc);
12909
12910
12911         /* data */
12912         if(od>offset){
12913                 /* We have some initial padding bytes.
12914                 */
12915                 padcnt = od-offset;
12916                 if (padcnt > bc)
12917                         padcnt = bc;
12918                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12919                 COUNT_BYTES(padcnt);
12920         }
12921         /*
12922          * If the data count is bigger than the count of bytes
12923          * remaining, clamp it so that the count of bytes remaining
12924          * doesn't go negative.
12925          */
12926         if (dc > bc)
12927                 dc = bc;
12928         COUNT_BYTES(dc);
12929
12930
12931
12932         /* from now on, everything is in separate tvbuffs so we dont count
12933            the bytes with COUNT_BYTES any more.
12934            neither do we reference offset any more (which by now points to the
12935            first byte AFTER this PDU */
12936
12937
12938         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
12939                 /* TRANSACTION2 parameters*/
12940                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
12941         }
12942
12943
12944         if(si->cmd==SMB_COM_TRANSACTION){
12945                 smb_transact_info_t *tri;
12946
12947                 dissected_trans = FALSE;
12948                 if (si->sip != NULL)
12949                         tri = si->sip->extra_info;
12950                 else
12951                         tri = NULL;
12952                 if (tri != NULL) {
12953                         switch(tri->subcmd){
12954
12955                         case TRANSACTION_PIPE:
12956                                 /* This function is safe to call for 
12957                                    s_tvb==sp_tvb==NULL, i.e. if we don't
12958                                    know them at this point.
12959                                    It's also safe to call if "p_tvb"
12960                                    or "d_tvb" are null.
12961                                 */
12962                                 if( pd_tvb) {
12963                                         dissected_trans = dissect_pipe_smb(
12964                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
12965                                                 d_tvb, NULL, pinfo, top_tree);
12966                                 }
12967                                 break;
12968                                 
12969                         case TRANSACTION_MAILSLOT:
12970                                 /* This one should be safe to call
12971                                    even if s_tvb and sp_tvb is NULL
12972                                 */
12973                                 if(d_tvb){
12974                                         dissected_trans = dissect_mailslot_smb(
12975                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
12976                                                 top_tree);
12977                                 }
12978                                 break;
12979                         }
12980                 }
12981                 if (!dissected_trans) {
12982                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
12983                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12984                 }
12985         }
12986
12987
12988         if( (p_tvb==0) && (d_tvb==0) ){
12989                 if(check_col(pinfo->cinfo, COL_INFO)){
12990                         col_append_str(pinfo->cinfo, COL_INFO,
12991                                        "[transact continuation]");
12992                 }
12993         }
12994
12995         pinfo->fragmented = save_fragmented;
12996         END_OF_SMB
12997
12998         return offset;
12999 }
13000
13001
13002 static int
13003 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13004 {
13005         guint8 wc;
13006         guint16 bc;
13007
13008         WORD_COUNT;
13009
13010         /* Monitor handle */
13011         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13012         offset += 2;
13013
13014         BYTE_COUNT;
13015
13016         END_OF_SMB
13017
13018         return offset;
13019 }
13020
13021 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13022    END Transaction/Transaction2 Primary and secondary requests
13023    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13024
13025
13026 static int
13027 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13028 {
13029         guint8 wc;
13030         guint16 bc;
13031
13032         WORD_COUNT;
13033  
13034         if (wc != 0) {
13035                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13036                 offset += wc*2;
13037         }
13038
13039         BYTE_COUNT;
13040
13041         if (bc != 0) {
13042                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13043                 offset += bc;
13044                 bc = 0;
13045         }
13046
13047         END_OF_SMB
13048
13049         return offset;
13050 }
13051
13052 typedef struct _smb_function {
13053        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13054        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13055 } smb_function;
13056
13057 static smb_function smb_dissector[256] = {
13058   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13059   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13060   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13061   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13062   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13063   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13064   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13065   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13066   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13067   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13068   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13069   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13070   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13071   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13072   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13073   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13074
13075   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13076   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13077   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13078   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13079   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13080   /* 0x15 */  {dissect_unknown, dissect_unknown},
13081   /* 0x16 */  {dissect_unknown, dissect_unknown},
13082   /* 0x17 */  {dissect_unknown, dissect_unknown},
13083   /* 0x18 */  {dissect_unknown, dissect_unknown},
13084   /* 0x19 */  {dissect_unknown, dissect_unknown},
13085   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13086   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13087   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13088   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13089   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13090   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13091
13092   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13093   /* 0x21 */  {dissect_unknown, dissect_unknown},
13094   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13095   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13096   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13097   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13098   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13099   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13100   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13101   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13102   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13103   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13104   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13105   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13106   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13107   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13108
13109   /* 0x30 */  {dissect_unknown, dissect_unknown},
13110   /* 0x31 Close And Tree Discover*/  {dissect_unknown, dissect_unknown},
13111   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13112   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13113   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13114   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13115   /* 0x36 */  {dissect_unknown, dissect_unknown},
13116   /* 0x37 */  {dissect_unknown, dissect_unknown},
13117   /* 0x38 */  {dissect_unknown, dissect_unknown},
13118   /* 0x39 */  {dissect_unknown, dissect_unknown},
13119   /* 0x3a */  {dissect_unknown, dissect_unknown},
13120   /* 0x3b */  {dissect_unknown, dissect_unknown},
13121   /* 0x3c */  {dissect_unknown, dissect_unknown},
13122   /* 0x3d */  {dissect_unknown, dissect_unknown},
13123   /* 0x3e */  {dissect_unknown, dissect_unknown},
13124   /* 0x3f */  {dissect_unknown, dissect_unknown},
13125
13126   /* 0x40 */  {dissect_unknown, dissect_unknown},
13127   /* 0x41 */  {dissect_unknown, dissect_unknown},
13128   /* 0x42 */  {dissect_unknown, dissect_unknown},
13129   /* 0x43 */  {dissect_unknown, dissect_unknown},
13130   /* 0x44 */  {dissect_unknown, dissect_unknown},
13131   /* 0x45 */  {dissect_unknown, dissect_unknown},
13132   /* 0x46 */  {dissect_unknown, dissect_unknown},
13133   /* 0x47 */  {dissect_unknown, dissect_unknown},
13134   /* 0x48 */  {dissect_unknown, dissect_unknown},
13135   /* 0x49 */  {dissect_unknown, dissect_unknown},
13136   /* 0x4a */  {dissect_unknown, dissect_unknown},
13137   /* 0x4b */  {dissect_unknown, dissect_unknown},
13138   /* 0x4c */  {dissect_unknown, dissect_unknown},
13139   /* 0x4d */  {dissect_unknown, dissect_unknown},
13140   /* 0x4e */  {dissect_unknown, dissect_unknown},
13141   /* 0x4f */  {dissect_unknown, dissect_unknown},
13142
13143   /* 0x50 */  {dissect_unknown, dissect_unknown},
13144   /* 0x51 */  {dissect_unknown, dissect_unknown},
13145   /* 0x52 */  {dissect_unknown, dissect_unknown},
13146   /* 0x53 */  {dissect_unknown, dissect_unknown},
13147   /* 0x54 */  {dissect_unknown, dissect_unknown},
13148   /* 0x55 */  {dissect_unknown, dissect_unknown},
13149   /* 0x56 */  {dissect_unknown, dissect_unknown},
13150   /* 0x57 */  {dissect_unknown, dissect_unknown},
13151   /* 0x58 */  {dissect_unknown, dissect_unknown},
13152   /* 0x59 */  {dissect_unknown, dissect_unknown},
13153   /* 0x5a */  {dissect_unknown, dissect_unknown},
13154   /* 0x5b */  {dissect_unknown, dissect_unknown},
13155   /* 0x5c */  {dissect_unknown, dissect_unknown},
13156   /* 0x5d */  {dissect_unknown, dissect_unknown},
13157   /* 0x5e */  {dissect_unknown, dissect_unknown},
13158   /* 0x5f */  {dissect_unknown, dissect_unknown},
13159
13160   /* 0x60 */  {dissect_unknown, dissect_unknown},
13161   /* 0x61 */  {dissect_unknown, dissect_unknown},
13162   /* 0x62 */  {dissect_unknown, dissect_unknown},
13163   /* 0x63 */  {dissect_unknown, dissect_unknown},
13164   /* 0x64 */  {dissect_unknown, dissect_unknown},
13165   /* 0x65 */  {dissect_unknown, dissect_unknown},
13166   /* 0x66 */  {dissect_unknown, dissect_unknown},
13167   /* 0x67 */  {dissect_unknown, dissect_unknown},
13168   /* 0x68 */  {dissect_unknown, dissect_unknown},
13169   /* 0x69 */  {dissect_unknown, dissect_unknown},
13170   /* 0x6a */  {dissect_unknown, dissect_unknown},
13171   /* 0x6b */  {dissect_unknown, dissect_unknown},
13172   /* 0x6c */  {dissect_unknown, dissect_unknown},
13173   /* 0x6d */  {dissect_unknown, dissect_unknown},
13174   /* 0x6e */  {dissect_unknown, dissect_unknown},
13175   /* 0x6f */  {dissect_unknown, dissect_unknown},
13176
13177   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13178   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13179   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13180   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13181   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13182   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13183   /* 0x76 */  {dissect_unknown, dissect_unknown},
13184   /* 0x77 */  {dissect_unknown, dissect_unknown},
13185   /* 0x78 */  {dissect_unknown, dissect_unknown},
13186   /* 0x79 */  {dissect_unknown, dissect_unknown},
13187   /* 0x7a */  {dissect_unknown, dissect_unknown},
13188   /* 0x7b */  {dissect_unknown, dissect_unknown},
13189   /* 0x7c */  {dissect_unknown, dissect_unknown},
13190   /* 0x7d */  {dissect_unknown, dissect_unknown},
13191   /* 0x7e */  {dissect_unknown, dissect_unknown},
13192   /* 0x7f */  {dissect_unknown, dissect_unknown},
13193
13194   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13195   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13196   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13197   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13198   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13199   /* 0x85 */  {dissect_unknown, dissect_unknown},
13200   /* 0x86 */  {dissect_unknown, dissect_unknown},
13201   /* 0x87 */  {dissect_unknown, dissect_unknown},
13202   /* 0x88 */  {dissect_unknown, dissect_unknown},
13203   /* 0x89 */  {dissect_unknown, dissect_unknown},
13204   /* 0x8a */  {dissect_unknown, dissect_unknown},
13205   /* 0x8b */  {dissect_unknown, dissect_unknown},
13206   /* 0x8c */  {dissect_unknown, dissect_unknown},
13207   /* 0x8d */  {dissect_unknown, dissect_unknown},
13208   /* 0x8e */  {dissect_unknown, dissect_unknown},
13209   /* 0x8f */  {dissect_unknown, dissect_unknown},
13210
13211   /* 0x90 */  {dissect_unknown, dissect_unknown},
13212   /* 0x91 */  {dissect_unknown, dissect_unknown},
13213   /* 0x92 */  {dissect_unknown, dissect_unknown},
13214   /* 0x93 */  {dissect_unknown, dissect_unknown},
13215   /* 0x94 */  {dissect_unknown, dissect_unknown},
13216   /* 0x95 */  {dissect_unknown, dissect_unknown},
13217   /* 0x96 */  {dissect_unknown, dissect_unknown},
13218   /* 0x97 */  {dissect_unknown, dissect_unknown},
13219   /* 0x98 */  {dissect_unknown, dissect_unknown},
13220   /* 0x99 */  {dissect_unknown, dissect_unknown},
13221   /* 0x9a */  {dissect_unknown, dissect_unknown},
13222   /* 0x9b */  {dissect_unknown, dissect_unknown},
13223   /* 0x9c */  {dissect_unknown, dissect_unknown},
13224   /* 0x9d */  {dissect_unknown, dissect_unknown},
13225   /* 0x9e */  {dissect_unknown, dissect_unknown},
13226   /* 0x9f */  {dissect_unknown, dissect_unknown},
13227
13228   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13229   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13230   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13231   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13232   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13233   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13234   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13235   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13236   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13237   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13238   /* 0xaa */  {dissect_unknown, dissect_unknown},
13239   /* 0xab */  {dissect_unknown, dissect_unknown},
13240   /* 0xac */  {dissect_unknown, dissect_unknown},
13241   /* 0xad */  {dissect_unknown, dissect_unknown},
13242   /* 0xae */  {dissect_unknown, dissect_unknown},
13243   /* 0xaf */  {dissect_unknown, dissect_unknown},
13244
13245   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13246   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13247   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13248   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13249   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13250   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13251   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13252   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13253   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13254   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13255   /* 0xba */  {dissect_unknown, dissect_unknown},
13256   /* 0xbb */  {dissect_unknown, dissect_unknown},
13257   /* 0xbc */  {dissect_unknown, dissect_unknown},
13258   /* 0xbd */  {dissect_unknown, dissect_unknown},
13259   /* 0xbe */  {dissect_unknown, dissect_unknown},
13260   /* 0xbf */  {dissect_unknown, dissect_unknown},
13261
13262   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13263   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13264   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13265   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13266   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13267   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13268   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13269   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13270   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13271   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13272   /* 0xca */  {dissect_unknown, dissect_unknown},
13273   /* 0xcb */  {dissect_unknown, dissect_unknown},
13274   /* 0xcc */  {dissect_unknown, dissect_unknown},
13275   /* 0xcd */  {dissect_unknown, dissect_unknown},
13276   /* 0xce */  {dissect_unknown, dissect_unknown},
13277   /* 0xcf */  {dissect_unknown, dissect_unknown},
13278
13279   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13280   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13281   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13282   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13283   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13284   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13285   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13286   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13287   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13288   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13289   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13290   /* 0xdb */  {dissect_unknown, dissect_unknown},
13291   /* 0xdc */  {dissect_unknown, dissect_unknown},
13292   /* 0xdd */  {dissect_unknown, dissect_unknown},
13293   /* 0xde */  {dissect_unknown, dissect_unknown},
13294   /* 0xdf */  {dissect_unknown, dissect_unknown},
13295
13296   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13297   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13298   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13299   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13300   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13301   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13302   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13303   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13304   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13305   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13306   /* 0xea */  {dissect_unknown, dissect_unknown},
13307   /* 0xeb */  {dissect_unknown, dissect_unknown},
13308   /* 0xec */  {dissect_unknown, dissect_unknown},
13309   /* 0xed */  {dissect_unknown, dissect_unknown},
13310   /* 0xee */  {dissect_unknown, dissect_unknown},
13311   /* 0xef */  {dissect_unknown, dissect_unknown},
13312
13313   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13314   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13315   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13316   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13317   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13318   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13319   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13320   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13321   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13322   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13323   /* 0xfa */  {dissect_unknown, dissect_unknown},
13324   /* 0xfb */  {dissect_unknown, dissect_unknown},
13325   /* 0xfc */  {dissect_unknown, dissect_unknown},
13326   /* 0xfd */  {dissect_unknown, dissect_unknown},
13327   /* 0xfe */  {dissect_unknown, dissect_unknown},
13328   /* 0xff */  {dissect_unknown, dissect_unknown},
13329 };
13330
13331 static int
13332 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd)
13333 {
13334         int old_offset = offset;
13335         smb_info_t *si;
13336  
13337         si = pinfo->private_data;
13338         if(cmd!=0xff){
13339                 proto_item *cmd_item;
13340                 proto_tree *cmd_tree;
13341                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13342
13343                 if (check_col(pinfo->cinfo, COL_INFO)) {
13344                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
13345                                 decode_smb_name(cmd),
13346                                 (si->request)? "Request" : "Response");
13347                 }
13348
13349                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13350                         "%s %s (0x%02x)",
13351                         decode_smb_name(cmd), 
13352                         (si->request)?"Request":"Response",
13353                         cmd);
13354
13355                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13356
13357                 dissector = (si->request)?
13358                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13359
13360                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13361                 proto_item_set_len(cmd_item, offset-old_offset);
13362         }
13363         return offset;
13364 }
13365
13366
13367 /* NOTE: this value_string array will also be used to access data directly by
13368  * index instead of val_to_str() since 
13369  * 1, the array will always span every value from 0x00 to 0xff and
13370  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13371  * This means that this value_string array MUST always
13372  * 1, contain all entries 0x00 to 0xff
13373  * 2, all entries must be in order.
13374  */
13375 static const value_string smb_cmd_vals[] = {
13376   { 0x00, "Create Directory" },
13377   { 0x01, "Delete Directory" },
13378   { 0x02, "Open" },
13379   { 0x03, "Create" },
13380   { 0x04, "Close" },
13381   { 0x05, "Flush" },
13382   { 0x06, "Delete" },
13383   { 0x07, "Rename" },
13384   { 0x08, "Query Information" },
13385   { 0x09, "Set Information" },
13386   { 0x0A, "Read" },
13387   { 0x0B, "Write" },
13388   { 0x0C, "Lock Byte Range" },
13389   { 0x0D, "Unlock Byte Range" },
13390   { 0x0E, "Create Temp" },
13391   { 0x0F, "Create New" },
13392   { 0x10, "Check Directory" },
13393   { 0x11, "Process Exit" },
13394   { 0x12, "Seek" },
13395   { 0x13, "Lock And Read" },
13396   { 0x14, "Write And Unlock" },
13397   { 0x15, "unknown-0x15" },
13398   { 0x16, "unknown-0x16" },
13399   { 0x17, "unknown-0x17" },
13400   { 0x18, "unknown-0x18" },
13401   { 0x19, "unknown-0x19" },
13402   { 0x1A, "Read Raw" },
13403   { 0x1B, "Read MPX" },
13404   { 0x1C, "Read MPX Secondary" },
13405   { 0x1D, "Write Raw" },
13406   { 0x1E, "Write MPX" },
13407   { 0x1F, "Write MPX Secondary" },
13408   { 0x20, "Write Complete" },
13409   { 0x21, "unknown-0x21" },
13410   { 0x22, "Set Information2" },
13411   { 0x23, "Query Information2" },
13412   { 0x24, "Locking AndX" },
13413   { 0x25, "Transaction" },
13414   { 0x26, "Transaction Secondary" },
13415   { 0x27, "IOCTL" },
13416   { 0x28, "IOCTL Secondary" },
13417   { 0x29, "Copy" },
13418   { 0x2A, "Move" },
13419   { 0x2B, "Echo" },
13420   { 0x2C, "Write And Close" },
13421   { 0x2D, "Open AndX" },
13422   { 0x2E, "Read AndX" },
13423   { 0x2F, "Write AndX" },
13424   { 0x30, "unknown-0x30" },
13425   { 0x31, "Close And Tree Discover" },
13426   { 0x32, "Transaction2" },
13427   { 0x33, "Transaction2 Secondary" },
13428   { 0x34, "Find Close2" },
13429   { 0x35, "Find Notify Close" },
13430   { 0x36, "unknown-0x36" },
13431   { 0x37, "unknown-0x37" },
13432   { 0x38, "unknown-0x38" },
13433   { 0x39, "unknown-0x39" },
13434   { 0x3A, "unknown-0x3A" },
13435   { 0x3B, "unknown-0x3B" },
13436   { 0x3C, "unknown-0x3C" },
13437   { 0x3D, "unknown-0x3D" },
13438   { 0x3E, "unknown-0x3E" },
13439   { 0x3F, "unknown-0x3F" },
13440   { 0x40, "unknown-0x40" },
13441   { 0x41, "unknown-0x41" },
13442   { 0x42, "unknown-0x42" },
13443   { 0x43, "unknown-0x43" },
13444   { 0x44, "unknown-0x44" },
13445   { 0x45, "unknown-0x45" },
13446   { 0x46, "unknown-0x46" },
13447   { 0x47, "unknown-0x47" },
13448   { 0x48, "unknown-0x48" },
13449   { 0x49, "unknown-0x49" },
13450   { 0x4A, "unknown-0x4A" },
13451   { 0x4B, "unknown-0x4B" },
13452   { 0x4C, "unknown-0x4C" },
13453   { 0x4D, "unknown-0x4D" },
13454   { 0x4E, "unknown-0x4E" },
13455   { 0x4F, "unknown-0x4F" },
13456   { 0x50, "unknown-0x50" },
13457   { 0x51, "unknown-0x51" },
13458   { 0x52, "unknown-0x52" },
13459   { 0x53, "unknown-0x53" },
13460   { 0x54, "unknown-0x54" },
13461   { 0x55, "unknown-0x55" },
13462   { 0x56, "unknown-0x56" },
13463   { 0x57, "unknown-0x57" },
13464   { 0x58, "unknown-0x58" },
13465   { 0x59, "unknown-0x59" },
13466   { 0x5A, "unknown-0x5A" },
13467   { 0x5B, "unknown-0x5B" },
13468   { 0x5C, "unknown-0x5C" },
13469   { 0x5D, "unknown-0x5D" },
13470   { 0x5E, "unknown-0x5E" },
13471   { 0x5F, "unknown-0x5F" },
13472   { 0x60, "unknown-0x60" },
13473   { 0x61, "unknown-0x61" },
13474   { 0x62, "unknown-0x62" },
13475   { 0x63, "unknown-0x63" },
13476   { 0x64, "unknown-0x64" },
13477   { 0x65, "unknown-0x65" },
13478   { 0x66, "unknown-0x66" },
13479   { 0x67, "unknown-0x67" },
13480   { 0x68, "unknown-0x68" },
13481   { 0x69, "unknown-0x69" },
13482   { 0x6A, "unknown-0x6A" },
13483   { 0x6B, "unknown-0x6B" },
13484   { 0x6C, "unknown-0x6C" },
13485   { 0x6D, "unknown-0x6D" },
13486   { 0x6E, "unknown-0x6E" },
13487   { 0x6F, "unknown-0x6F" },
13488   { 0x70, "Tree Connect" },
13489   { 0x71, "Tree Disconnect" },
13490   { 0x72, "Negotiate Protocol" },
13491   { 0x73, "Session Setup AndX" },
13492   { 0x74, "Logoff AndX" },
13493   { 0x75, "Tree Connect AndX" },
13494   { 0x76, "unknown-0x76" },
13495   { 0x77, "unknown-0x77" },
13496   { 0x78, "unknown-0x78" },
13497   { 0x79, "unknown-0x79" },
13498   { 0x7A, "unknown-0x7A" },
13499   { 0x7B, "unknown-0x7B" },
13500   { 0x7C, "unknown-0x7C" },
13501   { 0x7D, "unknown-0x7D" },
13502   { 0x7E, "unknown-0x7E" },
13503   { 0x7F, "unknown-0x7F" },
13504   { 0x80, "Query Information Disk" },
13505   { 0x81, "Search" },
13506   { 0x82, "Find" },
13507   { 0x83, "Find Unique" },
13508   { 0x84, "Find Close" },
13509   { 0x85, "unknown-0x85" },
13510   { 0x86, "unknown-0x86" },
13511   { 0x87, "unknown-0x87" },
13512   { 0x88, "unknown-0x88" },
13513   { 0x89, "unknown-0x89" },
13514   { 0x8A, "unknown-0x8A" },
13515   { 0x8B, "unknown-0x8B" },
13516   { 0x8C, "unknown-0x8C" },
13517   { 0x8D, "unknown-0x8D" },
13518   { 0x8E, "unknown-0x8E" },
13519   { 0x8F, "unknown-0x8F" },
13520   { 0x90, "unknown-0x90" },
13521   { 0x91, "unknown-0x91" },
13522   { 0x92, "unknown-0x92" },
13523   { 0x93, "unknown-0x93" },
13524   { 0x94, "unknown-0x94" },
13525   { 0x95, "unknown-0x95" },
13526   { 0x96, "unknown-0x96" },
13527   { 0x97, "unknown-0x97" },
13528   { 0x98, "unknown-0x98" },
13529   { 0x99, "unknown-0x99" },
13530   { 0x9A, "unknown-0x9A" },
13531   { 0x9B, "unknown-0x9B" },
13532   { 0x9C, "unknown-0x9C" },
13533   { 0x9D, "unknown-0x9D" },
13534   { 0x9E, "unknown-0x9E" },
13535   { 0x9F, "unknown-0x9F" },
13536   { 0xA0, "NT Transact" },
13537   { 0xA1, "NT Transact Secondary" },
13538   { 0xA2, "NT Create AndX" },
13539   { 0xA3, "unknown-0xA3" },
13540   { 0xA4, "NT Cancel" },
13541   { 0xA5, "NT Rename" },
13542   { 0xA6, "unknown-0xA6" },
13543   { 0xA7, "unknown-0xA7" },
13544   { 0xA8, "unknown-0xA8" },
13545   { 0xA9, "unknown-0xA9" },
13546   { 0xAA, "unknown-0xAA" },
13547   { 0xAB, "unknown-0xAB" },
13548   { 0xAC, "unknown-0xAC" },
13549   { 0xAD, "unknown-0xAD" },
13550   { 0xAE, "unknown-0xAE" },
13551   { 0xAF, "unknown-0xAF" },
13552   { 0xB0, "unknown-0xB0" },
13553   { 0xB1, "unknown-0xB1" },
13554   { 0xB2, "unknown-0xB2" },
13555   { 0xB3, "unknown-0xB3" },
13556   { 0xB4, "unknown-0xB4" },
13557   { 0xB5, "unknown-0xB5" },
13558   { 0xB6, "unknown-0xB6" },
13559   { 0xB7, "unknown-0xB7" },
13560   { 0xB8, "unknown-0xB8" },
13561   { 0xB9, "unknown-0xB9" },
13562   { 0xBA, "unknown-0xBA" },
13563   { 0xBB, "unknown-0xBB" },
13564   { 0xBC, "unknown-0xBC" },
13565   { 0xBD, "unknown-0xBD" },
13566   { 0xBE, "unknown-0xBE" },
13567   { 0xBF, "unknown-0xBF" },
13568   { 0xC0, "Open Print File" },
13569   { 0xC1, "Write Print File" },
13570   { 0xC2, "Close Print File" },
13571   { 0xC3, "Get Print Queue" },
13572   { 0xC4, "unknown-0xC4" },
13573   { 0xC5, "unknown-0xC5" },
13574   { 0xC6, "unknown-0xC6" },
13575   { 0xC7, "unknown-0xC7" },
13576   { 0xC8, "unknown-0xC8" },
13577   { 0xC9, "unknown-0xC9" },
13578   { 0xCA, "unknown-0xCA" },
13579   { 0xCB, "unknown-0xCB" },
13580   { 0xCC, "unknown-0xCC" },
13581   { 0xCD, "unknown-0xCD" },
13582   { 0xCE, "unknown-0xCE" },
13583   { 0xCF, "unknown-0xCF" },
13584   { 0xD0, "Send Single Block Message" },
13585   { 0xD1, "Send Broadcast Message" },
13586   { 0xD2, "Forward User Name" },
13587   { 0xD3, "Cancel Forward" },
13588   { 0xD4, "Get Machine Name" },
13589   { 0xD5, "Send Start of Multi-block Message" },
13590   { 0xD6, "Send End of Multi-block Message" },
13591   { 0xD7, "Send Text of Multi-block Message" },
13592   { 0xD8, "SMBreadbulk" },
13593   { 0xD9, "SMBwritebulk" },
13594   { 0xDA, "SMBwritebulkdata" },
13595   { 0xDB, "unknown-0xDB" },
13596   { 0xDC, "unknown-0xDC" },
13597   { 0xDD, "unknown-0xDD" },
13598   { 0xDE, "unknown-0xDE" },
13599   { 0xDF, "unknown-0xDF" },
13600   { 0xE0, "unknown-0xE0" },
13601   { 0xE1, "unknown-0xE1" },
13602   { 0xE2, "unknown-0xE2" },
13603   { 0xE3, "unknown-0xE3" },
13604   { 0xE4, "unknown-0xE4" },
13605   { 0xE5, "unknown-0xE5" },
13606   { 0xE6, "unknown-0xE6" },
13607   { 0xE7, "unknown-0xE7" },
13608   { 0xE8, "unknown-0xE8" },
13609   { 0xE9, "unknown-0xE9" },
13610   { 0xEA, "unknown-0xEA" },
13611   { 0xEB, "unknown-0xEB" },
13612   { 0xEC, "unknown-0xEC" },
13613   { 0xED, "unknown-0xED" },
13614   { 0xEE, "unknown-0xEE" },
13615   { 0xEF, "unknown-0xEF" },
13616   { 0xF0, "unknown-0xF0" },
13617   { 0xF1, "unknown-0xF1" },
13618   { 0xF2, "unknown-0xF2" },
13619   { 0xF3, "unknown-0xF3" },
13620   { 0xF4, "unknown-0xF4" },
13621   { 0xF5, "unknown-0xF5" },
13622   { 0xF6, "unknown-0xF6" },
13623   { 0xF7, "unknown-0xF7" },
13624   { 0xF8, "unknown-0xF8" },
13625   { 0xF9, "unknown-0xF9" },
13626   { 0xFA, "unknown-0xFA" },
13627   { 0xFB, "unknown-0xFB" },
13628   { 0xFC, "unknown-0xFC" },
13629   { 0xFD, "unknown-0xFD" },
13630   { 0xFE, "SMBinvalid" },
13631   { 0xFF, "unknown-0xFF" },
13632   { 0x00, NULL },
13633 };
13634
13635 static char *decode_smb_name(unsigned char cmd)
13636 {
13637   return(smb_cmd_vals[cmd].strptr);
13638 }
13639  
13640
13641
13642 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13643  * Everything TVBUFFIFIED above this line
13644  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13645
13646
13647 static void
13648 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
13649 {
13650         conv_tables_t *ct = ctarg;
13651
13652         if (ct->unmatched)
13653                 g_hash_table_destroy(ct->unmatched);
13654         if (ct->matched)
13655                 g_hash_table_destroy(ct->matched);
13656         if (ct->dcerpc_fid_to_frame)
13657                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
13658         if (ct->tid_service)
13659                 g_hash_table_destroy(ct->tid_service);
13660 }
13661
13662 static void
13663 smb_init_protocol(void)
13664 {
13665         if (smb_saved_info_key_chunk)
13666                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
13667         if (smb_saved_info_chunk)
13668                 g_mem_chunk_destroy(smb_saved_info_chunk);
13669         if (smb_nt_transact_info_chunk)
13670                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
13671         if (smb_transact2_info_chunk)
13672                 g_mem_chunk_destroy(smb_transact2_info_chunk);
13673         if (smb_transact_info_chunk)
13674                 g_mem_chunk_destroy(smb_transact_info_chunk);
13675
13676         /*
13677          * Free the hash tables attached to the conversation table
13678          * structures, and then free the list of conversation table
13679          * data structures (which doesn't free the data structures
13680          * themselves; that's done by destroying the chunk from
13681          * which they were allocated).
13682          */
13683         if (conv_tables) {
13684                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
13685                 g_slist_free(conv_tables);
13686                 conv_tables = NULL;
13687         }
13688
13689         /*
13690          * Now destroy the chunk from which the conversation table
13691          * structures were allocated.
13692          */
13693         if (conv_tables_chunk)
13694                 g_mem_chunk_destroy(conv_tables_chunk);
13695
13696         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
13697             sizeof(smb_saved_info_t),
13698             smb_saved_info_init_count * sizeof(smb_saved_info_t),
13699             G_ALLOC_ONLY);
13700         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
13701             sizeof(smb_saved_info_key_t),
13702             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
13703             G_ALLOC_ONLY);
13704         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
13705             sizeof(smb_nt_transact_info_t),
13706             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
13707             G_ALLOC_ONLY);
13708         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
13709             sizeof(smb_transact2_info_t),
13710             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
13711             G_ALLOC_ONLY);
13712         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
13713             sizeof(smb_transact_info_t),
13714             smb_transact_info_init_count * sizeof(smb_transact_info_t),
13715             G_ALLOC_ONLY);
13716         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
13717             sizeof(conv_tables_t),
13718             conv_tables_count * sizeof(conv_tables_t),
13719             G_ALLOC_ONLY);
13720 }
13721
13722 /* Max string length for displaying Unicode strings.  */
13723 #define MAX_UNICODE_STR_LEN     256
13724
13725
13726 /* Turn a little-endian Unicode '\0'-terminated string into a string we
13727    can display.
13728    XXX - for now, we just handle the ISO 8859-1 characters.
13729    If exactlen==TRUE then us_lenp contains the exact len of the string in
13730    bytes. It might not be null terminated !
13731    bc specifies the number of bytes in the byte parameters; Windows 2000,
13732    at least, appears, in some cases, to put only 1 byte of 0 at the end
13733    of a Unicode string if the byte count
13734 */
13735 static gchar *
13736 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
13737                    guint16 bc)
13738 {
13739   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
13740   static gchar *cur;
13741   gchar        *p;
13742   guint16       uchar;
13743   int           len;
13744   int           us_len;
13745   int           overflow = 0;
13746
13747   if (cur == &str[0][0]) {
13748     cur = &str[1][0];
13749   } else if (cur == &str[1][0]) {  
13750     cur = &str[2][0];
13751   } else {  
13752     cur = &str[0][0];
13753   }
13754   p = cur;
13755   len = MAX_UNICODE_STR_LEN;
13756   us_len = 0;
13757   for (;;) {
13758     if (bc == 0)
13759       break;
13760     if (bc == 1) {
13761       /* XXX - explain this */
13762       if (!exactlen)
13763         us_len += 1;    /* this is a one-byte null terminator */
13764       break;
13765     }
13766     uchar = tvb_get_letohs(tvb, offset);
13767     if (uchar == 0) {
13768       us_len += 2;      /* this is a two-byte null terminator */
13769       break;
13770     }
13771     if (len > 0) {
13772       if ((uchar & 0xFF00) == 0)
13773         *p++ = uchar;   /* ISO 8859-1 */
13774       else
13775         *p++ = '?';     /* not 8859-1 */
13776       len--;
13777     } else
13778       overflow = 1;
13779     offset += 2;
13780     bc -= 2;
13781     us_len += 2;
13782     if(exactlen){
13783       if(us_len>= *us_lenp){
13784         break;
13785       }
13786     }
13787   }
13788   if (overflow) {
13789     /* Note that we're not showing the full string.  */
13790     *p++ = '.';
13791     *p++ = '.';
13792     *p++ = '.';
13793   }
13794   *p = '\0';
13795   *us_lenp = us_len;
13796   return cur;
13797 }
13798  
13799
13800 /* nopad == TRUE : Do not add any padding before this string
13801  * exactlen == TRUE : len contains the exact len of the string in bytes.
13802  * bc: pointer to variable with amount of data left in the byte parameters
13803  *   region
13804  */
13805 static const gchar *
13806 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
13807     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
13808     guint16 *bcp)
13809 {
13810   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
13811   static gchar *cur;
13812   const gchar *string;
13813   int string_len;
13814   smb_info_t *si;
13815   unsigned int copylen;
13816
13817   if (*bcp == 0) {
13818     /* Not enough data in buffer */
13819     return NULL;
13820   }
13821   si = pinfo->private_data;
13822   if (si->unicode) {
13823     if ((!nopad) && (*offsetp % 2)) {
13824       /*
13825        * XXX - this should be an offset relative to the beginning of the SMB,
13826        * not an offset relative to the beginning of the frame; if the stuff
13827        * before the SMB has an odd number of bytes, an offset relative to
13828        * the beginning of the frame will give the wrong answer.
13829        */
13830       (*offsetp)++;   /* Looks like a pad byte there sometimes */
13831       (*bcp)--;
13832       if (*bcp == 0) {
13833         /* Not enough data in buffer */
13834         return NULL;
13835       }
13836     }
13837     if(exactlen){
13838       string_len = *len;
13839     }
13840     string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
13841   } else {
13842     if(exactlen){
13843       /*
13844        * The string we return must be null-terminated.
13845        */
13846       if (cur == &str[0][0]) {
13847         cur = &str[1][0];
13848       } else if (cur == &str[1][0]) {  
13849         cur = &str[2][0];
13850       } else {  
13851         cur = &str[0][0];
13852       }
13853       copylen = *len;
13854       if (copylen > MAX_UNICODE_STR_LEN)
13855         copylen = MAX_UNICODE_STR_LEN;
13856       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
13857       cur[copylen] = '\0';
13858       if (copylen > MAX_UNICODE_STR_LEN)
13859         strcat(cur, "...");
13860       string_len = *len;
13861       string = cur;
13862     } else {
13863       string_len = tvb_strsize(tvb, *offsetp);
13864       string = tvb_get_ptr(tvb, *offsetp, string_len);
13865     }
13866   }
13867   *len = string_len;
13868   return string;
13869 }
13870
13871
13872
13873 static const value_string errcls_types[] = {
13874   { SMB_SUCCESS, "Success"},
13875   { SMB_ERRDOS, "DOS Error"},
13876   { SMB_ERRSRV, "Server Error"},
13877   { SMB_ERRHRD, "Hardware Error"},
13878   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
13879   { 0, NULL }
13880 };
13881
13882 const value_string DOS_errors[] = {
13883   {0, "Success"},
13884   {SMBE_insufficientbuffer, "Insufficient buffer"},
13885   {SMBE_badfunc, "Invalid function (or system call)"},
13886   {SMBE_badfile, "File not found (pathname error)"},
13887   {SMBE_badpath, "Directory not found"},
13888   {SMBE_nofids, "Too many open files"},
13889   {SMBE_noaccess, "Access denied"},
13890   {SMBE_badfid, "Invalid fid"},
13891   {SMBE_nomem,  "Out of memory"},
13892   {SMBE_badmem, "Invalid memory block address"},
13893   {SMBE_badenv, "Invalid environment"},
13894   {SMBE_badaccess, "Invalid open mode"},
13895   {SMBE_baddata, "Invalid data (only from ioctl call)"},
13896   {SMBE_res, "Reserved error code?"}, 
13897   {SMBE_baddrive, "Invalid drive"},
13898   {SMBE_remcd, "Attempt to delete current directory"},
13899   {SMBE_diffdevice, "Rename/move across different filesystems"},
13900   {SMBE_nofiles, "No more files found in file search"},
13901   {SMBE_badshare, "Share mode on file conflict with open mode"},
13902   {SMBE_lock, "Lock request conflicts with existing lock"},
13903   {SMBE_unsup, "Request unsupported, returned by Win 95"},
13904   {SMBE_nosuchshare, "Requested share does not exist"},
13905   {SMBE_filexists, "File in operation already exists"},
13906   {SMBE_cannotopen, "Cannot open the file specified"},
13907   {SMBE_unknownlevel, "Unknown info level"},
13908   {SMBE_invalidname, "Invalid name"},
13909   {SMBE_badpipe, "Named pipe invalid"},
13910   {SMBE_pipebusy, "All instances of pipe are busy"},
13911   {SMBE_pipeclosing, "Named pipe close in progress"},
13912   {SMBE_notconnected, "No process on other end of named pipe"},
13913   {SMBE_moredata, "More data to be returned"},
13914   {SMBE_baddirectory,  "Invalid directory name in a path."},
13915   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
13916   {SMBE_eas_nsup, "Extended attributes not supported"},
13917   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
13918   {SMBE_unknownipc, "Unknown IPC Operation"},
13919   {SMBE_noipc, "Don't support ipc"},
13920   {SMBE_alreadyexists, "File already exists"},
13921   {SMBE_unknownprinterdriver, "Unknown printer driver"},
13922   {SMBE_invalidprintername, "Invalid printer name"},
13923   {SMBE_printeralreadyexists, "Printer already exists"},
13924   {SMBE_invaliddatatype, "Invalid data type"},
13925   {SMBE_invalidenvironment, "Invalid environment"},
13926   {SMBE_printerdriverinuse, "Printer driver in use"},
13927   {SMBE_invalidparam, "Invalid parameter"},
13928   {SMBE_invalidformsize, "Invalid form size"},
13929   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
13930   {SMBE_invalidowner, "Invalid owner"},
13931   {0, NULL}
13932   };
13933
13934 /* Error codes for the ERRSRV class */
13935
13936 static const value_string SRV_errors[] = {
13937   {SMBE_error, "Non specific error code"},
13938   {SMBE_badpw, "Bad password"},
13939   {SMBE_badtype, "Reserved"},
13940   {SMBE_access, "No permissions to perform the requested operation"},
13941   {SMBE_invnid, "TID invalid"},
13942   {SMBE_invnetname, "Invalid network name. Service not found"},
13943   {SMBE_invdevice, "Invalid device"},
13944   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
13945   {SMBE_qfull, "Print queue full"},
13946   {SMBE_qtoobig, "Queued item too big"},
13947   {SMBE_qeof, "EOF on print queue dump"},
13948   {SMBE_invpfid, "Invalid print file in smb_fid"},
13949   {SMBE_smbcmd, "Unrecognised command"},
13950   {SMBE_srverror, "SMB server internal error"},
13951   {SMBE_filespecs, "Fid and pathname invalid combination"},
13952   {SMBE_badlink, "Bad link in request ???"},
13953   {SMBE_badpermits, "Access specified for a file is not valid"},
13954   {SMBE_badpid, "Bad process id in request"},
13955   {SMBE_setattrmode, "Attribute mode invalid"},
13956   {SMBE_paused, "Message server paused"},
13957   {SMBE_msgoff, "Not receiving messages"},
13958   {SMBE_noroom, "No room for message"},
13959   {SMBE_rmuns, "Too many remote usernames"},
13960   {SMBE_timeout, "Operation timed out"},
13961   {SMBE_noresource, "No resources currently available for request."},
13962   {SMBE_toomanyuids, "Too many userids"},
13963   {SMBE_baduid, "Bad userid"},
13964   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
13965   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
13966   {SMBE_contMPX, "Resume MPX mode"},
13967   {SMBE_badPW, "Bad Password???"},
13968   {SMBE_nosupport, "Operation not supported"},
13969   { 0, NULL}
13970 };
13971
13972 /* Error codes for the ERRHRD class */
13973
13974 static const value_string HRD_errors[] = {
13975   {SMBE_nowrite, "Read only media"},
13976   {SMBE_badunit, "Unknown device"},
13977   {SMBE_notready, "Drive not ready"},
13978   {SMBE_badcmd, "Unknown command"},
13979   {SMBE_data, "Data (CRC) error"},
13980   {SMBE_badreq, "Bad request structure length"},
13981   {SMBE_seek, "Seek error"},
13982   {SMBE_badmedia, "Unknown media type"},
13983   {SMBE_badsector, "Sector not found"},
13984   {SMBE_nopaper, "Printer out of paper"},
13985   {SMBE_write, "Write fault"},
13986   {SMBE_read, "Read fault"},
13987   {SMBE_general, "General failure"},
13988   {SMBE_badshare, "A open conflicts with an existing open"},
13989   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
13990   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
13991   {SMBE_FCBunavail, "No FCBs are available to process request"},
13992   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
13993   {SMBE_diskfull, "Disk full???"},
13994   {0, NULL}
13995 };
13996
13997 static char *decode_smb_error(guint8 errcls, guint16 errcode)
13998 {
13999
14000   switch (errcls) {
14001
14002   case SMB_SUCCESS:
14003
14004     return("No Error");   /* No error ??? */
14005     break;
14006
14007   case SMB_ERRDOS:
14008
14009     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14010     break;
14011
14012   case SMB_ERRSRV:
14013
14014     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14015     break;
14016
14017   case SMB_ERRHRD:
14018
14019     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14020     break;
14021
14022   default:
14023
14024     return("Unknown error class!");
14025
14026   }
14027
14028 }
14029
14030
14031 /* These are the MS country codes from
14032
14033         http://www.unicode.org/unicode/onlinedat/countries.html
14034
14035    For countries that share the same number, I choose to use only the
14036    name of the largest country. Apologies for this. If this offends you,
14037    here is the table to change that.
14038
14039    This also includes the code of 0 for "Default", which isn't in
14040    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14041    header file.  Presumably it means "don't override the setting
14042    on the user's machine".
14043
14044    Future versions of Microsoft's "winnls.h" header file might include
14045    additional codes; the current version matches the Unicode Consortium's
14046    table.
14047 */
14048 const value_string ms_country_codes[] = {
14049         {  0,   "Default"},
14050         {  1,   "USA"},
14051         {  2,   "Canada"},
14052         {  7,   "Russia"},
14053         { 20,   "Egypt"},
14054         { 27,   "South Africa"},
14055         { 30,   "Greece"},
14056         { 31,   "Netherlands"},
14057         { 32,   "Belgium"},
14058         { 33,   "France"},
14059         { 34,   "Spain"},
14060         { 36,   "Hungary"},
14061         { 39,   "Italy"},
14062         { 40,   "Romania"},
14063         { 41,   "Switzerland"},
14064         { 43,   "Austria"},
14065         { 44,   "United Kingdom"},
14066         { 45,   "Denmark"},
14067         { 46,   "Sweden"},
14068         { 47,   "Norway"},
14069         { 48,   "Poland"},
14070         { 49,   "Germany"},
14071         { 51,   "Peru"},
14072         { 52,   "Mexico"},
14073         { 54,   "Argentina"},
14074         { 55,   "Brazil"},
14075         { 56,   "Chile"},
14076         { 57,   "Colombia"},
14077         { 58,   "Venezuela"},
14078         { 60,   "Malaysia"},
14079         { 61,   "Australia"},
14080         { 62,   "Indonesia"},
14081         { 63,   "Philippines"},
14082         { 64,   "New Zealand"},
14083         { 65,   "Singapore"},
14084         { 66,   "Thailand"},
14085         { 81,   "Japan"},
14086         { 82,   "South Korea"},
14087         { 84,   "Viet Nam"},
14088         { 86,   "China"},
14089         { 90,   "Turkey"},
14090         { 91,   "India"},
14091         { 92,   "Pakistan"},
14092         {212,   "Morocco"},
14093         {213,   "Algeria"},
14094         {216,   "Tunisia"},
14095         {218,   "Libya"},
14096         {254,   "Kenya"},
14097         {263,   "Zimbabwe"},
14098         {298,   "Faroe Islands"},
14099         {351,   "Portugal"},
14100         {352,   "Luxembourg"},
14101         {353,   "Ireland"},
14102         {354,   "Iceland"},
14103         {355,   "Albania"},
14104         {358,   "Finland"},
14105         {359,   "Bulgaria"},
14106         {370,   "Lithuania"},
14107         {371,   "Latvia"},
14108         {372,   "Estonia"},
14109         {374,   "Armenia"},
14110         {375,   "Belarus"},
14111         {380,   "Ukraine"},
14112         {381,   "Serbia"},
14113         {385,   "Croatia"},
14114         {386,   "Slovenia"},
14115         {389,   "Macedonia"},
14116         {420,   "Czech Republic"},
14117         {421,   "Slovak Republic"},
14118         {501,   "Belize"},
14119         {502,   "Guatemala"},
14120         {503,   "El Salvador"},
14121         {504,   "Honduras"},
14122         {505,   "Nicaragua"},
14123         {506,   "Costa Rica"},
14124         {507,   "Panama"},
14125         {591,   "Bolivia"},
14126         {593,   "Ecuador"},
14127         {595,   "Paraguay"},
14128         {598,   "Uruguay"},
14129         {673,   "Brunei Darussalam"},
14130         {852,   "Hong Kong"},
14131         {853,   "Macau"},
14132         {886,   "Taiwan"},
14133         {960,   "Maldives"},
14134         {961,   "Lebanon"},
14135         {962,   "Jordan"},
14136         {963,   "Syria"},
14137         {964,   "Iraq"},
14138         {965,   "Kuwait"},
14139         {966,   "Saudi Arabia"},
14140         {967,   "Yemen"},
14141         {968,   "Oman"},
14142         {971,   "United Arab Emirates"},
14143         {972,   "Israel"},
14144         {973,   "Bahrain"},
14145         {974,   "Qatar"},
14146         {976,   "Mongolia"},
14147         {981,   "Iran"},
14148         {994,   "Azerbaijan"},
14149         {995,   "Georgia"},
14150         {996,   "Kyrgyzstan"},
14151
14152         {0,     NULL}
14153 };
14154
14155 /*
14156  * NT error codes.
14157  *
14158  * From
14159  *
14160  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14161  */
14162 const value_string NT_errors[] = {
14163   { 0x00000000, "STATUS_SUCCESS" },
14164   { 0x00000000, "STATUS_WAIT_0" },
14165   { 0x00000001, "STATUS_WAIT_1" },
14166   { 0x00000002, "STATUS_WAIT_2" },
14167   { 0x00000003, "STATUS_WAIT_3" },
14168   { 0x0000003F, "STATUS_WAIT_63" },
14169   { 0x00000080, "STATUS_ABANDONED" },
14170   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14171   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14172   { 0x000000C0, "STATUS_USER_APC" },
14173   { 0x00000100, "STATUS_KERNEL_APC" },
14174   { 0x00000101, "STATUS_ALERTED" },
14175   { 0x00000102, "STATUS_TIMEOUT" },
14176   { 0x00000103, "STATUS_PENDING" },
14177   { 0x00000104, "STATUS_REPARSE" },
14178   { 0x00000105, "STATUS_MORE_ENTRIES" },
14179   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14180   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14181   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14182   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14183   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14184   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14185   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14186   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14187   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14188   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14189   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14190   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14191   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14192   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14193   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14194   { 0x00000116, "STATUS_CRASH_DUMP" },
14195   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14196   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14197   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14198   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14199   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14200   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14201   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14202   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14203   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14204   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14205   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14206   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14207   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14208   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14209   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14210   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14211   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14212   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14213   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14214   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14215   { 0x40000012, "STATUS_EVENT_DONE" },
14216   { 0x40000013, "STATUS_EVENT_PENDING" },
14217   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14218   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14219   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14220   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14221   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14222   { 0x40000019, "STATUS_WAS_LOCKED" },
14223   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14224   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14225   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14226   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14227   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14228   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14229   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14230   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14231   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14232   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14233   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14234   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14235   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14236   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14237   { 0x80000003, "STATUS_BREAKPOINT" },
14238   { 0x80000004, "STATUS_SINGLE_STEP" },
14239   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14240   { 0x80000006, "STATUS_NO_MORE_FILES" },
14241   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14242   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14243   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14244   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14245   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14246   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14247   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14248   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14249   { 0x80000011, "STATUS_DEVICE_BUSY" },
14250   { 0x80000012, "STATUS_NO_MORE_EAS" },
14251   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14252   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14253   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14254   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14255   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14256   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14257   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14258   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14259   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14260   { 0x8000001D, "STATUS_BUS_RESET" },
14261   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14262   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14263   { 0x80000020, "STATUS_MEDIA_CHECK" },
14264   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14265   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14266   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14267   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14268   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14269   { 0x80000026, "STATUS_LONGJUMP" },
14270   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14271   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14272   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14273   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14274   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14275   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14276   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14277   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14278   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14279   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14280   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14281   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14282   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14283   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14284   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14285   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14286   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14287   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14288   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14289   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14290   { 0xC000000B, "STATUS_INVALID_CID" },
14291   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14292   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14293   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14294   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14295   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14296   { 0xC0000011, "STATUS_END_OF_FILE" },
14297   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14298   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14299   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14300   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14301   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14302   { 0xC0000017, "STATUS_NO_MEMORY" },
14303   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14304   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14305   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14306   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14307   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14308   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14309   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14310   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14311   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14312   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14313   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14314   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14315   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14316   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14317   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14318   { 0xC0000027, "STATUS_UNWIND" },
14319   { 0xC0000028, "STATUS_BAD_STACK" },
14320   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14321   { 0xC000002A, "STATUS_NOT_LOCKED" },
14322   { 0xC000002B, "STATUS_PARITY_ERROR" },
14323   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14324   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14325   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14326   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14327   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14328   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14329   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14330   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14331   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14332   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14333   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14334   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14335   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14336   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14337   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14338   { 0xC000003C, "STATUS_DATA_OVERRUN" },
14339   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
14340   { 0xC000003E, "STATUS_DATA_ERROR" },
14341   { 0xC000003F, "STATUS_CRC_ERROR" },
14342   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
14343   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
14344   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
14345   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
14346   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
14347   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
14348   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
14349   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
14350   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
14351   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
14352   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
14353   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
14354   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
14355   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
14356   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
14357   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
14358   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
14359   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
14360   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
14361   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
14362   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
14363   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
14364   { 0xC0000056, "STATUS_DELETE_PENDING" },
14365   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
14366   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
14367   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
14368   { 0xC000005A, "STATUS_INVALID_OWNER" },
14369   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
14370   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
14371   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
14372   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
14373   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
14374   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
14375   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
14376   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
14377   { 0xC0000063, "STATUS_USER_EXISTS" },
14378   { 0xC0000064, "STATUS_NO_SUCH_USER" },
14379   { 0xC0000065, "STATUS_GROUP_EXISTS" },
14380   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
14381   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
14382   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
14383   { 0xC0000069, "STATUS_LAST_ADMIN" },
14384   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
14385   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
14386   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
14387   { 0xC000006D, "STATUS_LOGON_FAILURE" },
14388   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
14389   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
14390   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
14391   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
14392   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
14393   { 0xC0000073, "STATUS_NONE_MAPPED" },
14394   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
14395   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
14396   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
14397   { 0xC0000077, "STATUS_INVALID_ACL" },
14398   { 0xC0000078, "STATUS_INVALID_SID" },
14399   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
14400   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
14401   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
14402   { 0xC000007C, "STATUS_NO_TOKEN" },
14403   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
14404   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
14405   { 0xC000007F, "STATUS_DISK_FULL" },
14406   { 0xC0000080, "STATUS_SERVER_DISABLED" },
14407   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
14408   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
14409   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
14410   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
14411   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
14412   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
14413   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
14414   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
14415   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
14416   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
14417   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
14418   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
14419   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
14420   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
14421   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
14422   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
14423   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
14424   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
14425   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
14426   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
14427   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
14428   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
14429   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
14430   { 0xC0000098, "STATUS_FILE_INVALID" },
14431   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
14432   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
14433   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
14434   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
14435   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
14436   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
14437   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
14438   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
14439   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
14440   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
14441   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
14442   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
14443   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
14444   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
14445   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
14446   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
14447   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
14448   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
14449   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
14450   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
14451   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
14452   { 0xC00000AE, "STATUS_PIPE_BUSY" },
14453   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
14454   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
14455   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
14456   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
14457   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
14458   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
14459   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
14460   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
14461   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
14462   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
14463   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
14464   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
14465   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
14466   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
14467   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
14468   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
14469   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
14470   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
14471   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
14472   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
14473   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
14474   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
14475   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
14476   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
14477   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
14478   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
14479   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
14480   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
14481   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
14482   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
14483   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
14484   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
14485   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
14486   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
14487   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
14488   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
14489   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
14490   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
14491   { 0xC00000D5, "STATUS_FILE_RENAMED" },
14492   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
14493   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
14494   { 0xC00000D8, "STATUS_CANT_WAIT" },
14495   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
14496   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
14497   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
14498   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
14499   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
14500   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
14501   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
14502   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
14503   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
14504   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
14505   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
14506   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
14507   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
14508   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
14509   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
14510   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
14511   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
14512   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
14513   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
14514   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
14515   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
14516   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
14517   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
14518   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
14519   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
14520   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
14521   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
14522   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
14523   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
14524   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
14525   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
14526   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
14527   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
14528   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
14529   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
14530   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
14531   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
14532   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
14533   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
14534   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
14535   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
14536   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
14537   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
14538   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
14539   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
14540   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
14541   { 0xC0000107, "STATUS_FILES_OPEN" },
14542   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
14543   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
14544   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
14545   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
14546   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
14547   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
14548   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
14549   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
14550   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
14551   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
14552   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
14553   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
14554   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
14555   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
14556   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
14557   { 0xC0000117, "STATUS_NO_LDT" },
14558   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
14559   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
14560   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
14561   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
14562   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
14563   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
14564   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
14565   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
14566   { 0xC0000120, "STATUS_CANCELLED" },
14567   { 0xC0000121, "STATUS_CANNOT_DELETE" },
14568   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
14569   { 0xC0000123, "STATUS_FILE_DELETED" },
14570   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
14571   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
14572   { 0xC0000126, "STATUS_SPECIAL_USER" },
14573   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
14574   { 0xC0000128, "STATUS_FILE_CLOSED" },
14575   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
14576   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
14577   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
14578   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
14579   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
14580   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
14581   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
14582   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
14583   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
14584   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
14585   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
14586   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
14587   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
14588   { 0xC0000136, "STATUS_OPEN_FAILED" },
14589   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
14590   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
14591   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
14592   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
14593   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
14594   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
14595   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
14596   { 0xC000013E, "STATUS_LINK_FAILED" },
14597   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
14598   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
14599   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
14600   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
14601   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
14602   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
14603   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
14604   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
14605   { 0xC0000147, "STATUS_NO_PAGEFILE" },
14606   { 0xC0000148, "STATUS_INVALID_LEVEL" },
14607   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
14608   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
14609   { 0xC000014B, "STATUS_PIPE_BROKEN" },
14610   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
14611   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
14612   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
14613   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
14614   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
14615   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
14616   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
14617   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
14618   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
14619   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
14620   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
14621   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
14622   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
14623   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
14624   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
14625   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
14626   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
14627   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
14628   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
14629   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
14630   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
14631   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
14632   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
14633   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
14634   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
14635   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
14636   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
14637   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
14638   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
14639   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
14640   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
14641   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
14642   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
14643   { 0xC000016D, "STATUS_FT_ORPHANING" },
14644   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
14645   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
14646   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
14647   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
14648   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
14649   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
14650   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
14651   { 0xC0000178, "STATUS_NO_MEDIA" },
14652   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
14653   { 0xC000017B, "STATUS_INVALID_MEMBER" },
14654   { 0xC000017C, "STATUS_KEY_DELETED" },
14655   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
14656   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
14657   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
14658   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
14659   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
14660   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
14661   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
14662   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
14663   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
14664   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
14665   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
14666   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
14667   { 0xC0000189, "STATUS_TOO_LATE" },
14668   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
14669   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
14670   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
14671   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
14672   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
14673   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
14674   { 0xC0000190, "STATUS_TRUST_FAILURE" },
14675   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
14676   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
14677   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
14678   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
14679   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
14680   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
14681   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
14682   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
14683   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
14684   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
14685   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
14686   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
14687   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
14688   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
14689   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
14690   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
14691   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
14692   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
14693   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
14694   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
14695   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
14696   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
14697   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
14698   { 0xC000020D, "STATUS_CONNECTION_RESET" },
14699   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
14700   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
14701   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
14702   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
14703   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
14704   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
14705   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
14706   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
14707   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
14708   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
14709   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
14710   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
14711   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
14712   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
14713   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
14714   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
14715   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
14716   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
14717   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
14718   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
14719   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
14720   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
14721   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
14722   { 0xC0000225, "STATUS_NOT_FOUND" },
14723   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
14724   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
14725   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
14726   { 0xC0000229, "STATUS_FAIL_CHECK" },
14727   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
14728   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
14729   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
14730   { 0xC000022D, "STATUS_RETRY" },
14731   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
14732   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
14733   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
14734   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
14735   { 0xC0000232, "STATUS_INVALID_VARIANT" },
14736   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
14737   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
14738   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
14739   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
14740   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
14741   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
14742   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
14743   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
14744   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
14745   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
14746   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
14747   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
14748   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
14749   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
14750   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
14751   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
14752   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
14753   { 0xC0000244, "STATUS_AUDIT_FAILED" },
14754   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
14755   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
14756   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
14757   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
14758   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
14759   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
14760   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
14761   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
14762   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
14763   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
14764   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
14765   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
14766   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
14767   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
14768   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
14769   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
14770   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
14771   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
14772   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
14773   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
14774   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
14775   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
14776   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
14777   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
14778   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
14779   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
14780   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
14781   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
14782   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
14783   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
14784   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
14785   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
14786   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
14787   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
14788   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
14789   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
14790   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
14791   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
14792   { 0xC0000272, "STATUS_NO_MATCH" },
14793   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
14794   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
14795   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
14796   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
14797   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
14798   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
14799   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
14800   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
14801   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
14802   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
14803   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
14804   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
14805   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
14806   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
14807   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
14808   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
14809   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
14810   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
14811   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
14812   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
14813   { 0xC000028E, "STATUS_NO_EFS" },
14814   { 0xC000028F, "STATUS_WRONG_EFS" },
14815   { 0xC0000290, "STATUS_NO_USER_KEYS" },
14816   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
14817   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
14818   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
14819   { 0x40000294, "STATUS_WAKE_SYSTEM" },
14820   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
14821   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
14822   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
14823   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
14824   { 0xC0000299, "STATUS_SHARED_POLICY" },
14825   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
14826   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
14827   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
14828   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
14829   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
14830   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
14831   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
14832   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
14833   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
14834   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
14835   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
14836   { 0xC00002A5, "STATUS_DS_BUSY" },
14837   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
14838   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
14839   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
14840   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
14841   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
14842   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
14843   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
14844   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
14845   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
14846   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
14847   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
14848   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
14849   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
14850   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
14851   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
14852   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
14853   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
14854   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
14855   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
14856   { 0xC00002B9, "STATUS_NOINTERFACE" },
14857   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
14858   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
14859   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
14860   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
14861   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
14862   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
14863   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
14864   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
14865   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
14866   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
14867   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
14868   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
14869   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
14870   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
14871   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
14872   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
14873   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
14874   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
14875   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
14876   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
14877   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
14878   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
14879   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
14880   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
14881   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
14882   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
14883   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
14884   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
14885   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
14886   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
14887   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
14888   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
14889   { 0xC00002E1, "STATUS_DS_CANT_START" },
14890   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
14891   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
14892   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
14893   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
14894   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
14895   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
14896   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
14897   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
14898   { 0xC0009898, "STATUS_WOW_ASSERTION" },
14899   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
14900   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
14901   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
14902   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
14903   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
14904   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
14905   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
14906   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
14907   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
14908   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
14909   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
14910   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
14911   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
14912   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
14913   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
14914   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
14915   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
14916   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
14917   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
14918   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
14919   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
14920   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
14921   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
14922   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
14923   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
14924   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
14925   { 0xC002001B, "RPC_NT_CALL_FAILED" },
14926   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
14927   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
14928   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
14929   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
14930   { 0xC0020022, "RPC_NT_INVALID_TAG" },
14931   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
14932   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
14933   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
14934   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
14935   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
14936   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
14937   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
14938   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
14939   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
14940   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
14941   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
14942   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
14943   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
14944   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
14945   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
14946   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
14947   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
14948   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
14949   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
14950   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
14951   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
14952   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
14953   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
14954   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
14955   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
14956   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
14957   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
14958   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
14959   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
14960   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
14961   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
14962   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
14963   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
14964   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
14965   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
14966   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
14967   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
14968   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
14969   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
14970   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
14971   { 0xC002100A, "RPC_P_SEND_FAILED" },
14972   { 0xC002100B, "RPC_P_TIMEOUT" },
14973   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
14974   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
14975   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
14976   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
14977   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
14978   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
14979   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
14980   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
14981   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
14982   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
14983   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
14984   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
14985   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
14986   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
14987   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
14988   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
14989   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
14990   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
14991   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
14992   { 0xC002004C, "EPT_NT_CANT_CREATE" },
14993   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
14994   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
14995   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
14996   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
14997   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
14998   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
14999   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15000   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15001   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15002   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15003   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15004   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15005   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15006   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15007   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15008   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15009   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15010   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15011   { 0,          NULL }
15012 };
15013
15014
15015
15016 static const true_false_string tfs_smb_flags_lock = {
15017         "Lock&Read, Write&Unlock are supported",
15018         "Lock&Read, Write&Unlock are not supported"
15019 };
15020 static const true_false_string tfs_smb_flags_receive_buffer = {
15021         "Receive buffer has been posted",
15022         "Receive buffer has not been posted"
15023 };
15024 static const true_false_string tfs_smb_flags_caseless = {
15025         "Path names are caseless",
15026         "Path names are case sensitive"
15027 };
15028 static const true_false_string tfs_smb_flags_canon = {
15029         "Pathnames are canonicalized",
15030         "Pathnames are not canonicalized"
15031 };
15032 static const true_false_string tfs_smb_flags_oplock = {
15033         "OpLock requested/granted",
15034         "OpLock not requested/granted"
15035 };
15036 static const true_false_string tfs_smb_flags_notify = {
15037         "Notify client on all modifications",
15038         "Notify client only on open"
15039 };
15040 static const true_false_string tfs_smb_flags_response = {
15041         "Message is a response to the client/redirector",
15042         "Message is a request to the server"
15043 };
15044
15045 static int
15046 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15047 {
15048         guint8 mask;
15049         proto_item *item = NULL;
15050         proto_tree *tree = NULL;
15051
15052         mask = tvb_get_guint8(tvb, offset);
15053
15054         if(parent_tree){
15055                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15056                         "Flags: 0x%02x", mask);
15057                 tree = proto_item_add_subtree(item, ett_smb_flags);
15058         }
15059         proto_tree_add_boolean(tree, hf_smb_flags_response,
15060                 tvb, offset, 1, mask);
15061         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15062                 tvb, offset, 1, mask);
15063         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15064                 tvb, offset, 1, mask);
15065         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15066                 tvb, offset, 1, mask);
15067         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15068                 tvb, offset, 1, mask);
15069         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15070                 tvb, offset, 1, mask);
15071         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15072                 tvb, offset, 1, mask);
15073         offset += 1;
15074         return offset;
15075 }
15076
15077
15078  
15079 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15080         "Long file names are allowed in the response",
15081         "Long file names are not allowed in the response"
15082 };
15083 static const true_false_string tfs_smb_flags2_ea = {
15084         "Extended attributes are supported",
15085         "Extended attributes are not supported"
15086 };
15087 static const true_false_string tfs_smb_flags2_sec_sig = {
15088         "Security signatures are supported",
15089         "Security signatures are not supported"
15090 };
15091 static const true_false_string tfs_smb_flags2_long_names_used = {
15092         "Path names in request are long file names",
15093         "Path names in request are not long file names"
15094 };
15095 static const true_false_string tfs_smb_flags2_esn = {
15096         "Extended security negotiation is supported",
15097         "Extended security negotiation is not supported"
15098 };
15099 static const true_false_string tfs_smb_flags2_dfs = {
15100         "Resolve pathnames with Dfs",
15101         "Don't resolve pathnames with Dfs"
15102 };
15103 static const true_false_string tfs_smb_flags2_roe = {
15104         "Permit reads if execute-only",
15105         "Don't permit reads if execute-only"
15106 };
15107 static const true_false_string tfs_smb_flags2_nt_error = {
15108         "Error codes are NT error codes",
15109         "Error codes are DOS error codes"
15110 };
15111 static const true_false_string tfs_smb_flags2_string = {
15112         "Strings are Unicode",
15113         "Strings are ASCII"
15114 };
15115 static int
15116 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15117 {
15118         guint16 mask;
15119         proto_item *item = NULL;
15120         proto_tree *tree = NULL;
15121
15122         mask = tvb_get_letohs(tvb, offset);
15123
15124         if(parent_tree){
15125                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15126                         "Flags2: 0x%04x", mask);
15127                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15128         }
15129
15130         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15131                 tvb, offset, 2, mask);
15132         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15133                 tvb, offset, 2, mask);
15134         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15135                 tvb, offset, 2, mask);
15136         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15137                 tvb, offset, 2, mask);
15138         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15139                 tvb, offset, 2, mask);
15140         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15141                 tvb, offset, 2, mask);
15142         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15143                 tvb, offset, 2, mask);
15144         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15145                 tvb, offset, 2, mask);
15146         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15147                 tvb, offset, 2, mask);
15148
15149         offset += 2;
15150         return offset;
15151 }
15152
15153
15154
15155 #define SMB_FLAGS_DIRN 0x80
15156
15157
15158 static gboolean
15159 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15160 {
15161         int offset = 0;
15162         proto_item *item = NULL, *hitem = NULL;
15163         proto_tree *tree = NULL, *htree = NULL;
15164         guint8          flags;
15165         guint16         flags2;
15166         smb_info_t      si;
15167         smb_saved_info_t *sip = NULL;
15168         smb_saved_info_key_t key;
15169         smb_saved_info_key_t *new_key;
15170         guint32 nt_status = 0;
15171         guint8 errclass = 0;
15172         guint16 errcode = 0;
15173         guint32 pid_mid;
15174         conversation_t *conversation;
15175
15176         top_tree=parent_tree;
15177
15178         /* must check that this really is a smb packet */
15179         if (!tvb_bytes_exist(tvb, 0, 4))
15180                 return FALSE;
15181
15182         if( (tvb_get_guint8(tvb, 0) != 0xff)
15183             || (tvb_get_guint8(tvb, 1) != 'S')
15184             || (tvb_get_guint8(tvb, 2) != 'M')
15185             || (tvb_get_guint8(tvb, 3) != 'B') ){
15186                 return FALSE;
15187         }
15188          
15189         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15190                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15191         }
15192         if (check_col(pinfo->cinfo, COL_INFO)){
15193                 col_clear(pinfo->cinfo, COL_INFO);
15194         }
15195
15196         /* start off using the local variable, we will allocate a new one if we
15197            need to*/
15198         si.cmd = tvb_get_guint8(tvb, offset+4);
15199         flags = tvb_get_guint8(tvb, offset+9);
15200         si.request = !(flags&SMB_FLAGS_DIRN);
15201         flags2 = tvb_get_letohs(tvb, offset+10);
15202         if(flags2 & 0x8000){
15203                 si.unicode = TRUE; /* Mark them as Unicode */
15204         } else {
15205                 si.unicode = FALSE;
15206         }
15207         si.tid = tvb_get_letohs(tvb, offset+24);
15208         si.pid = tvb_get_letohs(tvb, offset+26);
15209         si.uid = tvb_get_letohs(tvb, offset+28);
15210         si.mid = tvb_get_letohs(tvb, offset+30);
15211         pid_mid = (si.pid << 16) | si.mid;
15212         si.info_level = -1;
15213         si.info_count = -1;
15214
15215         if (parent_tree) {
15216                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
15217                         -1, FALSE);
15218                 tree = proto_item_add_subtree(item, ett_smb);
15219
15220                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
15221                         "SMB Header");
15222
15223                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15224         }
15225
15226         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15227         offset += 4;  /* Skip the marker */
15228
15229         /* find which conversation we are part of and get the tables for that 
15230            conversation*/
15231         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15232                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15233         if(conversation){
15234                 si.ct=conversation_get_proto_data(conversation, proto_smb);
15235         } else {
15236                 /* OK this is a new conversation, we must create it
15237                    and attach appropriate data (matched and unmatched 
15238                    table for this conversation)
15239                 */
15240                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
15241                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15242                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
15243                 conv_tables = g_slist_prepend(conv_tables, si.ct);
15244                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
15245                         smb_saved_info_equal_matched);
15246                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
15247                         smb_saved_info_equal_unmatched);
15248                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
15249                         smb_saved_info_hash_unmatched, 
15250                         smb_saved_info_equal_unmatched);
15251                 si.ct->tid_service=g_hash_table_new(
15252                         smb_saved_info_hash_unmatched, 
15253                         smb_saved_info_equal_unmatched);
15254                 conversation_add_proto_data(conversation, proto_smb, si.ct);
15255         }
15256
15257         if( (si.request)
15258             &&  (si.mid==0)
15259             &&  (si.uid==0)
15260             &&  (si.pid==0)
15261             &&  (si.tid==0) ){
15262                 /* this is a broadcast SMB packet, there will not be a reply.
15263                    We dont need to do anything 
15264                 */
15265                 si.unidir = TRUE;
15266         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15267                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15268                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15269                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15270                 /* Ok, we got a special request type. This request is either
15271                    an NT Cancel or a continuation relative to a real request
15272                    in an earlier packet.  In either case, we don't expect any
15273                    responses to this packet.  For continuations, any later
15274                    responses we see really just belong to the original request.
15275                    Anyway, we want to remember this packet somehow and
15276                    remember which original request it is associated with so
15277                    we can say nice things such as "This is a Cancellation to
15278                    the request in frame x", but we don't want the
15279                    request/response matching to get messed up.
15280
15281                    The only thing we do in this case is trying to find which original
15282                    request we match with and insert an entry for this "special" 
15283                    request for later reference. We continue to reference the original
15284                    requests smb_saved_info_t but we dont touch it or change anything
15285                    in it.
15286                 */
15287
15288                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
15289
15290                 if(!pinfo->fd->flags.visited){
15291                         /* try to find which original call we match and if we 
15292                            find it add us to the matched table. Dont touch
15293                            anything else since we dont want this one to mess
15294                            up the request/response matching. We still consider
15295                            the initial call the real request and this is only
15296                            some sort of continuation.
15297                         */
15298                         /* we only check the unmatched table and assume that the
15299                            last seen MID matching ours is the right one.
15300                            This can fail but is better than nothing
15301                         */
15302                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15303                         if(sip!=NULL){
15304                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15305                                 new_key->frame = pinfo->fd->num;
15306                                 new_key->pid_mid = pid_mid;
15307                                 g_hash_table_insert(si.ct->matched, new_key,
15308                                     sip);
15309                         }
15310                 } else {
15311                         /* we have seen this packet before; check the
15312                            matching table
15313                         */
15314                         key.frame = pinfo->fd->num;
15315                         key.pid_mid = pid_mid;
15316                         sip=g_hash_table_lookup(si.ct->matched, &key);
15317                         if(sip==NULL){
15318                         /*
15319                           We didn't find it.
15320                           Too bad, unfortunately there is not really much we can
15321                           do now since this means that we never saw the initial
15322                           request.
15323                          */
15324                         }
15325                 }
15326
15327
15328                 if(sip && sip->frame_req){
15329                         switch(si.cmd){
15330                         case SMB_COM_NT_CANCEL:
15331                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
15332                                                     tvb, 0, 0, sip->frame_req);
15333                                 break;
15334                         case SMB_COM_TRANSACTION_SECONDARY:
15335                         case SMB_COM_TRANSACTION2_SECONDARY:
15336                         case SMB_COM_NT_TRANSACT_SECONDARY:
15337                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
15338                                                     tvb, 0, 0, sip->frame_req);
15339                                 break;
15340                         }
15341                 } else {
15342                         switch(si.cmd){
15343                         case SMB_COM_NT_CANCEL:
15344                                 proto_tree_add_text(htree, tvb, 0, 0,
15345                                                     "Cancellation to: <unknown frame>");
15346                                 break;
15347                         case SMB_COM_TRANSACTION_SECONDARY:
15348                         case SMB_COM_TRANSACTION2_SECONDARY:
15349                         case SMB_COM_NT_TRANSACT_SECONDARY:
15350                                 proto_tree_add_text(htree, tvb, 0, 0,
15351                                                     "Continuation to: <unknown frame>");
15352                                 break;
15353                         }
15354                 }
15355         } else { /* normal bidirectional request or response */
15356                 si.unidir = FALSE;
15357
15358                 if(!pinfo->fd->flags.visited){
15359                         /* first see if we find an unmatched smb "equal" to 
15360                            the current one 
15361                         */
15362                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15363                         if(sip!=NULL){
15364                                 gboolean cmd_match=FALSE;
15365
15366                                 /*
15367                                  * Make sure the SMB we found was the
15368                                  * same command, or a different command
15369                                  * that's another valid type of reply
15370                                  * to that command.
15371                                  */
15372                                 if(si.cmd==sip->cmd){
15373                                         cmd_match=TRUE;
15374                                 }
15375                                 else if(si.cmd==SMB_COM_NT_CANCEL){
15376                                         cmd_match=TRUE;
15377                                 }
15378                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
15379                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15380                                         cmd_match=TRUE;
15381                                 }
15382                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
15383                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15384                                         cmd_match=TRUE;
15385                                 }
15386                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
15387                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15388                                         cmd_match=TRUE;
15389                                 }
15390
15391                                 if( (si.request) || (!cmd_match) ) {
15392                                         /* If we are processing an SMB request but there was already
15393                                            another "identical" smb resuest we had not matched yet.
15394                                            This must mean that either we have a retransmission or that the
15395                                            response to the previous one was lost and the client has reused
15396                                            the MID for this conversation. In either case it's not much more
15397                                            we can do than forget the old request and concentrate on the 
15398                                            present one instead.
15399
15400                                            We also do this cleanup if we see that the cmd in the original
15401                                            request in sip->cmd is not compatible with the current cmd.
15402                                            This is to prevent matching errors such as if there were two
15403                                            SMBs of different cmds but with identical MID and PID values and
15404                                            if ethereal lost the first reply and the second request.
15405                                         */
15406                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
15407                                         sip=NULL; /* XXX should free it as well */
15408                                 } else {
15409                                         /* we have found a response to some request we have seen earlier.
15410                                            What we do now depends on whether this is the first response
15411                                            to that request we see (id frame_res==0) or not. 
15412                                         */
15413                                         if(sip->frame_res==0){
15414                                                 /* ok it is the first response we have seen to this packet */
15415                                                 sip->frame_res = pinfo->fd->num;
15416                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15417                                                 new_key->frame = sip->frame_req;
15418                                                 new_key->pid_mid = pid_mid;
15419                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15420                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15421                                                 new_key->frame = sip->frame_res;
15422                                                 new_key->pid_mid = pid_mid;
15423                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15424                                         } else {
15425                                                 /* we have already seen another response to this one, but
15426                                                    register it anyway so we see which request it matches 
15427                                                 */
15428                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15429                                                 new_key->frame = pinfo->fd->num;
15430                                                 new_key->pid_mid = pid_mid;
15431                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15432                                         }
15433                                 }
15434                         }
15435                         if(si.request){
15436                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
15437                                 sip->frame_req = pinfo->fd->num;
15438                                 sip->frame_res = 0;
15439                                 sip->flags = 0;
15440                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
15441                                     == (void *)TID_IPC) {
15442                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15443                                 }
15444                                 sip->cmd = si.cmd;
15445                                 sip->extra_info = NULL;
15446                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
15447                         }
15448                 } else {
15449                         /* we have seen this packet before; check the
15450                            matching table.
15451                            If we haven't yet seen the reply, we won't
15452                            find the info for it; we don't need it, as
15453                            we only use it to save information, and, as
15454                            we've seen this packet before, we've already
15455                            saved the information.
15456                         */
15457                         key.frame = pinfo->fd->num;
15458                         key.pid_mid = pid_mid;
15459                         sip=g_hash_table_lookup(si.ct->matched, &key);
15460                 }
15461         }
15462
15463         /*
15464          * Pass the "sip" on to subdissectors through "si".
15465          */
15466         si.sip = sip;
15467
15468         if (sip != NULL) {
15469                 /*
15470                  * Put in fields for the frame number of the frame to which
15471                  * this is a response or the frame with the response to this
15472                  * frame - if we know the frame number (i.e., it's not 0).
15473                  */
15474                 if(si.request){
15475                         if (sip->frame_res != 0)
15476                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15477                 } else {
15478                         if (sip->frame_req != 0)
15479                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
15480                 }
15481         }
15482
15483         /* smb command */
15484         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);
15485         offset += 1;
15486
15487         if(flags2 & 0x4000){
15488                 /* handle NT 32 bit error code */
15489
15490                 nt_status = tvb_get_letohl(tvb, offset);
15491
15492                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
15493                         TRUE);
15494                 offset += 4;
15495
15496         } else {
15497                 /* handle DOS error code & class */
15498                 errclass = tvb_get_guint8(tvb, offset);
15499                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
15500                         errclass);
15501                 offset += 1;
15502
15503                 /* reserved byte */
15504                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
15505                 offset += 1;
15506
15507                 /* error code */
15508                 /* XXX - the type of this field depends on the value of
15509                  * "errcls", so there is isn't a single value_string array
15510                  * fo it, so there can't be a single field for it.
15511                  */
15512                 errcode = tvb_get_letohs(tvb, offset);
15513                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
15514                         offset, 2, errcode, "Error Code: %s",
15515                         decode_smb_error(errclass, errcode));
15516                 offset += 2;
15517         }
15518
15519         /* flags */
15520         offset = dissect_smb_flags(tvb, htree, offset);
15521
15522         /* flags2 */
15523         offset = dissect_smb_flags2(tvb, htree, offset);
15524
15525         /*
15526          * The document at
15527          *
15528          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
15529          *
15530          * (a text version of "Microsoft Networks SMB FILE SHARING
15531          * PROTOCOL, Document Version 6.0p") says that:
15532          *
15533          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
15534          *      the "High Part of PID";
15535          *
15536          *      the next four bytes are reserved;
15537          *
15538          *      the next four bytes are, for SMB-over-IPX (with no
15539          *      NetBIOS involved) two bytes of Session ID and two bytes
15540          *      of SequenceNumber.
15541          *
15542          * If we ever implement SMB-over-IPX (which I suspect goes over
15543          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
15544          * document in question), we'd probably want to have some way
15545          * to determine whether this is SMB-over-IPX or not (which could
15546          * be done by adding a PT_IPXSOCKET port type, having the
15547          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
15548          * and having the SMB dissector check for a port type of
15549          * PT_IPXSOCKET and for "pinfo->match_port" being either
15550          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
15551          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
15552          */
15553
15554         /* 12 reserved bytes */
15555         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
15556         offset += 12;
15557
15558         /* TID */
15559         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
15560         offset += 2;
15561
15562         /* PID */
15563         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
15564         offset += 2;
15565
15566         /* UID */
15567         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
15568         offset += 2;
15569
15570         /* MID */
15571         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
15572         offset += 2;
15573
15574         pinfo->private_data = &si;
15575         dissect_smb_command(tvb, pinfo, offset, tree, si.cmd);
15576
15577         /* Append error info from this packet to info string. */
15578         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
15579                 if (flags2 & 0x4000) {
15580                         /*
15581                          * The status is an NT status code; was there
15582                          * an error?
15583                          */
15584                         if (nt_status != 0) {
15585                                 /*
15586                                  * Yes.
15587                                  */
15588                                 col_append_fstr(
15589                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15590                                         val_to_str(nt_status, NT_errors,
15591                                             "Unknown (0x%08X)"));
15592                         }
15593                 } else {
15594                         /*
15595                          * The status is a DOS error class and code; was
15596                          * there an error?
15597                          */
15598                         if (errclass != SMB_SUCCESS) {
15599                                 /*
15600                                  * Yes.
15601                                  */
15602                                 col_append_fstr(
15603                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15604                                         decode_smb_error(errclass, errcode));
15605                         }
15606                 }
15607         }
15608
15609         return TRUE;
15610 }
15611
15612 void
15613 proto_register_smb(void)
15614 {
15615         static hf_register_info hf[] = {
15616         { &hf_smb_cmd,
15617                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
15618                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
15619
15620         { &hf_smb_word_count,
15621                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
15622                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
15623
15624         { &hf_smb_byte_count,
15625                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
15626                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
15627
15628         { &hf_smb_response_to,
15629                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
15630                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
15631
15632         { &hf_smb_response_in,
15633                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
15634                 NULL, 0, "The response to this packet is in this packet", HFILL }},
15635
15636         { &hf_smb_continuation_to,
15637                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
15638                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
15639
15640         { &hf_smb_nt_status,
15641                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
15642                 VALS(NT_errors), 0, "NT Status code", HFILL }},
15643
15644         { &hf_smb_error_class,
15645                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
15646                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
15647
15648         { &hf_smb_error_code,
15649                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
15650                 NULL, 0, "DOS Error Code", HFILL }},
15651
15652         { &hf_smb_reserved,
15653                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
15654                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
15655
15656         { &hf_smb_pid,
15657                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
15658                 NULL, 0, "Process ID", HFILL }},
15659
15660         { &hf_smb_tid,
15661                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
15662                 NULL, 0, "Tree ID", HFILL }},
15663
15664         { &hf_smb_uid,
15665                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
15666                 NULL, 0, "User ID", HFILL }},
15667
15668         { &hf_smb_mid,
15669                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
15670                 NULL, 0, "Multiplex ID", HFILL }},
15671
15672         { &hf_smb_flags_lock,
15673                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
15674                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
15675
15676         { &hf_smb_flags_receive_buffer,
15677                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
15678                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
15679
15680         { &hf_smb_flags_caseless,
15681                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
15682                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
15683
15684         { &hf_smb_flags_canon,
15685                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
15686                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
15687
15688         { &hf_smb_flags_oplock,
15689                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
15690                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
15691
15692         { &hf_smb_flags_notify,
15693                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
15694                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
15695
15696         { &hf_smb_flags_response,
15697                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
15698                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
15699
15700         { &hf_smb_flags2_long_names_allowed,
15701                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
15702                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
15703
15704         { &hf_smb_flags2_ea,
15705                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
15706                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
15707
15708         { &hf_smb_flags2_sec_sig,
15709                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
15710                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
15711
15712         { &hf_smb_flags2_long_names_used,
15713                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
15714                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
15715
15716         { &hf_smb_flags2_esn,
15717                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
15718                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
15719
15720         { &hf_smb_flags2_dfs,
15721                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
15722                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
15723
15724         { &hf_smb_flags2_roe,
15725                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
15726                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
15727
15728         { &hf_smb_flags2_nt_error,
15729                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
15730                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
15731
15732         { &hf_smb_flags2_string,
15733                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
15734                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
15735
15736         { &hf_smb_buffer_format,
15737                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
15738                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
15739
15740         { &hf_smb_dialect_name,
15741                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
15742                 NULL, 0, "Name of dialect", HFILL }},
15743
15744         { &hf_smb_dialect_index,
15745                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
15746                 NULL, 0, "Index of selected dialect", HFILL }},
15747
15748         { &hf_smb_max_trans_buf_size,
15749                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
15750                 NULL, 0, "Maximum transmit buffer size", HFILL }},
15751
15752         { &hf_smb_max_mpx_count,
15753                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
15754                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
15755
15756         { &hf_smb_max_vcs_num,
15757                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
15758                 NULL, 0, "Maximum VCs between client and server", HFILL }},
15759
15760         { &hf_smb_session_key,
15761                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
15762                 NULL, 0, "Unique token identifying this session", HFILL }},
15763
15764         { &hf_smb_server_timezone,
15765                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
15766                 NULL, 0, "Current timezone at server.", HFILL }},
15767
15768         { &hf_smb_encryption_key_length,
15769                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
15770                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
15771
15772         { &hf_smb_encryption_key,
15773                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
15774                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
15775
15776         { &hf_smb_primary_domain,
15777                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
15778                 NULL, 0, "The server's primary domain", HFILL }},
15779
15780         { &hf_smb_max_raw_buf_size,
15781                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
15782                 NULL, 0, "Maximum raw buffer size", HFILL }},
15783
15784         { &hf_smb_server_guid,
15785                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
15786                 NULL, 0, "Globally unique identifier for this server", HFILL }},
15787
15788         { &hf_smb_security_blob_len,
15789                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
15790                 NULL, 0, "Security blob length", HFILL }},
15791
15792         { &hf_smb_security_blob,
15793                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
15794                 NULL, 0, "Security blob", HFILL }},
15795
15796         { &hf_smb_sm_mode16,
15797                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
15798                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15799
15800         { &hf_smb_sm_password16,
15801                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
15802                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15803
15804         { &hf_smb_sm_mode,
15805                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
15806                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15807
15808         { &hf_smb_sm_password,
15809                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
15810                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15811
15812         { &hf_smb_sm_signatures,
15813                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
15814                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
15815
15816         { &hf_smb_sm_sig_required,
15817                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
15818                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
15819
15820         { &hf_smb_rm_read,
15821                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
15822                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
15823
15824         { &hf_smb_rm_write,
15825                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
15826                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
15827
15828         { &hf_smb_server_date_time,
15829                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
15830                 NULL, 0, "Current date and time at server", HFILL }},
15831
15832         { &hf_smb_server_smb_date,
15833                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
15834                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
15835
15836         { &hf_smb_server_smb_time,
15837                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
15838                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
15839
15840         { &hf_smb_server_cap_raw_mode,
15841                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
15842                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
15843
15844         { &hf_smb_server_cap_mpx_mode,
15845                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
15846                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
15847
15848         { &hf_smb_server_cap_unicode,
15849                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
15850                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
15851
15852         { &hf_smb_server_cap_large_files,
15853                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
15854                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
15855
15856         { &hf_smb_server_cap_nt_smbs,
15857                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
15858                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
15859
15860         { &hf_smb_server_cap_rpc_remote_apis,
15861                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
15862                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
15863
15864         { &hf_smb_server_cap_nt_status,
15865                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
15866                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
15867
15868         { &hf_smb_server_cap_level_ii_oplocks,
15869                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
15870                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
15871
15872         { &hf_smb_server_cap_lock_and_read,
15873                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
15874                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
15875
15876         { &hf_smb_server_cap_nt_find,
15877                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
15878                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15879
15880         { &hf_smb_server_cap_dfs,
15881                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15882                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15883
15884         { &hf_smb_server_cap_infolevel_passthru,
15885                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15886                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15887
15888         { &hf_smb_server_cap_large_readx,
15889                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15890                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15891
15892         { &hf_smb_server_cap_large_writex,
15893                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15894                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15895
15896         { &hf_smb_server_cap_unix,
15897                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15898                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15899
15900         { &hf_smb_server_cap_reserved,
15901                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15902                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15903
15904         { &hf_smb_server_cap_bulk_transfer,
15905                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15906                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15907
15908         { &hf_smb_server_cap_compressed_data,
15909                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15910                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15911
15912         { &hf_smb_server_cap_extended_security,
15913                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
15914                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
15915
15916         { &hf_smb_system_time,
15917                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
15918                 NULL, 0, "System Time", HFILL }},
15919
15920         { &hf_smb_unknown,
15921                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
15922                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
15923
15924         { &hf_smb_dir_name,
15925                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
15926                 NULL, 0, "SMB Directory Name", HFILL }},
15927
15928         { &hf_smb_echo_count,
15929                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
15930                 NULL, 0, "Number of times to echo data back", HFILL }},
15931
15932         { &hf_smb_echo_data,
15933                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
15934                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
15935
15936         { &hf_smb_echo_seq_num,
15937                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
15938                 NULL, 0, "Sequence number for this echo response", HFILL }},
15939
15940         { &hf_smb_max_buf_size,
15941                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
15942                 NULL, 0, "Max client buffer size", HFILL }},
15943
15944         { &hf_smb_path,
15945                 { "Path", "smb.path", FT_STRING, BASE_NONE,
15946                 NULL, 0, "Path. Server name and share name", HFILL }},
15947
15948         { &hf_smb_service,
15949                 { "Service", "smb.service", FT_STRING, BASE_NONE,
15950                 NULL, 0, "Service name", HFILL }},
15951
15952         { &hf_smb_password,
15953                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15954                 NULL, 0, "Password", HFILL }},
15955
15956         { &hf_smb_ansi_password,
15957                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15958                 NULL, 0, "ANSI Password", HFILL }},
15959
15960         { &hf_smb_unicode_password,
15961                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15962                 NULL, 0, "Unicode Password", HFILL }},
15963
15964         { &hf_smb_move_flags_file,
15965                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15966                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15967
15968         { &hf_smb_move_flags_dir,
15969                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15970                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15971
15972         { &hf_smb_move_flags_verify,
15973                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15974                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15975
15976         { &hf_smb_files_moved,
15977                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
15978                 NULL, 0, "Number of files moved", HFILL }},
15979
15980         { &hf_smb_copy_flags_file,
15981                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
15982                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15983
15984         { &hf_smb_copy_flags_dir,
15985                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
15986                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15987
15988         { &hf_smb_copy_flags_dest_mode,
15989                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
15990                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
15991
15992         { &hf_smb_copy_flags_source_mode,
15993                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
15994                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
15995
15996         { &hf_smb_copy_flags_verify,
15997                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
15998                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15999
16000         { &hf_smb_copy_flags_tree_copy,
16001                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16002                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16003
16004         { &hf_smb_copy_flags_ea_action,
16005                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16006                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16007
16008         { &hf_smb_count,
16009                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16010                 NULL, 0, "Count number of items/bytes", HFILL }},
16011
16012         { &hf_smb_file_name,
16013                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16014                 NULL, 0, "File Name", HFILL }},
16015
16016         { &hf_smb_open_function_create,
16017                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16018                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16019
16020         { &hf_smb_open_function_open,
16021                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16022                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16023
16024         { &hf_smb_fid,
16025                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16026                 NULL, 0, "FID: File ID", HFILL }},
16027
16028         { &hf_smb_file_attr_read_only_16bit,
16029                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16030                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16031
16032         { &hf_smb_file_attr_read_only_8bit,
16033                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16034                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16035
16036         { &hf_smb_file_attr_hidden_16bit,
16037                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16038                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16039
16040         { &hf_smb_file_attr_hidden_8bit,
16041                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16042                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16043
16044         { &hf_smb_file_attr_system_16bit,
16045                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16046                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16047
16048         { &hf_smb_file_attr_system_8bit,
16049                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16050                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16051
16052         { &hf_smb_file_attr_volume_16bit,
16053                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16054                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16055
16056         { &hf_smb_file_attr_volume_8bit,
16057                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16058                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16059
16060         { &hf_smb_file_attr_directory_16bit,
16061                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16062                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16063
16064         { &hf_smb_file_attr_directory_8bit,
16065                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16066                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16067
16068         { &hf_smb_file_attr_archive_16bit,
16069                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16070                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16071
16072         { &hf_smb_file_attr_archive_8bit,
16073                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16074                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16075
16076         { &hf_smb_file_attr_device,
16077                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16078                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16079
16080         { &hf_smb_file_attr_normal,
16081                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16082                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16083
16084         { &hf_smb_file_attr_temporary,
16085                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16086                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16087
16088         { &hf_smb_file_attr_sparse,
16089                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16090                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16091
16092         { &hf_smb_file_attr_reparse,
16093                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16094                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16095
16096         { &hf_smb_file_attr_compressed,
16097                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16098                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16099
16100         { &hf_smb_file_attr_offline,
16101                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16102                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16103
16104         { &hf_smb_file_attr_not_content_indexed,
16105                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16106                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16107
16108         { &hf_smb_file_attr_encrypted,
16109                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16110                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16111
16112         { &hf_smb_file_size,
16113                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16114                 NULL, 0, "File Size", HFILL }},
16115
16116         { &hf_smb_search_attribute_read_only,
16117                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16118                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16119
16120         { &hf_smb_search_attribute_hidden,
16121                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16122                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16123
16124         { &hf_smb_search_attribute_system,
16125                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16126                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16127
16128         { &hf_smb_search_attribute_volume,
16129                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16130                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16131
16132         { &hf_smb_search_attribute_directory,
16133                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16134                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16135
16136         { &hf_smb_search_attribute_archive,
16137                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16138                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16139
16140         { &hf_smb_access_mode,
16141                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16142                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16143
16144         { &hf_smb_access_sharing,
16145                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16146                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16147
16148         { &hf_smb_access_locality,
16149                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16150                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16151
16152         { &hf_smb_access_caching,
16153                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16154                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16155
16156         { &hf_smb_access_writetru,
16157                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16158                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16159
16160         { &hf_smb_create_time,
16161                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16162                 NULL, 0, "Creation Time", HFILL }},
16163
16164         { &hf_smb_create_dos_date,
16165                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16166                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16167
16168         { &hf_smb_create_dos_time,
16169                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16170                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16171
16172         { &hf_smb_last_write_time,
16173                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16174                 NULL, 0, "Time this file was last written to", HFILL }},
16175
16176         { &hf_smb_last_write_dos_date,
16177                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16178                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16179
16180         { &hf_smb_last_write_dos_time,
16181                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16182                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16183
16184         { &hf_smb_old_file_name,
16185                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
16186                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16187
16188         { &hf_smb_offset,
16189                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16190                 NULL, 0, "Offset in file", HFILL }},
16191
16192         { &hf_smb_remaining,
16193                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16194                 NULL, 0, "Remaining number of bytes", HFILL }},
16195
16196         { &hf_smb_padding,
16197                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16198                 NULL, 0, "Padding or unknown data", HFILL }},
16199
16200         { &hf_smb_file_data,
16201                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16202                 NULL, 0, "Data read/written to the file", HFILL }},
16203
16204         { &hf_smb_total_data_len,
16205                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16206                 NULL, 0, "Total length of data", HFILL }},
16207
16208         { &hf_smb_data_len,
16209                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16210                 NULL, 0, "Length of data", HFILL }},
16211
16212         { &hf_smb_seek_mode,
16213                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16214                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16215
16216         { &hf_smb_access_time,
16217                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16218                 NULL, 0, "Last Access Time", HFILL }},
16219
16220         { &hf_smb_access_dos_date,
16221                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16222                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16223
16224         { &hf_smb_access_dos_time,
16225                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16226                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16227
16228         { &hf_smb_data_size,
16229                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16230                 NULL, 0, "Data Size", HFILL }},
16231
16232         { &hf_smb_alloc_size,
16233                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16234                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16235
16236         { &hf_smb_max_count,
16237                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16238                 NULL, 0, "Maximum Count", HFILL }},
16239
16240         { &hf_smb_min_count,
16241                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16242                 NULL, 0, "Minimum Count", HFILL }},
16243
16244         { &hf_smb_timeout,
16245                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16246                 NULL, 0, "Timeout in miliseconds", HFILL }},
16247
16248         { &hf_smb_high_offset,
16249                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16250                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16251
16252         { &hf_smb_units,
16253                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16254                 NULL, 0, "Total number of units at server", HFILL }},
16255
16256         { &hf_smb_bpu,
16257                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16258                 NULL, 0, "Blocks per unit at server", HFILL }},
16259
16260         { &hf_smb_blocksize,
16261                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16262                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16263
16264         { &hf_smb_freeunits,
16265                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16266                 NULL, 0, "Number of free units at server", HFILL }},
16267
16268         { &hf_smb_data_offset,
16269                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16270                 NULL, 0, "Data Offset", HFILL }},
16271
16272         { &hf_smb_dcm,
16273                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16274                 NULL, 0, "Data Compaction Mode", HFILL }},
16275
16276         { &hf_smb_request_mask,
16277                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
16278                 NULL, 0, "Connectionless mode mask", HFILL }},
16279
16280         { &hf_smb_response_mask,
16281                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
16282                 NULL, 0, "Connectionless mode mask", HFILL }},
16283
16284         { &hf_smb_sid,
16285                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
16286                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
16287
16288         { &hf_smb_write_mode_write_through,
16289                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
16290                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
16291
16292         { &hf_smb_write_mode_return_remaining,
16293                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
16294                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
16295
16296         { &hf_smb_write_mode_raw,
16297                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
16298                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
16299
16300         { &hf_smb_write_mode_message_start,
16301                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
16302                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
16303
16304         { &hf_smb_write_mode_connectionless,
16305                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
16306                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
16307
16308         { &hf_smb_resume_key_len,
16309                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
16310                 NULL, 0, "Resume Key length", HFILL }},
16311
16312         { &hf_smb_resume_find_id,
16313                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
16314                 NULL, 0, "Handle for Find operation", HFILL }},
16315
16316         { &hf_smb_resume_server_cookie,
16317                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
16318                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
16319
16320         { &hf_smb_resume_client_cookie,
16321                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
16322                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
16323
16324         { &hf_smb_andxoffset,
16325                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
16326                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
16327
16328         { &hf_smb_lock_type_large,
16329                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
16330                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
16331
16332         { &hf_smb_lock_type_cancel,
16333                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
16334                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
16335
16336         { &hf_smb_lock_type_change,
16337                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
16338                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
16339
16340         { &hf_smb_lock_type_oplock,
16341                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
16342                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
16343
16344         { &hf_smb_lock_type_shared,
16345                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
16346                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
16347
16348         { &hf_smb_locking_ol,
16349                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
16350                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
16351
16352         { &hf_smb_number_of_locks,
16353                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
16354                 NULL, 0, "Number of lock requests in this request", HFILL }},
16355
16356         { &hf_smb_number_of_unlocks,
16357                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
16358                 NULL, 0, "Number of unlock requests in this request", HFILL }},
16359
16360         { &hf_smb_lock_long_length,
16361                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
16362                 NULL, 0, "Length of lock/unlock region", HFILL }},
16363
16364         { &hf_smb_lock_long_offset,
16365                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
16366                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
16367
16368         { &hf_smb_file_type,
16369                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
16370                 VALS(filetype_vals), 0, "Type of file", HFILL }},
16371
16372         { &hf_smb_ipc_state_nonblocking,
16373                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
16374                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
16375
16376         { &hf_smb_ipc_state_endpoint,
16377                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
16378                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
16379
16380         { &hf_smb_ipc_state_pipe_type,
16381                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
16382                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
16383
16384         { &hf_smb_ipc_state_read_mode,
16385                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
16386                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
16387
16388         { &hf_smb_ipc_state_icount,
16389                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
16390                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
16391
16392         { &hf_smb_server_fid,
16393                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
16394                 NULL, 0, "Server unique File ID", HFILL }},
16395
16396         { &hf_smb_open_flags_add_info,
16397                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
16398                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
16399
16400         { &hf_smb_open_flags_ex_oplock,
16401                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
16402                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
16403
16404         { &hf_smb_open_flags_batch_oplock,
16405                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
16406                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
16407
16408         { &hf_smb_open_flags_ealen,
16409                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
16410                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
16411
16412         { &hf_smb_open_action_open,
16413                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
16414                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
16415
16416         { &hf_smb_open_action_lock,
16417                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
16418                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
16419
16420         { &hf_smb_vc_num,
16421                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
16422                 NULL, 0, "VC Number", HFILL }},
16423
16424         { &hf_smb_password_len,
16425                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
16426                 NULL, 0, "Length of password", HFILL }},
16427
16428         { &hf_smb_ansi_password_len,
16429                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
16430                 NULL, 0, "Length of ANSI password", HFILL }},
16431
16432         { &hf_smb_unicode_password_len,
16433                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
16434                 NULL, 0, "Length of Unicode password", HFILL }},
16435
16436         { &hf_smb_account,
16437                 { "Account", "smb.account", FT_STRING, BASE_NONE,
16438                 NULL, 0, "Account, username", HFILL }},
16439
16440         { &hf_smb_os,
16441                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
16442                 NULL, 0, "Which OS we are running", HFILL }},
16443
16444         { &hf_smb_lanman,
16445                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
16446                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
16447
16448         { &hf_smb_setup_action_guest,
16449                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
16450                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
16451
16452         { &hf_smb_fs,
16453                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
16454                 NULL, 0, "Native File System", HFILL }},
16455
16456         { &hf_smb_connect_flags_dtid,
16457                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
16458                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
16459
16460         { &hf_smb_connect_support_search,
16461                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
16462                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
16463
16464         { &hf_smb_connect_support_in_dfs,
16465                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
16466                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
16467
16468         { &hf_smb_max_setup_count,
16469                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
16470                 NULL, 0, "Maximum number of setup words to return", HFILL }},
16471
16472         { &hf_smb_total_param_count,
16473                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
16474                 NULL, 0, "Total number of parameter bytes", HFILL }},
16475
16476         { &hf_smb_total_data_count,
16477                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
16478                 NULL, 0, "Total number of data bytes", HFILL }},
16479
16480         { &hf_smb_max_param_count,
16481                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
16482                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
16483
16484         { &hf_smb_max_data_count,
16485                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
16486                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
16487
16488         { &hf_smb_param_disp16,
16489                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
16490                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16491
16492         { &hf_smb_param_count16,
16493                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
16494                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16495
16496         { &hf_smb_param_offset16,
16497                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
16498                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16499
16500         { &hf_smb_param_disp32,
16501                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
16502                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16503
16504         { &hf_smb_param_count32,
16505                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
16506                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16507
16508         { &hf_smb_param_offset32,
16509                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
16510                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16511
16512         { &hf_smb_data_count16,
16513                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
16514                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16515
16516         { &hf_smb_data_disp16,
16517                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
16518                 NULL, 0, "Data Displacement", HFILL }},
16519
16520         { &hf_smb_data_offset16,
16521                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16522                 NULL, 0, "Data Offset", HFILL }},
16523
16524         { &hf_smb_data_count32,
16525                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
16526                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16527
16528         { &hf_smb_data_disp32,
16529                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
16530                 NULL, 0, "Data Displacement", HFILL }},
16531
16532         { &hf_smb_data_offset32,
16533                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
16534                 NULL, 0, "Data Offset", HFILL }},
16535
16536         { &hf_smb_setup_count,
16537                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
16538                 NULL, 0, "Number of setup words in this buffer", HFILL }},
16539
16540         { &hf_smb_nt_trans_subcmd,
16541                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16542                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16543
16544         { &hf_smb_nt_ioctl_function_code,
16545                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
16546                 NULL, 0, "NT IOCTL function code", HFILL }},
16547
16548         { &hf_smb_nt_ioctl_isfsctl,
16549                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
16550                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
16551
16552         { &hf_smb_nt_ioctl_flags_root_handle,
16553                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
16554                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
16555
16556         { &hf_smb_nt_ioctl_data,
16557                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
16558                 NULL, 0, "Data for the IOCTL call", HFILL }},
16559
16560         { &hf_smb_nt_notify_action,
16561                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
16562                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
16563
16564         { &hf_smb_nt_notify_watch_tree,
16565                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
16566                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
16567
16568         { &hf_smb_nt_notify_stream_write,
16569                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
16570                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
16571
16572         { &hf_smb_nt_notify_stream_size,
16573                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
16574                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
16575
16576         { &hf_smb_nt_notify_stream_name,
16577                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
16578                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
16579
16580         { &hf_smb_nt_notify_security,
16581                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
16582                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
16583
16584         { &hf_smb_nt_notify_ea,
16585                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
16586                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
16587
16588         { &hf_smb_nt_notify_creation,
16589                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
16590                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
16591
16592         { &hf_smb_nt_notify_last_access,
16593                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
16594                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
16595
16596         { &hf_smb_nt_notify_last_write,
16597                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
16598                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
16599
16600         { &hf_smb_nt_notify_size,
16601                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
16602                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
16603
16604         { &hf_smb_nt_notify_attributes,
16605                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
16606                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
16607
16608         { &hf_smb_nt_notify_dir_name,
16609                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
16610                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
16611
16612         { &hf_smb_nt_notify_file_name,
16613                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
16614                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
16615
16616         { &hf_smb_root_dir_fid,
16617                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
16618                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
16619
16620         { &hf_smb_alloc_size64,
16621                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
16622                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16623
16624         { &hf_smb_nt_create_disposition,
16625                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
16626                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
16627
16628         { &hf_smb_sd_length,
16629                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
16630                 NULL, 0, "Total length of security descriptor", HFILL }},
16631
16632         { &hf_smb_ea_length,
16633                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
16634                 NULL, 0, "Total EA length for opened file", HFILL }},
16635
16636         { &hf_smb_file_name_len,
16637                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
16638                 NULL, 0, "Length of File Name", HFILL }},
16639
16640         { &hf_smb_nt_impersonation_level,
16641                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
16642                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
16643
16644         { &hf_smb_nt_security_flags_context_tracking,
16645                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
16646                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
16647
16648         { &hf_smb_nt_security_flags_effective_only,
16649                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
16650                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
16651
16652         { &hf_smb_nt_access_mask_generic_read,
16653                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
16654                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
16655
16656         { &hf_smb_nt_access_mask_generic_write,
16657                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
16658                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
16659
16660         { &hf_smb_nt_access_mask_generic_execute,
16661                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
16662                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
16663
16664         { &hf_smb_nt_access_mask_generic_all,
16665                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
16666                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
16667
16668         { &hf_smb_nt_access_mask_maximum_allowed,
16669                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
16670                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
16671
16672         { &hf_smb_nt_access_mask_system_security,
16673                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
16674                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
16675
16676         { &hf_smb_nt_access_mask_synchronize,
16677                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
16678                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
16679
16680         { &hf_smb_nt_access_mask_write_owner,
16681                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
16682                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
16683
16684         { &hf_smb_nt_access_mask_write_dac,
16685                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
16686                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
16687
16688         { &hf_smb_nt_access_mask_read_control,
16689                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
16690                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
16691
16692         { &hf_smb_nt_access_mask_delete,
16693                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
16694                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
16695
16696         { &hf_smb_nt_access_mask_write_attributes,
16697                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
16698                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
16699
16700         { &hf_smb_nt_access_mask_read_attributes,
16701                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
16702                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
16703
16704         { &hf_smb_nt_access_mask_delete_child,
16705                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
16706                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
16707
16708         /*
16709          * "Execute" for files, "traverse" for directories.
16710          */
16711         { &hf_smb_nt_access_mask_execute,
16712                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
16713                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
16714
16715         { &hf_smb_nt_access_mask_write_ea,
16716                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
16717                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
16718
16719         { &hf_smb_nt_access_mask_read_ea,
16720                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
16721                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
16722
16723         /*
16724          * "Append data" for files, "add subdirectory" for directories,
16725          * "create pipe instance" for named pipes.
16726          */
16727         { &hf_smb_nt_access_mask_append,
16728                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
16729                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
16730
16731         /*
16732          * "Write data" for files and pipes, "add file" for directory.
16733          */
16734         { &hf_smb_nt_access_mask_write,
16735                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
16736                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
16737
16738         /*
16739          * "Read data" for files and pipes, "list directory" for directory.
16740          */
16741         { &hf_smb_nt_access_mask_read,
16742                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
16743                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
16744
16745         { &hf_smb_nt_create_bits_oplock,
16746                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
16747                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
16748
16749         { &hf_smb_nt_create_bits_boplock,
16750                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
16751                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
16752
16753         { &hf_smb_nt_create_bits_dir,
16754                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
16755                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
16756
16757         { &hf_smb_nt_create_options_directory_file,
16758                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
16759                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
16760
16761         { &hf_smb_nt_create_options_write_through,
16762                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
16763                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
16764
16765         { &hf_smb_nt_create_options_sequential_only,
16766                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
16767                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
16768
16769         { &hf_smb_nt_create_options_sync_io_alert,
16770                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
16771                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
16772
16773         { &hf_smb_nt_create_options_sync_io_nonalert,
16774                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
16775                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
16776
16777         { &hf_smb_nt_create_options_non_directory_file,
16778                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
16779                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
16780
16781         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
16782            and "NtOpenFile()"; is that sent over the wire?  Network
16783            Monitor thinks so, but its author may just have grabbed
16784            the flag bits from a system header file. */
16785
16786         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
16787            and "NtOpenFile()"; is that sent over the wire?  NetMon
16788            thinks so, but see previous comment. */
16789
16790         { &hf_smb_nt_create_options_no_ea_knowledge,
16791                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
16792                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
16793
16794         { &hf_smb_nt_create_options_eight_dot_three_only,
16795                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
16796                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
16797
16798         { &hf_smb_nt_create_options_random_access,
16799                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
16800                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
16801
16802         { &hf_smb_nt_create_options_delete_on_close,
16803                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
16804                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
16805
16806         /* 0x00002000 is "open by FID", or something such as that (which
16807            I suspect is like "open by inumber" on UNIX), at least in
16808            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
16809            wire?  NetMon thinks so, but see previous comment. */
16810
16811         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
16812            and "NtOpenFile()"; is that sent over the wire?  NetMon
16813            thinks so, but see previous comment. */
16814
16815         { &hf_smb_nt_share_access_read,
16816                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
16817                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
16818
16819         { &hf_smb_nt_share_access_write,
16820                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
16821                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
16822
16823         { &hf_smb_nt_share_access_delete,
16824                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
16825                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
16826
16827         { &hf_smb_file_eattr_read_only,
16828                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
16829                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16830
16831         { &hf_smb_file_eattr_hidden,
16832                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
16833                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16834
16835         { &hf_smb_file_eattr_system,
16836                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
16837                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16838
16839         { &hf_smb_file_eattr_volume,
16840                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
16841                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16842
16843         { &hf_smb_file_eattr_directory,
16844                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
16845                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16846
16847         { &hf_smb_file_eattr_archive,
16848                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
16849                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16850
16851         { &hf_smb_file_eattr_device,
16852                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
16853                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16854
16855         { &hf_smb_file_eattr_normal,
16856                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
16857                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16858
16859         { &hf_smb_file_eattr_temporary,
16860                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
16861                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16862
16863         { &hf_smb_file_eattr_sparse,
16864                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
16865                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16866
16867         { &hf_smb_file_eattr_reparse,
16868                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
16869                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16870
16871         { &hf_smb_file_eattr_compressed,
16872                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
16873                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16874
16875         { &hf_smb_file_eattr_offline,
16876                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
16877                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16878
16879         { &hf_smb_file_eattr_not_content_indexed,
16880                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
16881                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16882
16883         { &hf_smb_file_eattr_encrypted,
16884                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
16885                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16886
16887         { &hf_smb_file_eattr_write_through,
16888                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
16889                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
16890
16891         { &hf_smb_file_eattr_no_buffering,
16892                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
16893                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
16894
16895         { &hf_smb_file_eattr_random_access,
16896                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
16897                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
16898
16899         { &hf_smb_file_eattr_sequential_scan,
16900                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
16901                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
16902
16903         { &hf_smb_file_eattr_delete_on_close,
16904                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
16905                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
16906
16907         { &hf_smb_file_eattr_backup_semantics,
16908                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
16909                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
16910
16911         { &hf_smb_file_eattr_posix_semantics,
16912                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
16913                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
16914
16915         { &hf_smb_sec_desc_len,
16916                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
16917                 NULL, 0, "Security Descriptor Length", HFILL }},
16918
16919         { &hf_smb_nt_qsd_owner,
16920                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
16921                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
16922
16923         { &hf_smb_nt_qsd_group,
16924                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
16925                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
16926
16927         { &hf_smb_nt_qsd_dacl,
16928                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
16929                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
16930
16931         { &hf_smb_nt_qsd_sacl,
16932                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
16933                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
16934
16935         { &hf_smb_extended_attributes,
16936                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
16937                 NULL, 0, "Extended Attributes", HFILL }},
16938
16939         { &hf_smb_oplock_level,
16940                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
16941                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
16942
16943         { &hf_smb_create_action,
16944                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
16945                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
16946
16947         { &hf_smb_file_id,
16948                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
16949                 NULL, 0, "Server unique file ID", HFILL }},
16950
16951         { &hf_smb_ea_error_offset,
16952                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
16953                 NULL, 0, "Offset into EA list if EA error", HFILL }},
16954
16955         { &hf_smb_end_of_file,
16956                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
16957                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
16958
16959         { &hf_smb_device_type,
16960                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
16961                 VALS(device_type_vals), 0, "Type of device", HFILL }},
16962
16963         { &hf_smb_is_directory,
16964                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
16965                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
16966
16967         { &hf_smb_next_entry_offset,
16968                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
16969                 NULL, 0, "Offset to next entry", HFILL }},
16970
16971         { &hf_smb_change_time,
16972                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
16973                 NULL, 0, "Last Change Time", HFILL }},
16974
16975         { &hf_smb_setup_len,
16976                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
16977                 NULL, 0, "Length of printer setup data", HFILL }},
16978
16979         { &hf_smb_print_mode,
16980                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
16981                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
16982
16983         { &hf_smb_print_identifier,
16984                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
16985                 NULL, 0, "Identifier string for this print job", HFILL }},
16986
16987         { &hf_smb_restart_index,
16988                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16989                 NULL, 0, "Index of entry after last returned", HFILL }},
16990
16991         { &hf_smb_print_queue_date,
16992                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16993                 NULL, 0, "Date when this entry was queued", HFILL }},
16994
16995         { &hf_smb_print_queue_dos_date,
16996                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16997                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16998
16999         { &hf_smb_print_queue_dos_time,
17000                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17001                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17002
17003         { &hf_smb_print_status,
17004                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17005                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17006
17007         { &hf_smb_print_spool_file_number,
17008                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17009                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17010
17011         { &hf_smb_print_spool_file_size,
17012                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17013                 NULL, 0, "Number of bytes in spool file", HFILL }},
17014
17015         { &hf_smb_print_spool_file_name,
17016                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17017                 NULL, 0, "Name of client that submitted this job", HFILL }},
17018
17019         { &hf_smb_start_index,
17020                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17021                 NULL, 0, "First queue entry to return", HFILL }},
17022
17023         { &hf_smb_originator_name,
17024                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17025                 NULL, 0, "Name of sender of message", HFILL }},
17026
17027         { &hf_smb_destination_name,
17028                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17029                 NULL, 0, "Name of recipient of message", HFILL }},
17030
17031         { &hf_smb_message_len,
17032                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17033                 NULL, 0, "Length of message", HFILL }},
17034
17035         { &hf_smb_message,
17036                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17037                 NULL, 0, "Message text", HFILL }},
17038
17039         { &hf_smb_mgid,
17040                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17041                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17042
17043         { &hf_smb_forwarded_name,
17044                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17045                 NULL, 0, "Recipient name being forwarded", HFILL }},
17046
17047         { &hf_smb_machine_name,
17048                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17049                 NULL, 0, "Name of target machine", HFILL }},
17050
17051         { &hf_smb_cancel_to,
17052                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
17053                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17054
17055         { &hf_smb_trans2_subcmd,
17056                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17057                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17058
17059         { &hf_smb_trans_name,
17060                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17061                 NULL, 0, "Name of transaction", HFILL }},
17062
17063         { &hf_smb_transaction_flags_dtid,
17064                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17065                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17066
17067         { &hf_smb_transaction_flags_owt,
17068                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17069                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17070
17071         { &hf_smb_search_count,
17072                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17073                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17074
17075         { &hf_smb_search_pattern,
17076                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17077                 NULL, 0, "Search Pattern", HFILL }},
17078
17079         { &hf_smb_ff2_backup,
17080                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17081                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17082
17083         { &hf_smb_ff2_continue,
17084                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17085                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17086
17087         { &hf_smb_ff2_resume,
17088                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17089                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17090
17091         { &hf_smb_ff2_close_eos,
17092                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17093                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17094
17095         { &hf_smb_ff2_close,
17096                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17097                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17098
17099         { &hf_smb_ff2_information_level,
17100                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17101                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17102
17103         { &hf_smb_qpi_loi,
17104                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
17105                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
17106
17107 #if 0
17108         { &hf_smb_sfi_writetru,
17109                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17110                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17111
17112         { &hf_smb_sfi_caching,
17113                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17114                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17115 #endif
17116
17117         { &hf_smb_storage_type,
17118                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17119                 NULL, 0, "Type of storage", HFILL }},
17120
17121         { &hf_smb_resume,
17122                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17123                 NULL, 0, "Resume Key", HFILL }},
17124
17125         { &hf_smb_max_referral_level,
17126                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17127                 NULL, 0, "Latest referral version number understood", HFILL }},
17128
17129         { &hf_smb_qfsi_information_level,
17130                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
17131                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17132
17133         { &hf_smb_nt_rename_level,
17134                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17135                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17136
17137         { &hf_smb_cluster_count,
17138                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17139                 NULL, 0, "Number of clusters", HFILL }},
17140
17141         { &hf_smb_ea_size,
17142                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
17143                 NULL, 0, "Size of file's EA information", HFILL }},
17144
17145         { &hf_smb_list_length,
17146                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
17147                 NULL, 0, "Length of the remaining data", HFILL }},
17148
17149         { &hf_smb_number_of_links,
17150                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17151                 NULL, 0, "Number of hard links to the file", HFILL }},
17152
17153         { &hf_smb_delete_pending,
17154                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17155                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17156
17157         { &hf_smb_index_number,
17158                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17159                 NULL, 0, "File system unique identifier", HFILL }},
17160
17161         { &hf_smb_current_offset,
17162                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17163                 NULL, 0, "Current offset in the file", HFILL }},
17164
17165         { &hf_smb_t2_alignment,
17166                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17167                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17168
17169         { &hf_smb_t2_stream_name_length,
17170                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17171                 NULL, 0, "Length of stream name", HFILL }},
17172
17173         { &hf_smb_t2_stream_size,
17174                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17175                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17176
17177         { &hf_smb_t2_stream_name,
17178                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17179                 NULL, 0, "Name of the stream", HFILL }},
17180
17181         { &hf_smb_t2_compressed_file_size,
17182                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17183                 NULL, 0, "Size of the compressed file", HFILL }},
17184
17185         { &hf_smb_t2_compressed_format,
17186                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17187                 NULL, 0, "Compression algorithm used", HFILL }},
17188
17189         { &hf_smb_t2_compressed_unit_shift,
17190                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17191                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17192
17193         { &hf_smb_t2_compressed_chunk_shift,
17194                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17195                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17196
17197         { &hf_smb_t2_compressed_cluster_shift,
17198                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17199                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17200
17201         { &hf_smb_dfs_path_consumed,
17202                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17203                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17204
17205         { &hf_smb_dfs_num_referrals,
17206                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17207                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17208
17209         { &hf_smb_get_dfs_server_hold_storage,
17210                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17211                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17212
17213         { &hf_smb_get_dfs_fielding,
17214                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17215                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17216
17217         { &hf_smb_dfs_referral_version,
17218                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17219                 NULL, 0, "Version of referral element", HFILL }},
17220
17221         { &hf_smb_dfs_referral_size,
17222                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17223                 NULL, 0, "Size of referral element", HFILL }},
17224
17225         { &hf_smb_dfs_referral_server_type,
17226                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17227                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17228
17229         { &hf_smb_dfs_referral_flags_strip,
17230                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17231                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17232
17233         { &hf_smb_dfs_referral_node_offset,
17234                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17235                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17236
17237         { &hf_smb_dfs_referral_node,
17238                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17239                 NULL, 0, "Name of entity to visit next", HFILL }},
17240
17241         { &hf_smb_dfs_referral_proximity,
17242                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17243                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17244
17245         { &hf_smb_dfs_referral_ttl,
17246                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17247                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17248
17249         { &hf_smb_dfs_referral_path_offset,
17250                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17251                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17252
17253         { &hf_smb_dfs_referral_path,
17254                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
17255                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
17256
17257         { &hf_smb_dfs_referral_alt_path_offset,
17258                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
17259                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
17260
17261         { &hf_smb_dfs_referral_alt_path,
17262                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
17263                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
17264
17265         { &hf_smb_end_of_search,
17266                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
17267                 NULL, 0, "Was last entry returned?", HFILL }},
17268
17269         { &hf_smb_last_name_offset,
17270                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
17271                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
17272
17273         { &hf_smb_fn_information_level,
17274                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
17275                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
17276
17277         { &hf_smb_monitor_handle,
17278                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
17279                 NULL, 0, "Handle for Find Notify operations", HFILL }},
17280
17281         { &hf_smb_change_count,
17282                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
17283                 NULL, 0, "Number of changes to wait for", HFILL }},
17284
17285         { &hf_smb_file_index,
17286                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
17287                 NULL, 0, "File index", HFILL }},
17288
17289         { &hf_smb_short_file_name,
17290                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
17291                 NULL, 0, "Short (8.3) File Name", HFILL }},
17292
17293         { &hf_smb_short_file_name_len,
17294                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
17295                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
17296
17297         { &hf_smb_fs_id,
17298                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
17299                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
17300
17301         { &hf_smb_sector_unit,
17302                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
17303                 NULL, 0, "Sectors per allocation unit", HFILL }},
17304
17305         { &hf_smb_fs_units,
17306                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
17307                 NULL, 0, "Total number of units on this filesystem", HFILL }},
17308
17309         { &hf_smb_fs_sector,
17310                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
17311                 NULL, 0, "Bytes per sector", HFILL }},
17312
17313         { &hf_smb_avail_units,
17314                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
17315                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
17316
17317         { &hf_smb_volume_serial_num,
17318                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
17319                 NULL, 0, "Volume serial number", HFILL }},
17320
17321         { &hf_smb_volume_label_len,
17322                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
17323                 NULL, 0, "Length of volume label", HFILL }},
17324
17325         { &hf_smb_volume_label,
17326                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
17327                 NULL, 0, "Volume label", HFILL }},
17328
17329         { &hf_smb_free_alloc_units64,
17330                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
17331                 NULL, 0, "Number of free allocation units", HFILL }},
17332
17333         { &hf_smb_caller_free_alloc_units64,
17334                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
17335                 NULL, 0, "Number of caller free allocation units", HFILL }},
17336
17337         { &hf_smb_actual_free_alloc_units64,
17338                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
17339                 NULL, 0, "Number of actual free allocation units", HFILL }},
17340
17341         { &hf_smb_soft_quota_limit,
17342                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
17343                 NULL, 0, "Soft Quota treshold", HFILL }},
17344
17345         { &hf_smb_hard_quota_limit,
17346                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
17347                 NULL, 0, "Hard Quota limit", HFILL }},
17348
17349         { &hf_smb_user_quota_used,
17350                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
17351                 NULL, 0, "How much Quota is used by this user", HFILL }},
17352
17353         { &hf_smb_max_name_len,
17354                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
17355                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
17356
17357         { &hf_smb_fs_name_len,
17358                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
17359                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
17360
17361         { &hf_smb_fs_name,
17362                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
17363                 NULL, 0, "Name of filesystem", HFILL }},
17364
17365         { &hf_smb_device_char_removable,
17366                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
17367                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
17368
17369         { &hf_smb_device_char_read_only,
17370                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
17371                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
17372
17373         { &hf_smb_device_char_floppy,
17374                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
17375                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
17376
17377         { &hf_smb_device_char_write_once,
17378                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
17379                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
17380
17381         { &hf_smb_device_char_remote,
17382                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
17383                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
17384
17385         { &hf_smb_device_char_mounted,
17386                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
17387                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
17388
17389         { &hf_smb_device_char_virtual,
17390                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
17391                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
17392
17393         { &hf_smb_fs_attr_css,
17394                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
17395                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
17396
17397         { &hf_smb_fs_attr_cpn,
17398                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
17399                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
17400
17401         { &hf_smb_fs_attr_pacls,
17402                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
17403                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
17404
17405         { &hf_smb_fs_attr_fc,
17406                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
17407                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
17408
17409         { &hf_smb_fs_attr_vq,
17410                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
17411                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
17412
17413         { &hf_smb_fs_attr_dim,
17414                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
17415                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
17416
17417         { &hf_smb_fs_attr_vic,
17418                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
17419                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
17420
17421         { &hf_smb_sec_desc_revision,
17422                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
17423                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
17424
17425         { &hf_smb_sid_revision,
17426                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
17427                 NULL, 0, "Version of SID structure", HFILL }},
17428
17429         { &hf_smb_sid_num_auth,
17430                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
17431                 NULL, 0, "Number of authorities for this SID", HFILL }},
17432
17433         { &hf_smb_acl_revision,
17434                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
17435                 NULL, 0, "Version of NT ACL structure", HFILL }},
17436
17437         { &hf_smb_acl_size,
17438                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
17439                 NULL, 0, "Size of NT ACL structure", HFILL }},
17440
17441         { &hf_smb_acl_num_aces,
17442                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
17443                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
17444
17445         { &hf_smb_user_quota_offset,
17446                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
17447                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
17448
17449         { &hf_smb_ace_type,
17450                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
17451                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
17452
17453         { &hf_smb_ace_size,
17454                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
17455                 NULL, 0, "Size of this ACE", HFILL }},
17456
17457         { &hf_smb_ace_flags_object_inherit,
17458                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
17459                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
17460
17461         { &hf_smb_ace_flags_container_inherit,
17462                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
17463                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
17464
17465         { &hf_smb_ace_flags_non_propagate_inherit,
17466                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
17467                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
17468
17469         { &hf_smb_ace_flags_inherit_only,
17470                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
17471                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
17472
17473         { &hf_smb_ace_flags_inherited_ace,
17474                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
17475                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
17476
17477         { &hf_smb_ace_flags_successful_access,
17478                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
17479                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
17480
17481         { &hf_smb_ace_flags_failed_access,
17482                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
17483                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
17484
17485         { &hf_smb_sec_desc_type_owner_defaulted,
17486                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
17487                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
17488
17489         { &hf_smb_sec_desc_type_group_defaulted,
17490                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
17491                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
17492
17493         { &hf_smb_sec_desc_type_dacl_present,
17494                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
17495                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
17496
17497         { &hf_smb_sec_desc_type_dacl_defaulted,
17498                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
17499                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
17500
17501         { &hf_smb_sec_desc_type_sacl_present,
17502                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
17503                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
17504
17505         { &hf_smb_sec_desc_type_sacl_defaulted,
17506                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
17507                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
17508
17509         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
17510                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
17511                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
17512
17513         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
17514                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
17515                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
17516
17517         { &hf_smb_sec_desc_type_dacl_auto_inherited,
17518                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
17519                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
17520
17521         { &hf_smb_sec_desc_type_sacl_auto_inherited,
17522                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
17523                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
17524
17525         { &hf_smb_sec_desc_type_dacl_protected,
17526                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
17527                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
17528
17529         { &hf_smb_sec_desc_type_sacl_protected,
17530                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
17531                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
17532
17533         { &hf_smb_sec_desc_type_self_relative,
17534                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
17535                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
17536
17537         { &hf_smb_quota_flags_deny_disk,
17538                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
17539                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
17540
17541         { &hf_smb_quota_flags_log_limit,
17542                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
17543                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
17544
17545         { &hf_smb_quota_flags_log_warning,
17546                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
17547                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
17548
17549         { &hf_smb_quota_flags_enabled,
17550                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
17551                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
17552
17553         };
17554         static gint *ett[] = {
17555                 &ett_smb,
17556                 &ett_smb_hdr,
17557                 &ett_smb_command,
17558                 &ett_smb_fileattributes,
17559                 &ett_smb_capabilities,
17560                 &ett_smb_aflags,
17561                 &ett_smb_dialect,
17562                 &ett_smb_dialects,
17563                 &ett_smb_mode,
17564                 &ett_smb_rawmode,
17565                 &ett_smb_flags,
17566                 &ett_smb_flags2,
17567                 &ett_smb_desiredaccess,
17568                 &ett_smb_search,
17569                 &ett_smb_file,
17570                 &ett_smb_openfunction,
17571                 &ett_smb_filetype,
17572                 &ett_smb_openaction,
17573                 &ett_smb_writemode,
17574                 &ett_smb_lock_type,
17575                 &ett_smb_ssetupandxaction,
17576                 &ett_smb_optionsup,
17577                 &ett_smb_time_date,
17578                 &ett_smb_move_copy_flags,
17579                 &ett_smb_file_attributes,
17580                 &ett_smb_search_resume_key,
17581                 &ett_smb_search_dir_info,
17582                 &ett_smb_unlocks,
17583                 &ett_smb_unlock,
17584                 &ett_smb_locks,
17585                 &ett_smb_lock,
17586                 &ett_smb_open_flags,
17587                 &ett_smb_ipc_state,
17588                 &ett_smb_open_action,
17589                 &ett_smb_setup_action,
17590                 &ett_smb_connect_flags,
17591                 &ett_smb_connect_support_bits,
17592                 &ett_smb_nt_access_mask,
17593                 &ett_smb_nt_create_bits,
17594                 &ett_smb_nt_create_options,
17595                 &ett_smb_nt_share_access,
17596                 &ett_smb_nt_security_flags,
17597                 &ett_smb_nt_trans_setup,
17598                 &ett_smb_nt_trans_data,
17599                 &ett_smb_nt_trans_param,
17600                 &ett_smb_nt_notify_completion_filter,
17601                 &ett_smb_nt_ioctl_flags,
17602                 &ett_smb_security_information_mask,
17603                 &ett_smb_print_queue_entry,
17604                 &ett_smb_transaction_flags,
17605                 &ett_smb_transaction_params,
17606                 &ett_smb_find_first2_flags,
17607 #if 0
17608                 &ett_smb_ioflag,
17609 #endif
17610                 &ett_smb_transaction_data,
17611                 &ett_smb_stream_info,
17612                 &ett_smb_dfs_referrals,
17613                 &ett_smb_dfs_referral,
17614                 &ett_smb_dfs_referral_flags,
17615                 &ett_smb_get_dfs_flags,
17616                 &ett_smb_ff2_data,
17617                 &ett_smb_device_characteristics,
17618                 &ett_smb_fs_attributes,
17619                 &ett_smb_segments,
17620                 &ett_smb_sec_desc,
17621                 &ett_smb_sid,
17622                 &ett_smb_acl,
17623                 &ett_smb_ace,
17624                 &ett_smb_ace_flags,
17625                 &ett_smb_sec_desc_type,
17626                 &ett_smb_quotaflags,
17627         };
17628         module_t *smb_module;
17629
17630         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
17631             "SMB", "smb");
17632         proto_register_subtree_array(ett, array_length(ett));
17633         proto_register_field_array(proto_smb, hf, array_length(hf));
17634         register_init_routine(&smb_init_protocol);
17635         smb_module = prefs_register_protocol(proto_smb, NULL);
17636         prefs_register_bool_preference(smb_module, "trans_reassembly",
17637                 "Reassemble SMB Transaction payload",
17638                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
17639                 &smb_trans_reassembly);
17640         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
17641                 "Reassemble DCERPC over SMB",
17642                 "Whether the dissector should reassemble DCERPC over SMB commands",
17643                 &smb_dcerpc_reassembly);
17644         register_init_routine(smb_trans_reassembly_init);
17645         register_init_routine(smb_dcerpc_reassembly_init);
17646 }
17647
17648 void
17649 proto_reg_handoff_smb(void)
17650 {
17651         heur_dissector_add("netbios", dissect_smb, proto_smb);
17652 }