Eliminate some unused variables.
[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.246 2002/04/22 06:26:08 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42
43 #include <time.h>
44 #include <string.h>
45 #include <glib.h>
46 #include <ctype.h>
47 #include <epan/packet.h>
48 #include <epan/conversation.h>
49 #include "smb.h"
50 #include "alignment.h"
51 #include <epan/strutil.h>
52 #include "prefs.h"
53 #include "reassemble.h"
54
55 #include "packet-smb-mailslot.h"
56 #include "packet-smb-pipe.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS draft from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
67  *
68  * (it supercedes the document at
69  *
70  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
71  *
72  * ).
73  *
74  * There are also some Open Group publications documenting CIFS for sale;
75  * catalog entries for them are at:
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c209.htm
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c195.htm
80  *
81  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
82  * can be found at
83  *
84  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
85  *
86  * (or, presumably a similar path under the Samba mirrors).  As the
87  * ".doc" indicates, it's a Word document.  Some of the specs from the
88  * Microsoft FTP site can be found in the
89  *
90  *      http://www.samba.org/samba/ftp/specs/
91  *
92  * directory as well.
93  *
94  * Beware - these specs may have errors.
95  */
96 static int proto_smb = -1;
97 static int hf_smb_cmd = -1;
98 static int hf_smb_pid = -1;
99 static int hf_smb_tid = -1;
100 static int hf_smb_uid = -1;
101 static int hf_smb_mid = -1;
102 static int hf_smb_response_to = -1;
103 static int hf_smb_response_in = -1;
104 static int hf_smb_continuation_to = -1;
105 static int hf_smb_nt_status = -1;
106 static int hf_smb_error_class = -1;
107 static int hf_smb_error_code = -1;
108 static int hf_smb_reserved = -1;
109 static int hf_smb_flags_lock = -1;
110 static int hf_smb_flags_receive_buffer = -1;
111 static int hf_smb_flags_caseless = -1;
112 static int hf_smb_flags_canon = -1;
113 static int hf_smb_flags_oplock = -1;
114 static int hf_smb_flags_notify = -1;
115 static int hf_smb_flags_response = -1;
116 static int hf_smb_flags2_long_names_allowed = -1;
117 static int hf_smb_flags2_ea = -1;
118 static int hf_smb_flags2_sec_sig = -1;
119 static int hf_smb_flags2_long_names_used = -1;
120 static int hf_smb_flags2_esn = -1;
121 static int hf_smb_flags2_dfs = -1;
122 static int hf_smb_flags2_roe = -1;
123 static int hf_smb_flags2_nt_error = -1;
124 static int hf_smb_flags2_string = -1;
125 static int hf_smb_word_count = -1;
126 static int hf_smb_byte_count = -1;
127 static int hf_smb_buffer_format = -1;
128 static int hf_smb_dialect_name = -1;
129 static int hf_smb_dialect_index = -1;
130 static int hf_smb_max_trans_buf_size = -1;
131 static int hf_smb_max_mpx_count = -1;
132 static int hf_smb_max_vcs_num = -1;
133 static int hf_smb_session_key = -1;
134 static int hf_smb_server_timezone = -1;
135 static int hf_smb_encryption_key_length = -1;
136 static int hf_smb_encryption_key = -1;
137 static int hf_smb_primary_domain = -1;
138 static int hf_smb_max_raw_buf_size = -1;
139 static int hf_smb_server_guid = -1;
140 static int hf_smb_security_blob_len = -1;
141 static int hf_smb_security_blob = -1;
142 static int hf_smb_sm_mode16 = -1;
143 static int hf_smb_sm_password16 = -1;
144 static int hf_smb_sm_mode = -1;
145 static int hf_smb_sm_password = -1;
146 static int hf_smb_sm_signatures = -1;
147 static int hf_smb_sm_sig_required = -1;
148 static int hf_smb_rm_read = -1;
149 static int hf_smb_rm_write = -1;
150 static int hf_smb_server_date_time = -1;
151 static int hf_smb_server_smb_date = -1;
152 static int hf_smb_server_smb_time = -1;
153 static int hf_smb_server_cap_raw_mode = -1;
154 static int hf_smb_server_cap_mpx_mode = -1;
155 static int hf_smb_server_cap_unicode = -1;
156 static int hf_smb_server_cap_large_files = -1;
157 static int hf_smb_server_cap_nt_smbs = -1;
158 static int hf_smb_server_cap_rpc_remote_apis = -1;
159 static int hf_smb_server_cap_nt_status = -1;
160 static int hf_smb_server_cap_level_ii_oplocks = -1;
161 static int hf_smb_server_cap_lock_and_read = -1;
162 static int hf_smb_server_cap_nt_find = -1;
163 static int hf_smb_server_cap_dfs = -1;
164 static int hf_smb_server_cap_infolevel_passthru = -1;
165 static int hf_smb_server_cap_large_readx = -1;
166 static int hf_smb_server_cap_large_writex = -1;
167 static int hf_smb_server_cap_unix = -1;
168 static int hf_smb_server_cap_reserved = -1;
169 static int hf_smb_server_cap_bulk_transfer = -1;
170 static int hf_smb_server_cap_compressed_data = -1;
171 static int hf_smb_server_cap_extended_security = -1;
172 static int hf_smb_system_time = -1;
173 static int hf_smb_unknown = -1;
174 static int hf_smb_dir_name = -1;
175 static int hf_smb_echo_count = -1;
176 static int hf_smb_echo_data = -1;
177 static int hf_smb_echo_seq_num = -1;
178 static int hf_smb_max_buf_size = -1;
179 static int hf_smb_password = -1;
180 static int hf_smb_password_len = -1;
181 static int hf_smb_ansi_password = -1;
182 static int hf_smb_ansi_password_len = -1;
183 static int hf_smb_unicode_password = -1;
184 static int hf_smb_unicode_password_len = -1;
185 static int hf_smb_path = -1;
186 static int hf_smb_service = -1;
187 static int hf_smb_move_flags_file = -1;
188 static int hf_smb_move_flags_dir = -1;
189 static int hf_smb_move_flags_verify = -1;
190 static int hf_smb_move_files_moved = -1;
191 static int hf_smb_count = -1;
192 static int hf_smb_file_name = -1;
193 static int hf_smb_open_function_open = -1;
194 static int hf_smb_open_function_create = -1;
195 static int hf_smb_fid = -1;
196 static int hf_smb_file_attr_read_only_16bit = -1;
197 static int hf_smb_file_attr_read_only_8bit = -1;
198 static int hf_smb_file_attr_hidden_16bit = -1;
199 static int hf_smb_file_attr_hidden_8bit = -1;
200 static int hf_smb_file_attr_system_16bit = -1;
201 static int hf_smb_file_attr_system_8bit = -1;
202 static int hf_smb_file_attr_volume_16bit = -1;
203 static int hf_smb_file_attr_volume_8bit = -1;
204 static int hf_smb_file_attr_directory_16bit = -1;
205 static int hf_smb_file_attr_directory_8bit = -1;
206 static int hf_smb_file_attr_archive_16bit = -1;
207 static int hf_smb_file_attr_archive_8bit = -1;
208 static int hf_smb_file_attr_device = -1;
209 static int hf_smb_file_attr_normal = -1;
210 static int hf_smb_file_attr_temporary = -1;
211 static int hf_smb_file_attr_sparse = -1;
212 static int hf_smb_file_attr_reparse = -1;
213 static int hf_smb_file_attr_compressed = -1;
214 static int hf_smb_file_attr_offline = -1;
215 static int hf_smb_file_attr_not_content_indexed = -1;
216 static int hf_smb_file_attr_encrypted = -1;
217 static int hf_smb_file_size = -1;
218 static int hf_smb_search_attribute_read_only = -1;
219 static int hf_smb_search_attribute_hidden = -1;
220 static int hf_smb_search_attribute_system = -1;
221 static int hf_smb_search_attribute_volume = -1;
222 static int hf_smb_search_attribute_directory = -1;
223 static int hf_smb_search_attribute_archive = -1;
224 static int hf_smb_access_mode = -1;
225 static int hf_smb_access_sharing = -1;
226 static int hf_smb_access_locality = -1;
227 static int hf_smb_access_caching = -1;
228 static int hf_smb_access_writetru = -1;
229 static int hf_smb_create_time = -1;
230 static int hf_smb_create_dos_date = -1;
231 static int hf_smb_create_dos_time = -1;
232 static int hf_smb_last_write_time = -1;
233 static int hf_smb_last_write_dos_date = -1;
234 static int hf_smb_last_write_dos_time = -1;
235 static int hf_smb_access_time = -1;
236 static int hf_smb_access_dos_date = -1;
237 static int hf_smb_access_dos_time = -1;
238 static int hf_smb_old_file_name = -1;
239 static int hf_smb_offset = -1;
240 static int hf_smb_remaining = -1;
241 static int hf_smb_padding = -1;
242 static int hf_smb_file_data = -1;
243 static int hf_smb_total_data_len = -1;
244 static int hf_smb_data_len = -1;
245 static int hf_smb_seek_mode = -1;
246 static int hf_smb_data_size = -1;
247 static int hf_smb_alloc_size = -1;
248 static int hf_smb_alloc_size64 = -1;
249 static int hf_smb_max_count = -1;
250 static int hf_smb_min_count = -1;
251 static int hf_smb_timeout = -1;
252 static int hf_smb_high_offset = -1;
253 static int hf_smb_units = -1;
254 static int hf_smb_bpu = -1;
255 static int hf_smb_blocksize = -1;
256 static int hf_smb_freeunits = -1;
257 static int hf_smb_data_offset = -1;
258 static int hf_smb_dcm = -1;
259 static int hf_smb_request_mask = -1;
260 static int hf_smb_response_mask = -1;
261 static int hf_smb_sid = -1;
262 static int hf_smb_write_mode_write_through = -1;
263 static int hf_smb_write_mode_return_remaining = -1;
264 static int hf_smb_write_mode_raw = -1;
265 static int hf_smb_write_mode_message_start = -1;
266 static int hf_smb_write_mode_connectionless = -1;
267 static int hf_smb_resume_key_len = -1;
268 static int hf_smb_resume_server_cookie = -1;
269 static int hf_smb_resume_client_cookie = -1;
270 static int hf_smb_andxoffset = -1;
271 static int hf_smb_lock_type_large = -1;
272 static int hf_smb_lock_type_cancel = -1;
273 static int hf_smb_lock_type_change = -1;
274 static int hf_smb_lock_type_oplock = -1;
275 static int hf_smb_lock_type_shared = -1;
276 static int hf_smb_locking_ol = -1;
277 static int hf_smb_number_of_locks = -1;
278 static int hf_smb_number_of_unlocks = -1;
279 static int hf_smb_lock_long_offset = -1;
280 static int hf_smb_lock_long_length = -1;
281 static int hf_smb_file_type = -1;
282 static int hf_smb_ipc_state_nonblocking = -1;
283 static int hf_smb_ipc_state_endpoint = -1;
284 static int hf_smb_ipc_state_pipe_type = -1;
285 static int hf_smb_ipc_state_read_mode = -1;
286 static int hf_smb_ipc_state_icount = -1;
287 static int hf_smb_server_fid = -1;
288 static int hf_smb_open_flags_add_info = -1;
289 static int hf_smb_open_flags_ex_oplock = -1;
290 static int hf_smb_open_flags_batch_oplock = -1;
291 static int hf_smb_open_flags_ealen = -1;
292 static int hf_smb_open_action_open = -1;
293 static int hf_smb_open_action_lock = -1;
294 static int hf_smb_vc_num = -1;
295 static int hf_smb_account = -1;
296 static int hf_smb_os = -1;
297 static int hf_smb_lanman = -1;
298 static int hf_smb_setup_action_guest = -1;
299 static int hf_smb_fs = -1;
300 static int hf_smb_connect_flags_dtid = -1;
301 static int hf_smb_connect_support_search = -1;
302 static int hf_smb_connect_support_in_dfs = -1;
303 static int hf_smb_max_setup_count = -1;
304 static int hf_smb_total_param_count = -1;
305 static int hf_smb_total_data_count = -1;
306 static int hf_smb_max_param_count = -1;
307 static int hf_smb_max_data_count = -1;
308 static int hf_smb_param_disp16 = -1;
309 static int hf_smb_param_count16 = -1;
310 static int hf_smb_param_offset16 = -1;
311 static int hf_smb_param_disp32 = -1;
312 static int hf_smb_param_count32 = -1;
313 static int hf_smb_param_offset32 = -1;
314 static int hf_smb_data_disp16 = -1;
315 static int hf_smb_data_count16 = -1;
316 static int hf_smb_data_offset16 = -1;
317 static int hf_smb_data_disp32 = -1;
318 static int hf_smb_data_count32 = -1;
319 static int hf_smb_data_offset32 = -1;
320 static int hf_smb_setup_count = -1;
321 static int hf_smb_nt_trans_subcmd = -1;
322 static int hf_smb_nt_ioctl_function_code = -1;
323 static int hf_smb_nt_ioctl_isfsctl = -1;
324 static int hf_smb_nt_ioctl_flags_root_handle = -1;
325 static int hf_smb_nt_ioctl_data = -1;
326 static int hf_smb_nt_security_information = -1;
327 static int hf_smb_nt_notify_action = -1;
328 static int hf_smb_nt_notify_watch_tree = -1;
329 static int hf_smb_nt_notify_stream_write = -1;
330 static int hf_smb_nt_notify_stream_size = -1;
331 static int hf_smb_nt_notify_stream_name = -1;
332 static int hf_smb_nt_notify_security = -1;
333 static int hf_smb_nt_notify_ea = -1;
334 static int hf_smb_nt_notify_creation = -1;
335 static int hf_smb_nt_notify_last_access = -1;
336 static int hf_smb_nt_notify_last_write = -1;
337 static int hf_smb_nt_notify_size = -1;
338 static int hf_smb_nt_notify_attributes = -1;
339 static int hf_smb_nt_notify_dir_name = -1;
340 static int hf_smb_nt_notify_file_name = -1;
341 static int hf_smb_root_dir_fid = -1;
342 static int hf_smb_nt_create_disposition = -1;
343 static int hf_smb_sd_length = -1;
344 static int hf_smb_ea_length = -1;
345 static int hf_smb_file_name_len = -1;
346 static int hf_smb_nt_impersonation_level = -1;
347 static int hf_smb_nt_security_flags_context_tracking = -1;
348 static int hf_smb_nt_security_flags_effective_only = -1;
349 static int hf_smb_nt_access_mask_generic_read = -1;
350 static int hf_smb_nt_access_mask_generic_write = -1;
351 static int hf_smb_nt_access_mask_generic_execute = -1;
352 static int hf_smb_nt_access_mask_generic_all = -1;
353 static int hf_smb_nt_access_mask_maximum_allowed = -1;
354 static int hf_smb_nt_access_mask_system_security = -1;
355 static int hf_smb_nt_access_mask_synchronize = -1;
356 static int hf_smb_nt_access_mask_write_owner = -1;
357 static int hf_smb_nt_access_mask_write_dac = -1;
358 static int hf_smb_nt_access_mask_read_control = -1;
359 static int hf_smb_nt_access_mask_delete = -1;
360 static int hf_smb_nt_access_mask_write_attributes = -1;
361 static int hf_smb_nt_access_mask_read_attributes = -1;
362 static int hf_smb_nt_access_mask_delete_child = -1;
363 static int hf_smb_nt_access_mask_execute = -1;
364 static int hf_smb_nt_access_mask_write_ea = -1;
365 static int hf_smb_nt_access_mask_read_ea = -1;
366 static int hf_smb_nt_access_mask_append = -1;
367 static int hf_smb_nt_access_mask_write = -1;
368 static int hf_smb_nt_access_mask_read = -1;
369 static int hf_smb_nt_create_bits_oplock = -1;
370 static int hf_smb_nt_create_bits_boplock = -1;
371 static int hf_smb_nt_create_bits_dir = -1;
372 static int hf_smb_nt_create_options_directory_file = -1;
373 static int hf_smb_nt_create_options_write_through = -1;
374 static int hf_smb_nt_create_options_sequential_only = -1;
375 static int hf_smb_nt_create_options_sync_io_alert = -1;
376 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
377 static int hf_smb_nt_create_options_non_directory_file = -1;
378 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
379 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
380 static int hf_smb_nt_create_options_random_access = -1;
381 static int hf_smb_nt_create_options_delete_on_close = -1;
382 static int hf_smb_nt_share_access_read = -1;
383 static int hf_smb_nt_share_access_write = -1;
384 static int hf_smb_nt_share_access_delete = -1;
385 static int hf_smb_file_eattr_read_only = -1;
386 static int hf_smb_file_eattr_hidden = -1;
387 static int hf_smb_file_eattr_system = -1;
388 static int hf_smb_file_eattr_volume = -1;
389 static int hf_smb_file_eattr_directory = -1;
390 static int hf_smb_file_eattr_archive = -1;
391 static int hf_smb_file_eattr_device = -1;
392 static int hf_smb_file_eattr_normal = -1;
393 static int hf_smb_file_eattr_temporary = -1;
394 static int hf_smb_file_eattr_sparse = -1;
395 static int hf_smb_file_eattr_reparse = -1;
396 static int hf_smb_file_eattr_compressed = -1;
397 static int hf_smb_file_eattr_offline = -1;
398 static int hf_smb_file_eattr_not_content_indexed = -1;
399 static int hf_smb_file_eattr_encrypted = -1;
400 static int hf_smb_file_eattr_write_through = -1;
401 static int hf_smb_file_eattr_no_buffering = -1;
402 static int hf_smb_file_eattr_random_access = -1;
403 static int hf_smb_file_eattr_sequential_scan = -1;
404 static int hf_smb_file_eattr_delete_on_close = -1;
405 static int hf_smb_file_eattr_backup_semantics = -1;
406 static int hf_smb_file_eattr_posix_semantics = -1;
407 static int hf_smb_sec_desc_len = -1;
408 static int hf_smb_sec_desc_revision = -1;
409 static int hf_smb_sec_desc_type_owner_defaulted = -1;
410 static int hf_smb_sec_desc_type_group_defaulted = -1;
411 static int hf_smb_sec_desc_type_dacl_present = -1;
412 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
413 static int hf_smb_sec_desc_type_sacl_present = -1;
414 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
415 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
416 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
417 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
418 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
419 static int hf_smb_sec_desc_type_dacl_protected = -1;
420 static int hf_smb_sec_desc_type_sacl_protected = -1;
421 static int hf_smb_sec_desc_type_self_relative = -1;
422 static int hf_smb_sid_revision = -1;
423 static int hf_smb_sid_num_auth = -1;
424 static int hf_smb_acl_revision = -1;
425 static int hf_smb_acl_size = -1;
426 static int hf_smb_acl_num_aces = -1;
427 static int hf_smb_ace_type = -1;
428 static int hf_smb_ace_size = -1;
429 static int hf_smb_ace_flags_object_inherit = -1;
430 static int hf_smb_ace_flags_container_inherit = -1;
431 static int hf_smb_ace_flags_non_propagate_inherit = -1;
432 static int hf_smb_ace_flags_inherit_only = -1;
433 static int hf_smb_ace_flags_inherited_ace = -1;
434 static int hf_smb_ace_flags_successful_access = -1;
435 static int hf_smb_ace_flags_failed_access = -1;
436 static int hf_smb_nt_qsd_owner = -1;
437 static int hf_smb_nt_qsd_group = -1;
438 static int hf_smb_nt_qsd_dacl = -1;
439 static int hf_smb_nt_qsd_sacl = -1;
440 static int hf_smb_extended_attributes = -1;
441 static int hf_smb_oplock_level = -1;
442 static int hf_smb_create_action = -1;
443 static int hf_smb_ea_error_offset = -1;
444 static int hf_smb_end_of_file = -1;
445 static int hf_smb_device_type = -1;
446 static int hf_smb_is_directory = -1;
447 static int hf_smb_next_entry_offset = -1;
448 static int hf_smb_change_time = -1;
449 static int hf_smb_setup_len = -1;
450 static int hf_smb_print_mode = -1;
451 static int hf_smb_print_identifier = -1;
452 static int hf_smb_restart_index = -1;
453 static int hf_smb_print_queue_date = -1;
454 static int hf_smb_print_queue_dos_date = -1;
455 static int hf_smb_print_queue_dos_time = -1;
456 static int hf_smb_print_status = -1;
457 static int hf_smb_print_spool_file_number = -1;
458 static int hf_smb_print_spool_file_size = -1;
459 static int hf_smb_print_spool_file_name = -1;
460 static int hf_smb_start_index = -1;
461 static int hf_smb_cancel_to = -1;
462 static int hf_smb_trans2_subcmd = -1;
463 static int hf_smb_trans_name = -1;
464 static int hf_smb_transaction_flags_dtid = -1;
465 static int hf_smb_transaction_flags_owt = -1;
466 static int hf_smb_search_count = -1;
467 static int hf_smb_search_pattern = -1;
468 static int hf_smb_ff2_backup = -1;
469 static int hf_smb_ff2_continue = -1;
470 static int hf_smb_ff2_resume = -1;
471 static int hf_smb_ff2_close_eos = -1;
472 static int hf_smb_ff2_close = -1;
473 static int hf_smb_ff2_information_level = -1;
474 static int hf_smb_qpi_loi = -1;
475 static int hf_smb_storage_type = -1;
476 static int hf_smb_resume = -1;
477 static int hf_smb_max_referral_level = -1;
478 static int hf_smb_qfsi_information_level = -1;
479 static int hf_smb_ea_size = -1;
480 static int hf_smb_list_length = -1;
481 static int hf_smb_number_of_links = -1;
482 static int hf_smb_delete_pending = -1;
483 static int hf_smb_index_number = -1;
484 static int hf_smb_current_offset = -1;
485 static int hf_smb_t2_alignment = -1;
486 static int hf_smb_t2_stream_name_length = -1;
487 static int hf_smb_t2_stream_size = -1;
488 static int hf_smb_t2_stream_name = -1;
489 static int hf_smb_t2_compressed_file_size = -1;
490 static int hf_smb_t2_compressed_format = -1;
491 static int hf_smb_t2_compressed_unit_shift = -1;
492 static int hf_smb_t2_compressed_chunk_shift = -1;
493 static int hf_smb_t2_compressed_cluster_shift = -1;
494 static int hf_smb_dfs_path_consumed = -1;
495 static int hf_smb_dfs_num_referrals = -1;
496 static int hf_smb_get_dfs_server_hold_storage = -1;
497 static int hf_smb_get_dfs_fielding = -1;
498 static int hf_smb_dfs_referral_version = -1;
499 static int hf_smb_dfs_referral_size = -1;
500 static int hf_smb_dfs_referral_server_type = -1;
501 static int hf_smb_dfs_referral_flags_strip = -1;
502 static int hf_smb_dfs_referral_node_offset = -1;
503 static int hf_smb_dfs_referral_node = -1;
504 static int hf_smb_dfs_referral_proximity = -1;
505 static int hf_smb_dfs_referral_ttl = -1;
506 static int hf_smb_dfs_referral_path_offset = -1;
507 static int hf_smb_dfs_referral_path = -1;
508 static int hf_smb_dfs_referral_alt_path_offset = -1;
509 static int hf_smb_dfs_referral_alt_path = -1;
510 static int hf_smb_end_of_search = -1;
511 static int hf_smb_last_name_offset = -1;
512 static int hf_smb_file_index = -1;
513 static int hf_smb_short_file_name = -1;
514 static int hf_smb_short_file_name_len = -1;
515 static int hf_smb_fs_id = -1;
516 static int hf_smb_sector_unit = -1;
517 static int hf_smb_fs_units = -1;
518 static int hf_smb_fs_sector = -1;
519 static int hf_smb_avail_units = -1;
520 static int hf_smb_volume_serial_num = -1;
521 static int hf_smb_volume_label_len = -1;
522 static int hf_smb_volume_label = -1;
523 static int hf_smb_free_alloc_units64 = -1;
524 static int hf_smb_max_name_len = -1;
525 static int hf_smb_fs_name_len = -1;
526 static int hf_smb_fs_name = -1;
527 static int hf_smb_device_char_removable = -1;
528 static int hf_smb_device_char_read_only = -1;
529 static int hf_smb_device_char_floppy = -1;
530 static int hf_smb_device_char_write_once = -1;
531 static int hf_smb_device_char_remote = -1;
532 static int hf_smb_device_char_mounted = -1;
533 static int hf_smb_device_char_virtual = -1;
534 static int hf_smb_fs_attr_css = -1;
535 static int hf_smb_fs_attr_cpn = -1;
536 static int hf_smb_fs_attr_pacls = -1;
537 static int hf_smb_fs_attr_fc = -1;
538 static int hf_smb_fs_attr_vq = -1;
539 static int hf_smb_fs_attr_dim = -1;
540 static int hf_smb_fs_attr_vic = -1;
541 static int hf_smb_quota_flags_enabled = -1;
542 static int hf_smb_quota_flags_deny_disk = -1;
543 static int hf_smb_quota_flags_log_limit = -1;
544 static int hf_smb_quota_flags_log_warning = -1;
545 static int hf_smb_soft_quota_limit = -1;
546 static int hf_smb_hard_quota_limit = -1;
547 static int hf_smb_user_quota_used = -1;
548 static int hf_smb_user_quota_offset = -1;
549 static int hf_smb_nt_rename_level = -1;
550 static int hf_smb_cluster_count = -1;
551
552 static gint ett_smb = -1;
553 static gint ett_smb_hdr = -1;
554 static gint ett_smb_command = -1;
555 static gint ett_smb_fileattributes = -1;
556 static gint ett_smb_capabilities = -1;
557 static gint ett_smb_aflags = -1;
558 static gint ett_smb_dialect = -1;
559 static gint ett_smb_dialects = -1;
560 static gint ett_smb_mode = -1;
561 static gint ett_smb_rawmode = -1;
562 static gint ett_smb_flags = -1;
563 static gint ett_smb_flags2 = -1;
564 static gint ett_smb_desiredaccess = -1;
565 static gint ett_smb_search = -1;
566 static gint ett_smb_file = -1;
567 static gint ett_smb_openfunction = -1;
568 static gint ett_smb_filetype = -1;
569 static gint ett_smb_openaction = -1;
570 static gint ett_smb_writemode = -1;
571 static gint ett_smb_lock_type = -1;
572 static gint ett_smb_ssetupandxaction = -1;
573 static gint ett_smb_optionsup = -1;
574 static gint ett_smb_time_date = -1;
575 static gint ett_smb_move_flags = -1;
576 static gint ett_smb_file_attributes = -1;
577 static gint ett_smb_search_resume_key = -1;
578 static gint ett_smb_search_dir_info = -1;
579 static gint ett_smb_unlocks = -1;
580 static gint ett_smb_unlock = -1;
581 static gint ett_smb_locks = -1;
582 static gint ett_smb_lock = -1;
583 static gint ett_smb_open_flags = -1;
584 static gint ett_smb_ipc_state = -1;
585 static gint ett_smb_open_action = -1;
586 static gint ett_smb_setup_action = -1;
587 static gint ett_smb_connect_flags = -1;
588 static gint ett_smb_connect_support_bits = -1;
589 static gint ett_smb_nt_access_mask = -1;
590 static gint ett_smb_nt_create_bits = -1;
591 static gint ett_smb_nt_create_options = -1;
592 static gint ett_smb_nt_share_access = -1;
593 static gint ett_smb_nt_security_flags = -1;
594 static gint ett_smb_nt_trans_setup = -1;
595 static gint ett_smb_nt_trans_data = -1;
596 static gint ett_smb_nt_trans_param = -1;
597 static gint ett_smb_nt_notify_completion_filter = -1;
598 static gint ett_smb_nt_ioctl_flags = -1;
599 static gint ett_smb_security_information_mask = -1;
600 static gint ett_smb_print_queue_entry = -1;
601 static gint ett_smb_transaction_flags = -1;
602 static gint ett_smb_transaction_params = -1;
603 static gint ett_smb_find_first2_flags = -1;
604 static gint ett_smb_transaction_data = -1;
605 static gint ett_smb_stream_info = -1;
606 static gint ett_smb_dfs_referrals = -1;
607 static gint ett_smb_dfs_referral = -1;
608 static gint ett_smb_dfs_referral_flags = -1;
609 static gint ett_smb_get_dfs_flags = -1;
610 static gint ett_smb_ff2_data = -1;
611 static gint ett_smb_device_characteristics = -1;
612 static gint ett_smb_fs_attributes = -1;
613 static gint ett_smb_segments = -1;
614 static gint ett_smb_sec_desc = -1;
615 static gint ett_smb_sid = -1;
616 static gint ett_smb_acl = -1;
617 static gint ett_smb_ace = -1;
618 static gint ett_smb_ace_flags = -1;
619 static gint ett_smb_sec_desc_type = -1;
620 static gint ett_smb_quotaflags = -1;
621
622 proto_tree *top_tree=NULL;     /* ugly */
623
624 static char *decode_smb_name(unsigned char);
625 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
626 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
627     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
628     gboolean exactlen, guint16 *bcp);
629
630 /*
631  * Macros for use in the main dissector routines for an SMB.
632  */
633
634 #define WORD_COUNT      \
635         /* Word Count */                                \
636         wc = tvb_get_guint8(tvb, offset);               \
637         proto_tree_add_uint(tree, hf_smb_word_count,    \
638                 tvb, offset, 1, wc);                    \
639         offset += 1;                                    \
640         if(wc==0) goto bytecount;
641
642 #define BYTE_COUNT      \
643         bytecount:                                      \
644         bc = tvb_get_letohs(tvb, offset);               \
645         proto_tree_add_uint(tree, hf_smb_byte_count,    \
646                         tvb, offset, 2, bc);            \
647         offset += 2;                                    \
648         if(bc==0) goto endofcommand;
649
650 #define CHECK_BYTE_COUNT(len)   \
651         if (bc < len) goto endofcommand;
652
653 #define COUNT_BYTES(len)   {\
654         int tmp;            \
655         tmp=len;            \
656         offset += tmp;      \
657         bc -= tmp;          \
658         }
659
660 #define END_OF_SMB      \
661         if (bc != 0) { \
662                 proto_tree_add_text(tree, tvb, offset, bc, \
663                     "Extra byte parameters");           \
664                 offset += bc;                           \
665         }                                               \
666         endofcommand:
667
668 /*
669  * Macros for use in routines called by them.
670  */
671 #define CHECK_BYTE_COUNT_SUBR(len)      \
672         if (*bcp < len) {               \
673                 *trunc = TRUE;          \
674                 return offset;          \
675         }
676
677 #define CHECK_STRING_SUBR(fn)   \
678         if (fn == NULL) {       \
679                 *trunc = TRUE;  \
680                 return offset;  \
681         }
682
683 #define COUNT_BYTES_SUBR(len)   \
684         offset += len;          \
685         *bcp -= len;
686
687 /*
688  * Macros for use when dissecting transaction parameters and data
689  */
690 #define CHECK_BYTE_COUNT_TRANS(len)     \
691         if (bc < len) return offset;
692
693 #define CHECK_STRING_TRANS(fn)  \
694         if (fn == NULL) return offset;
695
696 #define COUNT_BYTES_TRANS(len)  \
697         offset += len;          \
698         bc -= len;
699
700 /*
701  * Macros for use in subrroutines dissecting transaction parameters or data
702  */
703 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
704         if (*bcp < len) return offset;
705
706 #define CHECK_STRING_TRANS_SUBR(fn)     \
707         if (fn == NULL) return offset;
708
709 #define COUNT_BYTES_TRANS_SUBR(len)     \
710         offset += len;                  \
711         *bcp -= len;
712
713
714 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
715    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
716    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
717 static gboolean smb_trans_reassembly = FALSE;
718 gboolean smb_dcerpc_reassembly = FALSE;
719
720 static GHashTable *smb_trans_fragment_table = NULL;
721 GHashTable *dcerpc_fragment_table = NULL;
722
723 static void
724 smb_trans_reassembly_init(void)
725 {
726         fragment_table_init(&smb_trans_fragment_table);
727 }
728 static void
729 smb_dcerpc_reassembly_init(void)
730 {
731         fragment_table_init(&dcerpc_fragment_table);
732 }
733
734
735 static fragment_data *
736 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
737                      int offset, int count, int pos, int totlen)
738 {
739         fragment_data *fd_head=NULL;
740         smb_info_t *si;
741         int more_frags;
742
743         more_frags=totlen>(pos+count);
744
745         si = (smb_info_t *)pinfo->private_data;
746         if (si->sip == NULL) {
747                 /*
748                  * We don't have the frame number of the request.
749                  *
750                  * XXX - is there truly nothing we can do here?
751                  * Can we not separately keep track of the original
752                  * transaction and its continuations, as we did
753                  * at one time?
754                  *
755                  * It is probably not much point in even trying to do something here
756                  * if we have never seen the initial request. Without the initial 
757                  * request we probably miss all parameters and the begining of data
758                  * so we cant even call a subdissector since we can not determine
759                  * which type of transaction call this is.
760                  */
761                 return NULL;
762         }
763
764         if(!pinfo->fd->flags.visited){
765                 fd_head = fragment_add(tvb, offset, pinfo,
766                                        si->sip->frame_req, smb_trans_fragment_table,
767                                        pos, count, more_frags);
768         } else {
769                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
770         }
771
772         /* we only show the defragmented packet for the first fragment,
773            or else we might end up with dissecting one HUGE transaction PDU
774            a LOT of times. (first fragment is the only one containing the setup
775            bytes)
776            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
777            SMBs. Takes a LOT of time dissecting and is not fun.
778         */
779         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
780                 return fd_head;
781         } else {
782                 return NULL;
783         }
784 }
785                 
786
787
788
789
790 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
791    These variables and functions are used to match
792    responses with calls
793    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
794 /*
795  * The information we need to save about a request in order to show the
796  * frame number of the request in the dissection of the reply.
797  */
798 typedef struct  {
799         guint32 frame;
800         guint32 pid_mid;
801 } smb_saved_info_key_t;
802
803 static GMemChunk *smb_saved_info_key_chunk = NULL;
804 static GMemChunk *smb_saved_info_chunk = NULL;
805 static int smb_saved_info_init_count = 200;
806
807 /* unmatched smb_saved_info structures.
808    For unmatched smb_saved_info structures we store the smb_saved_info
809    structure using the MID and the PID as the key.
810
811    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
812    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
813    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
814 */
815 static gint
816 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
817 {
818         register guint32 key1 = (guint32)k1;
819         register guint32 key2 = (guint32)k2;
820         return key1==key2;
821 }
822 static guint
823 smb_saved_info_hash_unmatched(gconstpointer k)
824 {
825         register guint32 key = (guint32)k;
826         return key;
827 }
828
829 /* matched smb_saved_info structures.
830    For matched smb_saved_info structures we store the smb_saved_info
831    structure twice in the table using the frame number, and a combination
832    of the MID and the PID, as the key.
833    The frame number is guaranteed to be unique but if ever someone makes
834    some change that will renumber the frames in a capture we are in BIG trouble.
835    This is not likely though since that would break (among other things) all the
836    reassembly routines as well.
837
838    We also need the MID as there may be more than one SMB request or reply
839    in a single frame, and we also need the PID as there may be more than
840    one outstanding request with the same MID and different PIDs.
841 */
842 static gint
843 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
844 {
845         const smb_saved_info_key_t *key1 = k1;
846         const smb_saved_info_key_t *key2 = k2;
847         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
848 }
849 static guint
850 smb_saved_info_hash_matched(gconstpointer k)
851 {
852         const smb_saved_info_key_t *key = k;
853         return key->frame + key->pid_mid;
854 }
855
856 /*
857  * The information we need to save about an NT Transaction request in order
858  * to dissect the reply.
859  */
860 typedef struct {
861         int subcmd;
862 } smb_nt_transact_info_t;
863
864 static GMemChunk *smb_nt_transact_info_chunk = NULL;
865 static int smb_nt_transact_info_init_count = 200;
866
867 /*
868  * The information we need to save about a Transaction2 request in order
869  * to dissect the reply.
870  */
871 typedef struct {
872         int subcmd;
873         int info_level;
874 } smb_transact2_info_t;
875
876 static GMemChunk *smb_transact2_info_chunk = NULL;
877 static int smb_transact2_info_init_count = 200;
878
879 /*
880  * The information we need to save about a Transaction request in order
881  * to dissect the reply; this includes information for use by the
882  * Remote API dissector.
883  */
884 static GMemChunk *smb_transact_info_chunk = NULL;
885 static int smb_transact_info_init_count = 200;
886
887 static GMemChunk *conv_tables_chunk = NULL;
888 static GSList *conv_tables = NULL;
889 static int conv_tables_count = 10;
890
891
892 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
893    End of request/response matching functions
894    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
895
896 static const value_string buffer_format_vals[] = {
897         {1,     "Data Block"},
898         {2,     "Dialect"},
899         {3,     "Pathname"},
900         {4,     "ASCII"},
901         {5,     "Variable Block"},
902         {0,     NULL}
903 };
904
905 /*
906  * UTIME - this is *almost* like a UNIX time stamp, except that it's
907  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
908  * January 1, 1970, 00:00:00 GMT.
909  *
910  * This means we have to do some extra work to convert it.  This code is
911  * based on the Samba code:
912  *
913  *      Unix SMB/Netbios implementation.
914  *      Version 1.9.
915  *      time handling functions
916  *      Copyright (C) Andrew Tridgell 1992-1998
917  */
918
919 /*
920  * Yield the difference between *A and *B, in seconds, ignoring leap
921  * seconds.
922  */
923 #define TM_YEAR_BASE 1900
924
925 static int
926 tm_diff(struct tm *a, struct tm *b)
927 {
928         int ay = a->tm_year + (TM_YEAR_BASE - 1);
929         int by = b->tm_year + (TM_YEAR_BASE - 1);
930         int intervening_leap_days =
931             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
932         int years = ay - by;
933         int days =
934             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
935         int hours = 24*days + (a->tm_hour - b->tm_hour);
936         int minutes = 60*hours + (a->tm_min - b->tm_min);
937         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
938
939         return seconds;
940 }
941
942 /*
943  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
944  * determined.
945  */
946 static int
947 TimeZone(time_t t)
948 {
949         struct tm *tm = gmtime(&t);
950         struct tm tm_utc;
951
952         if (tm == NULL)
953                 return 0;
954         tm_utc = *tm;
955         tm = localtime(&t);
956         if (tm == NULL)
957                 return 0;
958         return tm_diff(&tm_utc,tm);
959 }
960
961 /*
962  * Return the same value as TimeZone, but it should be more efficient.
963  *
964  * We keep a table of DST offsets to prevent calling localtime() on each 
965  * call of this function. This saves a LOT of time on many unixes.
966  *
967  * Updated by Paul Eggert <eggert@twinsun.com>
968  */
969 #ifndef CHAR_BIT
970 #define CHAR_BIT 8
971 #endif
972
973 #ifndef TIME_T_MIN
974 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
975                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
976 #endif
977 #ifndef TIME_T_MAX
978 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
979 #endif
980
981 static int
982 TimeZoneFaster(time_t t)
983 {
984         static struct dst_table {time_t start,end; int zone;} *tdt;
985         static struct dst_table *dst_table = NULL;
986         static int table_size = 0;
987         int i;
988         int zone = 0;
989
990         if (t == 0)
991                 t = time(NULL);
992
993         /* Tunis has a 8 day DST region, we need to be careful ... */
994 #define MAX_DST_WIDTH (365*24*60*60)
995 #define MAX_DST_SKIP (7*24*60*60)
996
997         for (i = 0; i < table_size; i++) {
998                 if (t >= dst_table[i].start && t <= dst_table[i].end)
999                         break;
1000         }
1001
1002         if (i < table_size) {
1003                 zone = dst_table[i].zone;
1004         } else {
1005                 time_t low,high;
1006
1007                 zone = TimeZone(t);
1008                 if (dst_table == NULL)
1009                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1010                 else
1011                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1012                 if (tdt == NULL) {
1013                         if (dst_table)
1014                                 free(dst_table);
1015                         table_size = 0;
1016                 } else {
1017                         dst_table = tdt;
1018                         table_size++;
1019     
1020                         dst_table[i].zone = zone; 
1021                         dst_table[i].start = dst_table[i].end = t;
1022     
1023                         /* no entry will cover more than 6 months */
1024                         low = t - MAX_DST_WIDTH/2;
1025                         if (t < low)
1026                                 low = TIME_T_MIN;
1027       
1028                         high = t + MAX_DST_WIDTH/2;
1029                         if (high < t)
1030                                 high = TIME_T_MAX;
1031       
1032                         /*
1033                          * Widen the new entry using two bisection searches.
1034                          */
1035                         while (low+60*60 < dst_table[i].start) {
1036                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1037                                         t = dst_table[i].start - MAX_DST_SKIP;
1038                                 else
1039                                         t = low + (dst_table[i].start-low)/2;
1040                                 if (TimeZone(t) == zone)
1041                                         dst_table[i].start = t;
1042                                 else
1043                                         low = t;
1044                         }
1045
1046                         while (high-60*60 > dst_table[i].end) {
1047                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1048                                         t = dst_table[i].end + MAX_DST_SKIP;
1049                                 else
1050                                         t = high - (high-dst_table[i].end)/2;
1051                                 if (TimeZone(t) == zone)
1052                                         dst_table[i].end = t;
1053                                 else
1054                                         high = t;
1055                         }
1056                 }
1057         }
1058         return zone;
1059 }
1060
1061 /*
1062  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1063  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1064  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1065  * daylight savings transitions because some local times are ambiguous.
1066  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1067  */
1068 static int
1069 LocTimeDiff(time_t lt)
1070 {
1071         int d = TimeZoneFaster(lt);
1072         time_t t = lt + d;
1073
1074         /* if overflow occurred, ignore all the adjustments so far */
1075         if (((t < lt) ^ (d < 0)))
1076                 t = lt;
1077
1078         /*
1079          * Now t should be close enough to the true UTC to yield the
1080          * right answer.
1081          */
1082         return TimeZoneFaster(t);
1083 }
1084
1085 static int
1086 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1087 {
1088         guint32 timeval;
1089         nstime_t ts;
1090  
1091         timeval = tvb_get_letohl(tvb, offset);
1092         if (timeval == 0xffffffff) {
1093                 proto_tree_add_text(tree, tvb, offset, 4,
1094                     "%s: No time specified (0xffffffff)",
1095                     proto_registrar_get_name(hf_date));
1096                 offset += 4;
1097                 return offset;
1098         }
1099
1100         /*
1101          * We add the local time offset.
1102          */
1103         ts.secs = timeval + LocTimeDiff(timeval);
1104         ts.nsecs = 0;
1105
1106         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1107         offset += 4;
1108  
1109         return offset;
1110 }
1111
1112 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1113
1114 /*
1115  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1116  * to an "nstime_t".
1117  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1118  * midnight "UTC", in 100ns units.
1119  * Return TRUE if the conversion succeeds, FALSE otherwise.
1120  *
1121  * According to the Samba code, it appears to be kludge-GMT (at least for
1122  * file listings). This means it's the GMT you get by taking a local time
1123  * and adding the server time zone offset.  This is NOT the same as GMT in
1124  * some cases.   However, we don't know the server time zone, so we don't
1125  * do that adjustment.
1126  *
1127  * This code is based on the Samba code:
1128  *
1129  *      Unix SMB/Netbios implementation.
1130  *      Version 1.9.
1131  *      time handling functions
1132  *      Copyright (C) Andrew Tridgell 1992-1998
1133  */
1134 static gboolean
1135 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1136 {
1137         double d;
1138         /* The next two lines are a fix needed for the 
1139             broken SCO compiler. JRA. */
1140         time_t l_time_min = TIME_T_MIN;
1141         time_t l_time_max = TIME_T_MAX;
1142
1143         if (filetime_high == 0)
1144                 return FALSE;
1145
1146         /*
1147          * Get the time as a double, in seconds and fractional seconds.
1148          */
1149         d = ((double)filetime_high)*4.0*(double)(1<<30);
1150         d += filetime_low;
1151         d *= 1.0e-7;
1152  
1153         /* Now adjust by 369 years, to make the seconds since 1970. */
1154         d -= TIME_FIXUP_CONSTANT;
1155
1156         if (!(l_time_min <= d && d <= l_time_max))
1157                 return FALSE;
1158
1159         /*
1160          * Get the time as seconds and nanoseconds.
1161          */
1162         tv->secs = d;
1163         tv->nsecs = (d - tv->secs)*1000000000;
1164
1165         return TRUE;
1166 }
1167
1168 int
1169 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1170 {
1171         guint32 filetime_high, filetime_low;
1172         nstime_t ts;
1173
1174         /* XXX there seems also to be another special time value which is fairly common :
1175            0x40000000 00000000  
1176            the meaning of this one is yet unknown 
1177         */
1178         if (tree) {
1179                 filetime_low = tvb_get_letohl(tvb, offset);
1180                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1181                 if (filetime_low == 0 && filetime_high == 0) {
1182                         proto_tree_add_text(tree, tvb, offset, 8,
1183                             "%s: No time specified (0)",
1184                             proto_registrar_get_name(hf_date));
1185                 } else if(filetime_low==0 && filetime_high==0x80000000){
1186                         proto_tree_add_text(tree, tvb, offset, 8,
1187                             "%s: Infinity (relative time)",
1188                             proto_registrar_get_name(hf_date));
1189                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1190                         proto_tree_add_text(tree, tvb, offset, 8,
1191                             "%s: Infinity (absolute time)",
1192                             proto_registrar_get_name(hf_date));
1193                 } else {                        
1194                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1195                                 proto_tree_add_time(tree, hf_date, tvb,
1196                                     offset, 8, &ts);
1197                         } else {
1198                                 proto_tree_add_text(tree, tvb, offset, 8,
1199                                     "%s: Time can't be converted",
1200                                     proto_registrar_get_name(hf_date));
1201                         }
1202                 }
1203         }
1204
1205         offset += 8;
1206         return offset;
1207 }
1208
1209 static int
1210 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
1211     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
1212     int hf_dos_time, gboolean time_first)
1213 {
1214         guint16 dos_time, dos_date;
1215         proto_item *item = NULL;
1216         proto_tree *tree = NULL;
1217         struct tm tm;
1218         time_t t;
1219         static const int mday_noleap[12] = {
1220                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1221         };
1222         static const int mday_leap[12] = {
1223                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1224         };
1225 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1226         nstime_t tv;
1227
1228         if (time_first) {
1229                 dos_time = tvb_get_letohs(tvb, offset);
1230                 dos_date = tvb_get_letohs(tvb, offset+2);
1231         } else {
1232                 dos_date = tvb_get_letohs(tvb, offset);
1233                 dos_time = tvb_get_letohs(tvb, offset+2);
1234         }
1235
1236         if ((dos_time == 0xffff && dos_time == 0xffff) ||
1237             (dos_time == 0 && dos_time == 0)) {
1238                 /*
1239                  * No date/time specified.
1240                  */
1241                 if(parent_tree){
1242                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1243                             "%s: No time specified (0x%08x)",
1244                             proto_registrar_get_name(hf_date),
1245                             (dos_date << 16) | dos_time);
1246                 }
1247                 offset += 4;
1248                 return offset;
1249         }
1250
1251         tm.tm_sec = (dos_time&0x1f)*2;
1252         tm.tm_min = (dos_time>>5)&0x3f;
1253         tm.tm_hour = (dos_time>>11)&0x1f;
1254         tm.tm_mday = dos_date&0x1f;
1255         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1256         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1257         tm.tm_isdst = -1;
1258
1259         /*
1260          * Do some sanity checks before calling "mktime()";
1261          * "mktime()" doesn't do them, it "normalizes" out-of-range
1262          * values.
1263          */
1264         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1265            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1266            (ISLEAP(tm.tm_year + 1900) ?
1267              tm.tm_mday > mday_leap[tm.tm_mon] :
1268              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1269              (t = mktime(&tm)) == -1) {
1270                 /*
1271                  * Invalid date/time.
1272                  */
1273                 if (parent_tree) {
1274                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1275                             "%s: Invalid time",
1276                             proto_registrar_get_name(hf_date));
1277                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1278                         if (time_first) {
1279                                 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);
1280                                 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);
1281                         } else {
1282                                 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);
1283                                 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);
1284                         }
1285                 }
1286                 offset += 4;
1287                 return offset;
1288         }
1289
1290         tv.secs = t;
1291         tv.nsecs = 0;
1292
1293         if(parent_tree){
1294                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1295                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1296                 if (time_first) {
1297                         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);
1298                         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);
1299                 } else {
1300                         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);
1301                         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);
1302                 }
1303         }
1304
1305         offset += 4;
1306
1307         return offset;
1308 }
1309
1310
1311 static const value_string da_access_vals[] = {
1312         { 0,            "Open for reading"},
1313         { 1,            "Open for writing"},
1314         { 2,            "Open for reading and writing"},
1315         { 3,            "Open for execute"},
1316         {0, NULL}
1317 };
1318 static const value_string da_sharing_vals[] = {
1319         { 0,            "Compatibility mode"},
1320         { 1,            "Deny read/write/execute (exclusive)"},
1321         { 2,            "Deny write"},
1322         { 3,            "Deny read/execute"},
1323         { 4,            "Deny none"},
1324         {0, NULL}
1325 };
1326 static const value_string da_locality_vals[] = {
1327         { 0,            "Locality of reference unknown"},
1328         { 1,            "Mainly sequential access"},
1329         { 2,            "Mainly random access"},
1330         { 3,            "Random access with some locality"},
1331         {0, NULL}
1332 };
1333 static const true_false_string tfs_da_caching = {
1334         "Do not cache this file",
1335         "Caching permitted on this file"
1336 };
1337 static const true_false_string tfs_da_writetru = {
1338         "Write through enabled",
1339         "Write through disabled"
1340 };
1341 static int
1342 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1343 {
1344         guint16 mask;
1345         proto_item *item = NULL;
1346         proto_tree *tree = NULL;
1347
1348         mask = tvb_get_letohs(tvb, offset);
1349
1350         if(parent_tree){
1351                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1352                         "%s Access: 0x%04x", type, mask);
1353                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1354         }
1355
1356         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1357                 tvb, offset, 2, mask);
1358         proto_tree_add_boolean(tree, hf_smb_access_caching,
1359                 tvb, offset, 2, mask);
1360         proto_tree_add_uint(tree, hf_smb_access_locality,
1361                 tvb, offset, 2, mask);
1362         proto_tree_add_uint(tree, hf_smb_access_sharing,
1363                 tvb, offset, 2, mask);
1364         proto_tree_add_uint(tree, hf_smb_access_mode,
1365                 tvb, offset, 2, mask);
1366
1367         offset += 2;
1368
1369         return offset;
1370 }
1371
1372 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1373 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1374 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1375 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1376 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1377 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1378 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1379 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1380 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1381 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1382 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1383 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1384 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1385 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1386 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1387
1388 /*
1389  * These are flags to be used in NT Create operations.
1390  */
1391 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1392 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1393 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1394 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1395 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1396 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1397 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1398
1399 static const true_false_string tfs_file_attribute_write_through = {
1400         "This object requires WRITE THROUGH",
1401         "This object does NOT require write through",
1402 };
1403 static const true_false_string tfs_file_attribute_no_buffering = {
1404         "This object requires NO BUFFERING",
1405         "This object can be buffered",
1406 };
1407 static const true_false_string tfs_file_attribute_random_access = {
1408         "This object will be RANDOM ACCESSed",
1409         "Random access is NOT requested",
1410 };
1411 static const true_false_string tfs_file_attribute_sequential_scan = {
1412         "This object is optimized for SEQUENTIAL SCAN",
1413         "This object is NOT optimized for sequential scan",
1414 };
1415 static const true_false_string tfs_file_attribute_delete_on_close = {
1416         "This object will be DELETED ON CLOSE",
1417         "This object will not be deleted on close",
1418 };
1419 static const true_false_string tfs_file_attribute_backup_semantics = {
1420         "This object supports BACKUP SEMANTICS",
1421         "This object does NOT support backup semantics",
1422 };
1423 static const true_false_string tfs_file_attribute_posix_semantics = {
1424         "This object supports POSIX SEMANTICS",
1425         "This object does NOT support POSIX semantics",
1426 };
1427 static const true_false_string tfs_file_attribute_read_only = {
1428         "This file is READ ONLY",
1429         "This file is NOT read only",
1430 };
1431 static const true_false_string tfs_file_attribute_hidden = {
1432         "This is a HIDDEN file",
1433         "This is NOT a hidden file"
1434 };
1435 static const true_false_string tfs_file_attribute_system = {
1436         "This is a SYSTEM file",
1437         "This is NOT a system file"
1438 };
1439 static const true_false_string tfs_file_attribute_volume = {
1440         "This is a VOLUME ID",
1441         "This is NOT a volume ID"
1442 };
1443 static const true_false_string tfs_file_attribute_directory = {
1444         "This is a DIRECTORY",
1445         "This is NOT a directory"
1446 };
1447 static const true_false_string tfs_file_attribute_archive = {
1448         "This is an ARCHIVE file",
1449         "This is NOT an archive file"
1450 };
1451 static const true_false_string tfs_file_attribute_device = {
1452         "This is a DEVICE",
1453         "This is NOT a device"
1454 };
1455 static const true_false_string tfs_file_attribute_normal = {
1456         "This file is an ordinary file",
1457         "This file has some attribute set"
1458 };
1459 static const true_false_string tfs_file_attribute_temporary = {
1460         "This is a TEMPORARY file",
1461         "This is NOT a temporary file"
1462 };
1463 static const true_false_string tfs_file_attribute_sparse = {
1464         "This is a SPARSE file",
1465         "This is NOT a sparse file"
1466 };
1467 static const true_false_string tfs_file_attribute_reparse = {
1468         "This file has an associated REPARSE POINT",
1469         "This file does NOT have an associated reparse point"
1470 };
1471 static const true_false_string tfs_file_attribute_compressed = {
1472         "This is a COMPRESSED file",
1473         "This is NOT a compressed file"
1474 };
1475 static const true_false_string tfs_file_attribute_offline = {
1476         "This file is OFFLINE",
1477         "This file is NOT offline"
1478 };
1479 static const true_false_string tfs_file_attribute_not_content_indexed = {
1480         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1481         "This file MAY be indexed by the content indexing service"
1482 };
1483 static const true_false_string tfs_file_attribute_encrypted = {
1484         "This is an ENCRYPTED file",
1485         "This is NOT an encrypted file"
1486 };
1487
1488 static int
1489 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1490 {
1491         guint16 mask;
1492         proto_item *item = NULL;
1493         proto_tree *tree = NULL;
1494
1495         mask = tvb_get_letohs(tvb, offset);
1496
1497         if(parent_tree){
1498                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1499                         "File Attributes: 0x%04x", mask);
1500                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1501         }
1502         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1503                 tvb, offset, 2, mask);
1504         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1505                 tvb, offset, 2, mask);
1506         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1507                 tvb, offset, 2, mask);
1508         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1509                 tvb, offset, 2, mask);
1510         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1511                 tvb, offset, 2, mask);
1512         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1513                 tvb, offset, 2, mask);
1514
1515         offset += 2;
1516
1517         return offset;
1518 }
1519
1520 /* 3.11 */
1521 static int
1522 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1523 {
1524         guint32 mask;
1525         proto_item *item = NULL;
1526         proto_tree *tree = NULL;
1527
1528         mask = tvb_get_letohl(tvb, offset);
1529
1530         if(parent_tree){
1531                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1532                         "File Attributes: 0x%08x", mask);
1533                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1534         }
1535
1536         /*
1537          * XXX - Network Monitor disagrees on some of the
1538          * bits, e.g. the bits above temporary are "atomic write"
1539          * and "transaction write", and it says nothing about the
1540          * bits above that.
1541          *
1542          * Does the Win32 API documentation, or the NT Native API book,
1543          * suggest anything?
1544          */
1545         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1546                 tvb, offset, 4, mask);
1547         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1548                 tvb, offset, 4, mask);
1549         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1550                 tvb, offset, 4, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1552                 tvb, offset, 4, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1554                 tvb, offset, 4, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1556                 tvb, offset, 4, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1558                 tvb, offset, 4, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1560                 tvb, offset, 4, mask);
1561         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1562                 tvb, offset, 4, mask);
1563         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1564                 tvb, offset, 4, mask);
1565         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1566                 tvb, offset, 4, mask);
1567         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1568                 tvb, offset, 4, mask);
1569         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1570                 tvb, offset, 4, mask);
1571         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1572                 tvb, offset, 4, mask);
1573         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1574                 tvb, offset, 4, mask);
1575         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1576                 tvb, offset, 4, mask);
1577         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1578                 tvb, offset, 4, mask);
1579         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1580                 tvb, offset, 4, mask);
1581         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1582                 tvb, offset, 4, mask);
1583         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1584                 tvb, offset, 4, mask);
1585         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1586                 tvb, offset, 4, mask);
1587         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1588                 tvb, offset, 4, mask);
1589
1590         offset += 4;
1591
1592         return offset;
1593 }
1594
1595 static int
1596 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1597 {
1598         guint8 mask;
1599         proto_item *item = NULL;
1600         proto_tree *tree = NULL;
1601
1602         mask = tvb_get_guint8(tvb, offset);
1603
1604         if(parent_tree){
1605                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1606                         "File Attributes: 0x%02x", mask);
1607                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1608         }
1609         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1610                 tvb, offset, 1, mask);
1611         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1612                 tvb, offset, 1, mask);
1613         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1614                 tvb, offset, 1, mask);
1615         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1616                 tvb, offset, 1, mask);
1617         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1618                 tvb, offset, 1, mask);
1619         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1620                 tvb, offset, 1, mask);
1621
1622         offset += 1;
1623
1624         return offset;
1625 }
1626
1627 static const true_false_string tfs_search_attribute_read_only = {
1628         "Include READ ONLY files in search results",
1629         "Do NOT include read only files in search results",
1630 };
1631 static const true_false_string tfs_search_attribute_hidden = {
1632         "Include HIDDEN files in search results",
1633         "Do NOT include hidden files in search results"
1634 };
1635 static const true_false_string tfs_search_attribute_system = {
1636         "Include SYSTEM files in search results",
1637         "Do NOT include system files in search results"
1638 };
1639 static const true_false_string tfs_search_attribute_volume = {
1640         "Include VOLUME IDs in search results",
1641         "Do NOT include volume IDs in search results"
1642 };
1643 static const true_false_string tfs_search_attribute_directory = {
1644         "Include DIRECTORIES in search results",
1645         "Do NOT include directories in search results"
1646 };
1647 static const true_false_string tfs_search_attribute_archive = {
1648         "Include ARCHIVE files in search results",
1649         "Do NOT include archive files in search results"
1650 };
1651
1652 static int
1653 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1654 {
1655         guint16 mask;
1656         proto_item *item = NULL;
1657         proto_tree *tree = NULL;
1658
1659         mask = tvb_get_letohs(tvb, offset);
1660
1661         if(parent_tree){
1662                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1663                         "Search Attributes: 0x%04x", mask);
1664                 tree = proto_item_add_subtree(item, ett_smb_search);
1665         }
1666
1667         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1668                 tvb, offset, 2, mask);
1669         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1670                 tvb, offset, 2, mask);
1671         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1672                 tvb, offset, 2, mask);  
1673         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1674                 tvb, offset, 2, mask);
1675         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1676                 tvb, offset, 2, mask);
1677         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1678                 tvb, offset, 2, mask);
1679
1680         offset += 2;
1681         return offset;
1682 }
1683
1684 #if 0
1685 /*
1686  * XXX - this isn't used.
1687  * Is this used for anything?  NT Create AndX doesn't use it.
1688  * Is there some 16-bit attribute field with more bits than Read Only,
1689  * Hidden, System, Volume ID, Directory, and Archive?
1690  */
1691 static int
1692 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1693 {
1694         guint32 mask;
1695         proto_item *item = NULL;
1696         proto_tree *tree = NULL;
1697
1698         mask = tvb_get_letohl(tvb, offset);
1699
1700         if(parent_tree){
1701                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1702                         "File Attributes: 0x%08x", mask);
1703                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1704         }
1705         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1706                 tvb, offset, 2, mask);
1707         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1708                 tvb, offset, 2, mask);
1709         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1710                 tvb, offset, 2, mask);
1711         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1712                 tvb, offset, 2, mask);
1713         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1714                 tvb, offset, 2, mask);
1715         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1716                 tvb, offset, 2, mask);
1717         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1718                 tvb, offset, 2, mask);
1719         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1720                 tvb, offset, 2, mask);
1721         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1722                 tvb, offset, 2, mask);
1723         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1724                 tvb, offset, 2, mask);
1725         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1726                 tvb, offset, 2, mask);
1727         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1728                 tvb, offset, 2, mask);
1729         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1730                 tvb, offset, 2, mask);
1731         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1732                 tvb, offset, 2, mask);
1733         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1734                 tvb, offset, 2, mask);
1735
1736         offset += 2;
1737
1738         return offset;
1739 }
1740 #endif
1741
1742
1743 #define SERVER_CAP_RAW_MODE            0x00000001
1744 #define SERVER_CAP_MPX_MODE            0x00000002
1745 #define SERVER_CAP_UNICODE             0x00000004
1746 #define SERVER_CAP_LARGE_FILES         0x00000008
1747 #define SERVER_CAP_NT_SMBS             0x00000010
1748 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1749 #define SERVER_CAP_STATUS32            0x00000040
1750 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1751 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1752 #define SERVER_CAP_NT_FIND             0x00000200
1753 #define SERVER_CAP_DFS                 0x00001000
1754 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1755 #define SERVER_CAP_LARGE_READX         0x00004000
1756 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1757 #define SERVER_CAP_UNIX                0x00800000
1758 #define SERVER_CAP_RESERVED            0x02000000
1759 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1760 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1761 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1762 static const true_false_string tfs_server_cap_raw_mode = {
1763         "Read Raw and Write Raw are supported",
1764         "Read Raw and Write Raw are not supported"
1765 };
1766 static const true_false_string tfs_server_cap_mpx_mode = {
1767         "Read Mpx and Write Mpx are supported",
1768         "Read Mpx and Write Mpx are not supported"
1769 };
1770 static const true_false_string tfs_server_cap_unicode = {
1771         "Unicode strings are supported",
1772         "Unicode strings are not supported"
1773 };
1774 static const true_false_string tfs_server_cap_large_files = {
1775         "Large files are supported",
1776         "Large files are not supported",
1777 };
1778 static const true_false_string tfs_server_cap_nt_smbs = {
1779         "NT SMBs are supported",
1780         "NT SMBs are not supported"
1781 };
1782 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1783         "RPC remote APIs are supported",
1784         "RPC remote APIs are not supported"
1785 };
1786 static const true_false_string tfs_server_cap_nt_status = {
1787         "NT status codes are supported",
1788         "NT status codes are not supported"
1789 };
1790 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1791         "Level 2 oplocks are supported",
1792         "Level 2 oplocks are not supported"
1793 };
1794 static const true_false_string tfs_server_cap_lock_and_read = {
1795         "Lock and Read is supported",
1796         "Lock and Read is not supported"
1797 };
1798 static const true_false_string tfs_server_cap_nt_find = {
1799         "NT Find is supported",
1800         "NT Find is not supported"
1801 };
1802 static const true_false_string tfs_server_cap_dfs = {
1803         "Dfs is supported",
1804         "Dfs is not supported"
1805 };
1806 static const true_false_string tfs_server_cap_infolevel_passthru = {
1807         "NT information level request passthrough is supported",
1808         "NT information level request passthrough is not supported"
1809 };
1810 static const true_false_string tfs_server_cap_large_readx = {
1811         "Large Read andX is supported",
1812         "Large Read andX is not supported"
1813 };
1814 static const true_false_string tfs_server_cap_large_writex = {
1815         "Large Write andX is supported",
1816         "Large Write andX is not supported"
1817 };
1818 static const true_false_string tfs_server_cap_unix = {
1819         "UNIX extensions are supported",
1820         "UNIX extensions are not supported"
1821 };
1822 static const true_false_string tfs_server_cap_reserved = {
1823         "Reserved",
1824         "Reserved"
1825 };
1826 static const true_false_string tfs_server_cap_bulk_transfer = {
1827         "Bulk Read and Bulk Write are supported",
1828         "Bulk Read and Bulk Write are not supported"
1829 };
1830 static const true_false_string tfs_server_cap_compressed_data = {
1831         "Compressed data transfer is supported",
1832         "Compressed data transfer is not supported"
1833 };
1834 static const true_false_string tfs_server_cap_extended_security = {
1835         "Extended security exchanges are supported",
1836         "Extended security exchanges are not supported"
1837 };
1838 static int
1839 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1840 {
1841         guint32 mask;
1842         proto_item *item = NULL;
1843         proto_tree *tree = NULL;
1844
1845         mask = tvb_get_letohl(tvb, offset);
1846
1847         if(parent_tree){
1848                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1849                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1850         }
1851
1852         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1853                 tvb, offset, 4, mask);
1854         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1855                 tvb, offset, 4, mask);
1856         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1857                 tvb, offset, 4, mask);
1858         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1859                 tvb, offset, 4, mask);
1860         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1861                 tvb, offset, 4, mask);
1862         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1863                 tvb, offset, 4, mask);
1864         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1865                 tvb, offset, 4, mask);
1866         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1867                 tvb, offset, 4, mask);
1868         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1869                 tvb, offset, 4, mask);
1870         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1871                 tvb, offset, 4, mask);
1872         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1873                 tvb, offset, 4, mask);
1874         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1875                 tvb, offset, 4, mask);
1876         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1877                 tvb, offset, 4, mask);
1878         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1879                 tvb, offset, 4, mask);
1880         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1881                 tvb, offset, 4, mask);
1882         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1883                 tvb, offset, 4, mask);
1884         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1885                 tvb, offset, 4, mask);
1886         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1887                 tvb, offset, 4, mask);
1888         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1889                 tvb, offset, 4, mask);
1890
1891         return mask;
1892 }
1893
1894 #define RAWMODE_READ   0x01
1895 #define RAWMODE_WRITE  0x02
1896 static const true_false_string tfs_rm_read = {
1897         "Read Raw is supported",
1898         "Read Raw is not supported"
1899 };
1900 static const true_false_string tfs_rm_write = {
1901         "Write Raw is supported",
1902         "Write Raw is not supported"
1903 };
1904
1905 static int
1906 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1907 {
1908         guint16 mask;
1909         proto_item *item = NULL;
1910         proto_tree *tree = NULL;
1911
1912         mask = tvb_get_letohs(tvb, offset);
1913
1914         if(parent_tree){
1915                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1916                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1917         }
1918
1919         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1920         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1921
1922         offset += 2;
1923
1924         return offset;
1925 }
1926
1927 #define SECURITY_MODE_MODE             0x01
1928 #define SECURITY_MODE_PASSWORD         0x02
1929 #define SECURITY_MODE_SIGNATURES       0x04
1930 #define SECURITY_MODE_SIG_REQUIRED     0x08
1931 static const true_false_string tfs_sm_mode = {
1932         "USER security mode",
1933         "SHARE security mode"
1934 };
1935 static const true_false_string tfs_sm_password = {
1936         "ENCRYPTED password. Use challenge/response",
1937         "PLAINTEXT password"
1938 };
1939 static const true_false_string tfs_sm_signatures = {
1940         "Security signatures ENABLED",
1941         "Security signatures NOT enabled"
1942 };
1943 static const true_false_string tfs_sm_sig_required = {
1944         "Security signatures REQUIRED",
1945         "Security signatures NOT required"
1946 };
1947
1948 static int
1949 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1950 {
1951         guint16 mask = 0;
1952         proto_item *item = NULL;
1953         proto_tree *tree = NULL;
1954
1955         switch(wc){
1956         case 13:
1957                 mask = tvb_get_letohs(tvb, offset);
1958                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1959                                 "Security Mode: 0x%04x", mask);
1960                 tree = proto_item_add_subtree(item, ett_smb_mode);
1961                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1962                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1963                 offset += 2;
1964                 break;
1965
1966         case 17:
1967                 mask = tvb_get_guint8(tvb, offset);
1968                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1969                                 "Security Mode: 0x%02x", mask);
1970                 tree = proto_item_add_subtree(item, ett_smb_mode);
1971                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1972                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1973                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1974                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1975                 offset += 1;
1976                 break;
1977         }
1978
1979         return offset;
1980 }
1981
1982 static int
1983 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1984 {
1985         proto_item *it = NULL;
1986         proto_tree *tr = NULL;
1987         guint16 bc;
1988         guint8 wc;
1989
1990         WORD_COUNT;
1991
1992         BYTE_COUNT;
1993
1994         if(tree){
1995                 it = proto_tree_add_text(tree, tvb, offset, bc,
1996                                 "Requested Dialects");
1997                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1998         }
1999
2000         while(bc){
2001                 int len;
2002                 const guint8 *str;
2003                 proto_item *dit = NULL;
2004                 proto_tree *dtr = NULL;
2005
2006                 /* XXX - what if this runs past bc? */
2007                 len = tvb_strsize(tvb, offset+1);
2008                 str = tvb_get_ptr(tvb, offset+1, len);
2009
2010                 if(tr){
2011                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2012                                         "Dialect: %s", str);
2013                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2014                 }
2015
2016                 /* Buffer Format */
2017                 CHECK_BYTE_COUNT(1);
2018                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2019                         TRUE);
2020                 COUNT_BYTES(1);
2021
2022                 /*Dialect Name */
2023                 CHECK_BYTE_COUNT(len);
2024                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2025                         len, str);
2026                 COUNT_BYTES(len);
2027         }
2028
2029         END_OF_SMB
2030
2031         return offset;
2032 }
2033
2034 static int
2035 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2036 {
2037         guint8 wc;
2038         guint16 dialect;
2039         const char *dn;
2040         int dn_len;
2041         guint16 bc;
2042         guint16 ekl=0;
2043         guint32 caps=0;
2044         gint16 tz;
2045
2046         WORD_COUNT;
2047
2048         /* Dialect Index */
2049         dialect = tvb_get_letohs(tvb, offset);
2050         switch(wc){
2051         case 1:
2052                 if(dialect==0xffff){
2053                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2054                                 tvb, offset, 2, dialect,
2055                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2056                 } else {
2057                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2058                                 tvb, offset, 2, dialect);
2059                 }
2060                 break;
2061         case 13:
2062                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2063                         tvb, offset, 2, dialect,
2064                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2065                 break;
2066         case 17:
2067                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2068                         tvb, offset, 2, dialect,
2069                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2070                 break;
2071         default:
2072                 proto_tree_add_text(tree, tvb, offset, wc*2,
2073                         "Words for unknown response format");
2074                 offset += wc*2;
2075                 goto bytecount;
2076         }
2077         offset += 2;
2078
2079         switch(wc){
2080         case 13:
2081                 /* Security Mode */
2082                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
2083                                 wc);
2084
2085                 /* Maximum Transmit Buffer Size */
2086                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2087                         tvb, offset, 2, TRUE);
2088                 offset += 2;
2089
2090                 /* Maximum Multiplex Count */
2091                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2092                         tvb, offset, 2, TRUE);
2093                 offset += 2;
2094
2095                 /* Maximum Vcs Number */
2096                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2097                         tvb, offset, 2, TRUE);
2098                 offset += 2;
2099
2100                 /* raw mode */
2101                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
2102
2103                 /* session key */
2104                 proto_tree_add_item(tree, hf_smb_session_key,
2105                         tvb, offset, 4, TRUE);
2106                 offset += 4;
2107
2108                 /* current time and date at server */
2109                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2110                     TRUE);
2111
2112                 /* time zone */
2113                 tz = tvb_get_letohs(tvb, offset);
2114                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2115                 offset += 2;
2116
2117                 /* encryption key length */
2118                 ekl = tvb_get_letohs(tvb, offset);
2119                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2120                 offset += 2;
2121
2122                 /* 2 reserved bytes */
2123                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2124                 offset += 2;
2125
2126                 break;
2127
2128         case 17:
2129                 /* Security Mode */
2130                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
2131
2132                 /* Maximum Multiplex Count */
2133                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2134                         tvb, offset, 2, TRUE);
2135                 offset += 2;
2136
2137                 /* Maximum Vcs Number */
2138                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2139                         tvb, offset, 2, TRUE);
2140                 offset += 2;
2141
2142                 /* Maximum Transmit Buffer Size */
2143                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2144                         tvb, offset, 4, TRUE);
2145                 offset += 4;
2146
2147                 /* maximum raw buffer size */
2148                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2149                         tvb, offset, 4, TRUE);
2150                 offset += 4;
2151
2152                 /* session key */
2153                 proto_tree_add_item(tree, hf_smb_session_key,
2154                         tvb, offset, 4, TRUE);
2155                 offset += 4;
2156
2157                 /* server capabilities */
2158                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
2159                 offset += 4;
2160
2161                 /* system time */
2162                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
2163                                 hf_smb_system_time);
2164
2165                 /* time zone */
2166                 tz = tvb_get_letohs(tvb, offset);
2167                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2168                         tvb, offset, 2, tz,
2169                         "Server Time Zone: %d min from UTC", tz);
2170                 offset += 2;
2171
2172                 /* encryption key length */
2173                 ekl = tvb_get_guint8(tvb, offset);
2174                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2175                         tvb, offset, 1, ekl);
2176                 offset += 1;
2177
2178                 break;
2179         }
2180
2181         BYTE_COUNT;
2182
2183         switch(wc){
2184         case 13:
2185                 /* challenge/response encryption key */
2186                 if(ekl){
2187                         CHECK_BYTE_COUNT(ekl);
2188                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2189                         COUNT_BYTES(ekl);
2190                 }
2191
2192                 /* domain */
2193                 dn = get_unicode_or_ascii_string(tvb, &offset,
2194                         pinfo, &dn_len, FALSE, FALSE, &bc);
2195                 if (dn == NULL)
2196                         goto endofcommand;
2197                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2198                         offset, dn_len,dn);
2199                 COUNT_BYTES(dn_len);
2200                 break;
2201
2202         case 17:
2203                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2204                         smb_info_t *si;
2205
2206                         /* challenge/response encryption key */
2207                         /* XXX - is this aligned on an even boundary? */
2208                         if(ekl){
2209                                 CHECK_BYTE_COUNT(ekl);
2210                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2211                                         tvb, offset, ekl, TRUE);
2212                                 COUNT_BYTES(ekl);
2213                         }
2214
2215                         /* domain */
2216                         /* this string is special, unicode is flagged in caps */
2217                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2218                         si = pinfo->private_data;
2219                         si->unicode = (caps&SERVER_CAP_UNICODE);
2220                         dn = get_unicode_or_ascii_string(tvb,
2221                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2222                                 &bc);
2223                         if (dn == NULL)
2224                                 goto endofcommand;
2225                         proto_tree_add_string(tree, hf_smb_primary_domain,
2226                                 tvb, offset, dn_len, dn);
2227                         COUNT_BYTES(dn_len);
2228                 } else {
2229                         /* guid */
2230                         /* XXX - show it in the standard Microsoft format
2231                            for GUIDs? */
2232                         CHECK_BYTE_COUNT(16);
2233                         proto_tree_add_item(tree, hf_smb_server_guid,
2234                                 tvb, offset, 16, TRUE);
2235                         COUNT_BYTES(16);
2236
2237                         /* security blob */
2238                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2239                            data structure, at least in NT 5.0-and-later
2240                            server replies? */
2241                         if(bc){
2242                                 proto_tree_add_item(tree, hf_smb_security_blob,
2243                                         tvb, offset, bc, TRUE);
2244                                 COUNT_BYTES(bc);
2245                         }
2246                 }
2247                 break;
2248         }
2249
2250         END_OF_SMB
2251
2252         return offset;
2253 }
2254
2255
2256 static int
2257 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2258 {
2259         int dn_len;
2260         const char *dn;
2261         guint8 wc;
2262         guint16 bc;
2263
2264         WORD_COUNT;
2265  
2266         BYTE_COUNT;
2267
2268         /* buffer format */
2269         CHECK_BYTE_COUNT(1);
2270         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2271         COUNT_BYTES(1);
2272
2273         /* dir name */
2274         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2275                 FALSE, FALSE, &bc);
2276         if (dn == NULL)
2277                 goto endofcommand;
2278         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2279                 dn);
2280         COUNT_BYTES(dn_len);
2281
2282         if (check_col(pinfo->cinfo, COL_INFO)) {
2283                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2284         }
2285
2286         END_OF_SMB
2287
2288         return offset;
2289 }
2290
2291 static int
2292 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2293 {
2294         guint8 wc;
2295         guint16 bc;
2296  
2297         WORD_COUNT;
2298  
2299         BYTE_COUNT;
2300
2301         END_OF_SMB
2302
2303         return offset;
2304 }
2305
2306 static int
2307 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2308 {
2309         guint16 ec, bc;
2310         guint8 wc;
2311
2312         WORD_COUNT;
2313
2314         /* echo count */
2315         ec = tvb_get_letohs(tvb, offset);
2316         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2317         offset += 2;
2318
2319         BYTE_COUNT;
2320
2321         if (bc != 0) {
2322                 /* echo data */
2323                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2324                 COUNT_BYTES(bc);
2325         }
2326
2327         END_OF_SMB
2328
2329         return offset;
2330 }
2331
2332 static int
2333 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2334 {
2335         guint16 bc;
2336         guint8 wc;
2337
2338         WORD_COUNT;
2339
2340         /* echo sequence number */
2341         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2342         offset += 2;
2343
2344         BYTE_COUNT;
2345
2346         if (bc != 0) {
2347                 /* echo data */
2348                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2349                 COUNT_BYTES(bc);
2350         }
2351
2352         END_OF_SMB
2353
2354         return offset;
2355 }
2356
2357 static int
2358 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2359 {
2360         int an_len, pwlen;
2361         const char *an;
2362         guint8 wc;
2363         guint16 bc;
2364
2365         WORD_COUNT;
2366  
2367         BYTE_COUNT;
2368
2369         /* buffer format */
2370         CHECK_BYTE_COUNT(1);
2371         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2372         COUNT_BYTES(1);
2373
2374         /* Path */
2375         an = get_unicode_or_ascii_string(tvb, &offset,
2376                 pinfo, &an_len, FALSE, FALSE, &bc);
2377         if (an == NULL)
2378                 goto endofcommand;
2379         proto_tree_add_string(tree, hf_smb_path, tvb,
2380                 offset, an_len, an);
2381         COUNT_BYTES(an_len);
2382
2383         if (check_col(pinfo->cinfo, COL_INFO)) {
2384                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2385         }
2386
2387         /* buffer format */
2388         CHECK_BYTE_COUNT(1);
2389         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2390         COUNT_BYTES(1);
2391
2392         /* password, ANSI */
2393         /* XXX - what if this runs past bc? */
2394         pwlen = tvb_strsize(tvb, offset);
2395         CHECK_BYTE_COUNT(pwlen);
2396         proto_tree_add_item(tree, hf_smb_password,
2397                 tvb, offset, pwlen, TRUE);
2398         COUNT_BYTES(pwlen);
2399
2400         /* buffer format */
2401         CHECK_BYTE_COUNT(1);
2402         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2403         COUNT_BYTES(1);
2404
2405         /* Service */
2406         an = get_unicode_or_ascii_string(tvb, &offset,
2407                 pinfo, &an_len, FALSE, FALSE, &bc);
2408         if (an == NULL)
2409                 goto endofcommand;
2410         proto_tree_add_string(tree, hf_smb_service, tvb,
2411                 offset, an_len, an);
2412         COUNT_BYTES(an_len);
2413
2414         END_OF_SMB
2415
2416         return offset;
2417 }
2418
2419 static int
2420 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2421 {
2422         guint8 wc;
2423         guint16 bc;
2424
2425         WORD_COUNT;
2426  
2427         /* Maximum Buffer Size */
2428         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2429         offset += 2;
2430
2431         /* tid */
2432         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2433         offset += 2;
2434
2435         BYTE_COUNT;
2436
2437         END_OF_SMB
2438
2439         return offset;
2440 }
2441  
2442
2443 static const true_false_string tfs_of_create = {
2444         "Create file if it does not exist",
2445         "Fail if file does not exist"
2446 };
2447 static const value_string of_open[] = {
2448         { 0,            "Fail if file exists"},
2449         { 1,            "Open file if it exists"},
2450         { 2,            "Truncate file if it exists"},
2451         {0, NULL}
2452 };
2453 static int
2454 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2455 {
2456         guint16 mask;
2457         proto_item *item = NULL;
2458         proto_tree *tree = NULL;
2459
2460         mask = tvb_get_letohs(tvb, offset);
2461
2462         if(parent_tree){
2463                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2464                         "Open Function: 0x%04x", mask);
2465                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2466         }
2467
2468         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2469                 tvb, offset, 2, mask);
2470         proto_tree_add_uint(tree, hf_smb_open_function_open,
2471                 tvb, offset, 2, mask);
2472
2473         offset += 2;
2474
2475         return offset;
2476 }
2477
2478
2479 static const true_false_string tfs_mf_file = {
2480         "Target must be a file",
2481         "Target needn't be a file"
2482  };
2483 static const true_false_string tfs_mf_dir = {
2484         "Target must be a directory",
2485         "Target needn't be a directory"
2486 };
2487 static const true_false_string tfs_mf_verify = {
2488         "MUST verify all writes",
2489         "Don't have to verify writes"
2490 };
2491 static int
2492 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2493 {
2494         guint16 mask;
2495         proto_item *item = NULL;
2496         proto_tree *tree = NULL;
2497
2498         mask = tvb_get_letohs(tvb, offset);
2499
2500         if(parent_tree){
2501                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2502                         "Flags: 0x%04x", mask);
2503                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2504         }
2505  
2506         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2507                 tvb, offset, 2, mask);
2508         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2509                 tvb, offset, 2, mask);
2510         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2511                 tvb, offset, 2, mask);
2512
2513         offset += 2;
2514
2515         return offset;
2516 }
2517
2518 static int
2519 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2520 {
2521         int fn_len;
2522         guint16 tid;
2523         guint16 bc;
2524         guint8 wc;
2525         const char *fn;
2526
2527         WORD_COUNT;
2528
2529         /* tid */
2530         tid = tvb_get_letohs(tvb, offset);
2531         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2532                 "TID (target): 0x%04x", tid);
2533         offset += 2;
2534
2535         /* open function */
2536         offset = dissect_open_function(tvb, pinfo, tree, offset);
2537
2538         /* move flags */
2539         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2540
2541         BYTE_COUNT;
2542
2543         /* buffer format */
2544         CHECK_BYTE_COUNT(1);
2545         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2546         COUNT_BYTES(1);
2547
2548         /* file name */
2549         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2550                 FALSE, FALSE, &bc);
2551         if (fn == NULL)
2552                 goto endofcommand;
2553         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2554                 fn_len, fn, "Old File Name: %s", fn);
2555         COUNT_BYTES(fn_len);
2556
2557         if (check_col(pinfo->cinfo, COL_INFO)) {
2558                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2559         }
2560
2561         /* buffer format */
2562         CHECK_BYTE_COUNT(1);
2563         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2564         COUNT_BYTES(1);
2565
2566         /* file name */
2567         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2568                 FALSE, FALSE, &bc);
2569         if (fn == NULL)
2570                 goto endofcommand;
2571         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2572                 fn_len, fn, "New File Name: %s", fn);
2573         COUNT_BYTES(fn_len);
2574
2575         if (check_col(pinfo->cinfo, COL_INFO)) {
2576                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2577         }
2578
2579         END_OF_SMB
2580
2581         return offset;
2582 }
2583
2584 static int
2585 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2586 {
2587         int fn_len;
2588         const char *fn;
2589         guint8 wc;
2590         guint16 bc;
2591
2592         WORD_COUNT;
2593
2594         /* # of files moved */
2595         proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
2596         offset += 2;
2597
2598         BYTE_COUNT;
2599
2600         /* buffer format */
2601         CHECK_BYTE_COUNT(1);
2602         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2603         COUNT_BYTES(1);
2604
2605         /* file name */
2606         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2607                 FALSE, FALSE, &bc);
2608         if (fn == NULL)
2609                 goto endofcommand;
2610         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2611                 fn);
2612         COUNT_BYTES(fn_len);
2613
2614         END_OF_SMB
2615
2616         return offset;
2617 }
2618
2619 static int
2620 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2621 {
2622         int fn_len;
2623         const char *fn;
2624         guint8 wc;
2625         guint16 bc;
2626
2627         WORD_COUNT;
2628
2629         /* desired access */
2630         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2631
2632         /* Search Attributes */
2633         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2634
2635         BYTE_COUNT;
2636
2637         /* buffer format */
2638         CHECK_BYTE_COUNT(1);
2639         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2640         COUNT_BYTES(1);
2641
2642         /* file name */
2643         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2644                 FALSE, FALSE, &bc);
2645         if (fn == NULL)
2646                 goto endofcommand;
2647         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2648                 fn);
2649         COUNT_BYTES(fn_len);
2650
2651         if (check_col(pinfo->cinfo, COL_INFO)) {
2652                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2653         }
2654
2655         END_OF_SMB
2656
2657         return offset;
2658 }
2659
2660 void
2661 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2662     int len, guint16 fid)
2663 {
2664         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2665         if (check_col(pinfo->cinfo, COL_INFO))
2666                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2667 }
2668
2669 static int
2670 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2671 {
2672         guint8 wc;
2673         guint16 bc;
2674         guint16 fid;
2675
2676         WORD_COUNT;
2677
2678         /* fid */
2679         fid = tvb_get_letohs(tvb, offset);
2680         add_fid(tvb, pinfo, tree, offset, 2, fid);
2681         offset += 2;
2682
2683         /* File Attributes */
2684         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2685
2686         /* last write time */
2687         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2688         
2689         /* File Size */
2690         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2691         offset += 4;
2692
2693         /* granted access */
2694         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2695
2696         BYTE_COUNT;
2697
2698         END_OF_SMB
2699
2700         return offset;
2701 }
2702
2703 static int
2704 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2705 {
2706         guint8 wc;
2707         guint16 bc;
2708         guint16 fid;
2709
2710         WORD_COUNT;
2711
2712         /* fid */
2713         fid = tvb_get_letohs(tvb, offset);
2714         add_fid(tvb, pinfo, tree, offset, 2, fid);
2715         offset += 2;
2716
2717         BYTE_COUNT;
2718
2719         END_OF_SMB
2720
2721         return offset;
2722 }
2723
2724 static int
2725 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2726 {
2727         int fn_len;
2728         const char *fn;
2729         guint8 wc;
2730         guint16 bc;
2731
2732         WORD_COUNT;
2733
2734         /* file attributes */
2735         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2736
2737         /* creation time */
2738         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2739
2740         BYTE_COUNT;
2741
2742         /* buffer format */
2743         CHECK_BYTE_COUNT(1);
2744         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2745         COUNT_BYTES(1);
2746
2747         /* File Name */
2748         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2749                 FALSE, FALSE, &bc);
2750         if (fn == NULL)
2751                 goto endofcommand;
2752         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2753                 fn);
2754         COUNT_BYTES(fn_len);
2755
2756         if (check_col(pinfo->cinfo, COL_INFO)) {
2757                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2758         }
2759
2760         END_OF_SMB
2761
2762         return offset;
2763 }
2764
2765 static int
2766 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2767 {
2768         guint8 wc;
2769         guint16 bc, fid;
2770
2771         WORD_COUNT;
2772
2773         /* fid */
2774         fid = tvb_get_letohs(tvb, offset);
2775         add_fid(tvb, pinfo, tree, offset, 2, fid);
2776         offset += 2;
2777
2778         /* last write time */
2779         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2780
2781         BYTE_COUNT;
2782
2783         END_OF_SMB
2784
2785         return offset;
2786 }
2787
2788 static int
2789 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2790 {
2791         int fn_len;
2792         const char *fn;
2793         guint8 wc;
2794         guint16 bc;
2795
2796         WORD_COUNT;
2797
2798         /* search attributes */
2799         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2800
2801         BYTE_COUNT;
2802
2803         /* buffer format */
2804         CHECK_BYTE_COUNT(1);
2805         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2806         COUNT_BYTES(1);
2807
2808         /* file name */
2809         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2810                 FALSE, FALSE, &bc);
2811         if (fn == NULL)
2812                 goto endofcommand;
2813         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2814                 fn);
2815         COUNT_BYTES(fn_len);
2816
2817         if (check_col(pinfo->cinfo, COL_INFO)) {
2818                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2819         }
2820
2821         END_OF_SMB
2822
2823         return offset;
2824 }
2825
2826 static int
2827 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2828 {
2829         int fn_len;
2830         const char *fn;
2831         guint8 wc;
2832         guint16 bc;
2833
2834         WORD_COUNT;
2835
2836         /* search attributes */
2837         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2838
2839         BYTE_COUNT;
2840
2841         /* buffer format */
2842         CHECK_BYTE_COUNT(1);
2843         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2844         COUNT_BYTES(1);
2845
2846         /* old file name */
2847         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2848                 FALSE, FALSE, &bc);
2849         if (fn == NULL)
2850                 goto endofcommand;
2851         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2852                 fn);
2853         COUNT_BYTES(fn_len);
2854
2855         if (check_col(pinfo->cinfo, COL_INFO)) {
2856                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2857         }
2858
2859         /* buffer format */
2860         CHECK_BYTE_COUNT(1);
2861         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2862         COUNT_BYTES(1);
2863
2864         /* file name */
2865         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2866                 FALSE, FALSE, &bc);
2867         if (fn == NULL)
2868                 goto endofcommand;
2869         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2870                 fn);
2871         COUNT_BYTES(fn_len);
2872
2873         if (check_col(pinfo->cinfo, COL_INFO)) {
2874                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2875         }
2876
2877         END_OF_SMB
2878
2879         return offset;
2880 }
2881
2882 static int
2883 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2884 {
2885         int fn_len;
2886         const char *fn;
2887         guint8 wc;
2888         guint16 bc;
2889
2890         WORD_COUNT;
2891
2892         /* search attributes */
2893         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2894  
2895     proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
2896     offset += 2;
2897
2898     proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
2899     offset += 4;
2900
2901         BYTE_COUNT;
2902
2903         /* buffer format */
2904         CHECK_BYTE_COUNT(1);
2905         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2906         COUNT_BYTES(1);
2907
2908         /* old file name */
2909         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2910                 FALSE, FALSE, &bc);
2911         if (fn == NULL)
2912                 goto endofcommand;
2913         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2914                 fn);
2915         COUNT_BYTES(fn_len);
2916
2917         if (check_col(pinfo->cinfo, COL_INFO)) {
2918                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2919         }
2920
2921         /* buffer format */
2922         CHECK_BYTE_COUNT(1);
2923         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2924         COUNT_BYTES(1);
2925
2926         /* file name */
2927         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2928                 FALSE, FALSE, &bc);
2929         if (fn == NULL)
2930                 goto endofcommand;
2931         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2932                 fn);
2933         COUNT_BYTES(fn_len);
2934
2935         if (check_col(pinfo->cinfo, COL_INFO)) {
2936                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2937         }
2938
2939         END_OF_SMB
2940
2941         return offset;
2942 }
2943
2944
2945 static int
2946 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2947 {
2948         guint16 bc;
2949         guint8 wc;
2950         const char *fn;
2951         int fn_len;
2952
2953         WORD_COUNT;
2954
2955         BYTE_COUNT;
2956
2957         /* Buffer Format */
2958         CHECK_BYTE_COUNT(1);
2959         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2960         COUNT_BYTES(1);
2961
2962         /* File Name */
2963         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2964                 FALSE, FALSE, &bc);
2965         if (fn == NULL)
2966                 goto endofcommand;
2967         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2968                 fn);
2969         COUNT_BYTES(fn_len);
2970
2971         if (check_col(pinfo->cinfo, COL_INFO)) {
2972                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2973         }
2974
2975         END_OF_SMB
2976
2977         return offset;
2978 }
2979  
2980 static int
2981 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2982 {
2983         guint16 bc;
2984         guint8 wc;
2985
2986         WORD_COUNT;
2987
2988         /* File Attributes */
2989         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2990
2991         /* Last Write Time */
2992         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2993
2994         /* File Size */
2995         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2996         offset += 4;
2997
2998         /* 10 reserved bytes */
2999         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3000         offset += 10;
3001
3002         BYTE_COUNT;
3003
3004         END_OF_SMB
3005
3006         return offset;
3007 }
3008
3009 static int
3010 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3011 {
3012         int fn_len;
3013         const char *fn;
3014         guint8 wc;
3015         guint16 bc;
3016
3017         WORD_COUNT;
3018
3019         /* file attributes */
3020         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3021
3022         /* last write time */
3023         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3024
3025         /* 10 reserved bytes */
3026         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3027         offset += 10;
3028
3029         BYTE_COUNT;
3030
3031         /* buffer format */
3032         CHECK_BYTE_COUNT(1);
3033         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3034         COUNT_BYTES(1);
3035
3036         /* file name */
3037         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3038                 FALSE, FALSE, &bc);
3039         if (fn == NULL)
3040                 goto endofcommand;
3041         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3042                 fn);
3043         COUNT_BYTES(fn_len);
3044
3045         if (check_col(pinfo->cinfo, COL_INFO)) {
3046                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3047         }
3048
3049         END_OF_SMB
3050
3051         return offset;
3052 }
3053
3054 static int
3055 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3056 {
3057         guint8 wc;
3058         guint16 bc;
3059         smb_info_t *si;
3060         unsigned int fid;
3061
3062         WORD_COUNT;
3063
3064         /* fid */
3065         fid = tvb_get_letohs(tvb, offset);
3066         add_fid(tvb, pinfo, tree, offset, 2, fid);
3067         offset += 2;
3068         if (!pinfo->fd->flags.visited) {
3069                 /* remember the FID for the processing of the response */
3070                 si = (smb_info_t *)pinfo->private_data;
3071                 si->sip->extra_info=(void *)fid;
3072         }
3073
3074         /* read count */
3075         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3076         offset += 2;
3077
3078         /* offset */
3079         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3080         offset += 4;
3081
3082         /* remaining */
3083         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3084         offset += 2;
3085
3086         BYTE_COUNT;
3087
3088         END_OF_SMB
3089
3090         return offset;
3091 }
3092
3093 int
3094 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3095 {
3096         int tvblen;
3097
3098         if(bc>datalen){
3099                 /* We have some initial padding bytes. */
3100                 /* XXX - use the data offset here instead? */
3101                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3102                         TRUE);
3103                 offset += bc-datalen;
3104                 bc = datalen;
3105         }
3106         tvblen = tvb_length_remaining(tvb, offset);
3107         if(bc>tvblen){
3108                 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);
3109                 offset += tvblen;
3110         } else {
3111                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3112                 offset += bc;
3113         }
3114         return offset;
3115 }
3116
3117 static int
3118 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3119     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3120 {
3121         int tvblen;
3122         tvbuff_t *dcerpc_tvb;
3123
3124         if(bc>datalen){
3125                 /* We have some initial padding bytes. */
3126                 /* XXX - use the data offset here instead? */
3127                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3128                         TRUE);
3129                 offset += bc-datalen;
3130                 bc = datalen;
3131         }
3132         tvblen = tvb_length_remaining(tvb, offset);
3133         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3134         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3135         if(bc>tvblen)
3136                 offset += tvblen;
3137         else
3138                 offset += bc;
3139         return offset;
3140 }
3141
3142 static int
3143 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3144 {
3145         guint16 cnt=0, bc;
3146         guint8 wc;
3147         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3148         int fid=0;
3149
3150         WORD_COUNT;
3151
3152         /* read count */
3153         cnt = tvb_get_letohs(tvb, offset);
3154         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3155         offset += 2;
3156
3157         /* 8 reserved bytes */
3158         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3159         offset += 8;
3160
3161         /* If we have seen the request, then print which FID this refers to */
3162         /* first check if we have seen the request */
3163         if(si->sip != NULL && si->sip->frame_req>0){
3164                 fid=(int)si->sip->extra_info;
3165                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3166         }
3167
3168         BYTE_COUNT;
3169
3170         /* buffer format */
3171         CHECK_BYTE_COUNT(1);
3172         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3173         COUNT_BYTES(1);
3174
3175         /* data len */
3176         CHECK_BYTE_COUNT(2);
3177         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3178         COUNT_BYTES(2);
3179
3180         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3181            read write */
3182         if(bc){
3183                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3184                         /* dcerpc call */
3185                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3186                             top_tree, offset, bc, bc, fid);
3187                 } else {
3188                         /* ordinary file data, or we didn't see the request,
3189                            so we don't know whether this is a DCERPC call
3190                            or not */
3191                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3192                 }
3193                 bc = 0;
3194         }
3195
3196         END_OF_SMB
3197
3198         return offset;
3199 }
3200
3201 static int
3202 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3203 {
3204         guint16 cnt, bc;
3205         guint8 wc;
3206
3207         WORD_COUNT;
3208
3209         /* read count */
3210         cnt = tvb_get_letohs(tvb, offset);
3211         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3212         offset += 2;
3213
3214         /* 8 reserved bytes */
3215         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3216         offset += 8;
3217
3218         BYTE_COUNT;
3219
3220         /* buffer format */
3221         CHECK_BYTE_COUNT(1);
3222         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3223         COUNT_BYTES(1);
3224
3225         /* data len */
3226         CHECK_BYTE_COUNT(2);
3227         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3228         COUNT_BYTES(2);
3229
3230         END_OF_SMB
3231
3232         return offset;
3233 }
3234
3235
3236 static int
3237 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3238 {
3239         guint32 ofs=0;
3240         guint16 cnt=0, bc, fid=0;
3241         guint8 wc;
3242         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3243
3244         WORD_COUNT;
3245
3246         /* fid */
3247         fid = tvb_get_letohs(tvb, offset);
3248         add_fid(tvb, pinfo, tree, offset, 2, fid);
3249         offset += 2;
3250
3251         /* write count */
3252         cnt = tvb_get_letohs(tvb, offset);
3253         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3254         offset += 2;
3255
3256         /* offset */
3257         ofs = tvb_get_letohl(tvb, offset);
3258         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3259         offset += 4;
3260
3261         if (check_col(pinfo->cinfo, COL_INFO))
3262                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3263                                 ", %d byte%s at offset %d", cnt, 
3264                                 (cnt == 1) ? "" : "s", ofs);
3265
3266         /* remaining */
3267         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3268         offset += 2;
3269
3270         BYTE_COUNT;
3271
3272         /* buffer format */
3273         CHECK_BYTE_COUNT(1);
3274         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3275         COUNT_BYTES(1);
3276
3277         /* data len */
3278         CHECK_BYTE_COUNT(2);
3279         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3280         COUNT_BYTES(2);
3281
3282         if (bc != 0) {
3283                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3284                         /* dcerpc call */
3285                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3286                             top_tree, offset, bc, bc, fid);
3287                 } else {
3288                         /* ordinary file data */
3289                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3290                 }
3291                 bc = 0;
3292         }
3293
3294         END_OF_SMB
3295
3296         return offset;
3297 }
3298  
3299 static int
3300 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3301 {
3302         guint8 wc;
3303         guint16 bc, cnt;
3304
3305         WORD_COUNT;
3306
3307         /* write count */
3308         cnt = tvb_get_letohs(tvb, offset);
3309         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3310         offset += 2;
3311
3312         if (check_col(pinfo->cinfo, COL_INFO))
3313                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3314                                 ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
3315
3316         BYTE_COUNT;
3317
3318         END_OF_SMB
3319
3320         return offset;
3321 }
3322
3323 static int
3324 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3325 {
3326         guint8 wc;
3327         guint16 bc, fid;
3328
3329         WORD_COUNT;
3330
3331         /* fid */
3332         fid = tvb_get_letohs(tvb, offset);
3333         add_fid(tvb, pinfo, tree, offset, 2, fid);
3334         offset += 2;
3335
3336         /* lock count */
3337         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3338         offset += 4;
3339
3340         /* offset */
3341         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3342         offset += 4;
3343
3344         BYTE_COUNT;
3345
3346         END_OF_SMB
3347
3348         return offset;
3349 }
3350
3351 static int
3352 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3353 {
3354         int fn_len;
3355         const char *fn;
3356         guint8 wc;
3357         guint16 bc;
3358
3359         WORD_COUNT;
3360
3361         /* 2 reserved bytes */
3362         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3363         offset += 2;
3364
3365         /* Creation time */
3366         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3367
3368         BYTE_COUNT;
3369
3370         /* buffer format */
3371         CHECK_BYTE_COUNT(1);
3372         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3373         COUNT_BYTES(1);
3374
3375         /* directory name */
3376         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3377                 FALSE, FALSE, &bc);
3378         if (fn == NULL)
3379                 goto endofcommand;
3380         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3381                 fn);
3382         COUNT_BYTES(fn_len);
3383
3384         if (check_col(pinfo->cinfo, COL_INFO)) {
3385                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3386         }
3387
3388         END_OF_SMB
3389
3390         return offset;
3391 }
3392
3393 static int
3394 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3395 {
3396         int fn_len;
3397         const char *fn;
3398         guint8 wc;
3399         guint16 bc, fid;
3400
3401         WORD_COUNT;
3402
3403         /* fid */
3404         fid = tvb_get_letohs(tvb, offset);
3405         add_fid(tvb, pinfo, tree, offset, 2, fid);
3406         offset += 2;
3407
3408         BYTE_COUNT;
3409
3410         /* buffer format */
3411         CHECK_BYTE_COUNT(1);
3412         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3413         COUNT_BYTES(1);
3414
3415         /* file name */
3416         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3417                 FALSE, FALSE, &bc);
3418         if (fn == NULL)
3419                 goto endofcommand;
3420         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3421                 fn);
3422         COUNT_BYTES(fn_len);
3423
3424         END_OF_SMB
3425
3426         return offset;
3427 }
3428
3429 static const value_string seek_mode_vals[] = {
3430         {0,     "From Start Of File"},
3431         {1,     "From Current Position"},
3432         {2,     "From End Of File"},
3433         {0,     NULL}
3434 };
3435
3436 static int
3437 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3438 {
3439         guint8 wc;
3440         guint16 bc, fid;
3441
3442         WORD_COUNT;
3443
3444         /* fid */
3445         fid = tvb_get_letohs(tvb, offset);
3446         add_fid(tvb, pinfo, tree, offset, 2, fid);
3447         offset += 2;
3448
3449         /* Seek Mode */
3450         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3451         offset += 2;
3452
3453         /* offset */
3454         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3455         offset += 4;
3456
3457         BYTE_COUNT;
3458
3459         END_OF_SMB
3460
3461         return offset;
3462 }
3463
3464 static int
3465 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3466 {
3467         guint8 wc;
3468         guint16 bc;
3469
3470         WORD_COUNT;
3471
3472         /* offset */
3473         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3474         offset += 4;
3475
3476         BYTE_COUNT;
3477
3478         END_OF_SMB
3479
3480         return offset;
3481 }
3482  
3483 static int
3484 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3485 {
3486         guint8 wc;
3487         guint16 bc, fid;
3488
3489         WORD_COUNT;
3490
3491         /* fid */
3492         fid = tvb_get_letohs(tvb, offset);
3493         add_fid(tvb, pinfo, tree, offset, 2, fid);
3494         offset += 2;
3495
3496         /* create time */
3497         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3498                 hf_smb_create_time,
3499                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3500
3501         /* access time */
3502         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3503                 hf_smb_access_time,
3504                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3505
3506         /* last write time */
3507         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3508                 hf_smb_last_write_time,
3509                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3510
3511         BYTE_COUNT;
3512
3513         END_OF_SMB
3514
3515         return offset;
3516 }
3517
3518 static int
3519 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3520 {
3521         guint8 wc;
3522         guint16 bc;
3523
3524         WORD_COUNT;
3525
3526         /* create time */
3527         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3528                 hf_smb_create_time,
3529                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3530
3531         /* access time */
3532         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3533                 hf_smb_access_time,
3534                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3535
3536         /* last write time */
3537         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3538                 hf_smb_last_write_time,
3539                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3540
3541         /* data size */
3542         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3543         offset += 4;
3544
3545         /* allocation size */
3546         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3547         offset += 4;
3548
3549         /* File Attributes */
3550         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3551
3552         BYTE_COUNT;
3553
3554         END_OF_SMB
3555
3556         return offset;
3557 }
3558
3559 static int
3560 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3561 {
3562         guint8 wc;
3563         guint16 cnt=0;
3564         guint16 bc, fid;
3565
3566         WORD_COUNT;
3567
3568         /* fid */
3569         fid = tvb_get_letohs(tvb, offset);
3570         add_fid(tvb, pinfo, tree, offset, 2, fid);
3571         offset += 2;
3572
3573         /* write count */
3574         cnt = tvb_get_letohs(tvb, offset);
3575         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3576         offset += 2;
3577
3578         /* offset */
3579         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3580         offset += 4;
3581
3582         /* last write time */
3583         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3584         
3585         if(wc==12){
3586                 /* 12 reserved bytes */
3587                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3588                 offset += 12;
3589         }
3590
3591         BYTE_COUNT;
3592
3593         /* 1 pad byte */
3594         CHECK_BYTE_COUNT(1);
3595         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3596         COUNT_BYTES(1);
3597         
3598         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3599         bc = 0; /* XXX */
3600
3601         END_OF_SMB
3602
3603         return offset;
3604 }
3605  
3606 static int
3607 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3608 {
3609         guint8 wc;
3610         guint16 bc;
3611
3612         WORD_COUNT;
3613
3614         /* write count */
3615         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3616         offset += 2;
3617
3618         BYTE_COUNT;
3619
3620         END_OF_SMB
3621
3622         return offset;
3623 }
3624
3625 static int
3626 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3627 {
3628         guint8 wc;
3629         guint16 bc, fid;
3630         guint32 to;
3631
3632         WORD_COUNT;
3633
3634         /* fid */
3635         fid = tvb_get_letohs(tvb, offset);
3636         add_fid(tvb, pinfo, tree, offset, 2, fid);
3637         offset += 2;
3638
3639         /* offset */
3640         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3641         offset += 4;
3642
3643         /* max count */
3644         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3645         offset += 2;
3646
3647         /* min count */
3648         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3649         offset += 2;
3650
3651         /* timeout */
3652         to = tvb_get_letohl(tvb, offset);
3653         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3654         offset += 4;
3655
3656         /* 2 reserved bytes */
3657         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3658         offset += 2;
3659
3660         if(wc==10){
3661                 /* high offset */
3662                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3663                 offset += 4;
3664         }
3665
3666         BYTE_COUNT;
3667
3668         END_OF_SMB
3669
3670         return offset;
3671 }
3672
3673 static int
3674 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3675 {
3676         guint8 wc;
3677         guint16 bc;
3678
3679         WORD_COUNT;
3680
3681         /* units */
3682         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3683         offset += 2;
3684
3685         /* bpu */
3686         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3687         offset += 2;
3688
3689         /* block size */
3690         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3691         offset += 2;
3692
3693         /* free units */
3694         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3695         offset += 2;
3696
3697         /* 2 reserved bytes */
3698         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3699         offset += 2;
3700
3701         BYTE_COUNT;
3702
3703         END_OF_SMB
3704
3705         return offset;
3706 }
3707
3708 static int
3709 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3710 {
3711         guint8 wc;
3712         guint16 bc, fid;
3713
3714         WORD_COUNT;
3715
3716         /* fid */
3717         fid = tvb_get_letohs(tvb, offset);
3718         add_fid(tvb, pinfo, tree, offset, 2, fid);
3719         offset += 2;
3720
3721         /* offset */
3722         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3723         offset += 4;
3724
3725         /* max count */
3726         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3727         offset += 2;
3728
3729         /* min count */
3730         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3731         offset += 2;
3732
3733         /* 6 reserved bytes */
3734         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3735         offset += 6;
3736
3737         BYTE_COUNT;
3738
3739         END_OF_SMB
3740
3741         return offset;
3742 }
3743
3744 static int
3745 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3746 {
3747         guint16 datalen=0, bc;
3748         guint8 wc;
3749
3750         WORD_COUNT;
3751
3752         /* offset */
3753         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3754         offset += 4;
3755
3756         /* count */
3757         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3758         offset += 2;
3759
3760         /* 2 reserved bytes */
3761         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3762         offset += 2;
3763
3764         /* data compaction mode */
3765         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3766         offset += 2;
3767
3768         /* 2 reserved bytes */
3769         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3770         offset += 2;
3771
3772         /* data len */
3773         datalen = tvb_get_letohs(tvb, offset);
3774         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3775         offset += 2;
3776
3777         /* data offset */
3778         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3779         offset += 2;
3780
3781         BYTE_COUNT;
3782
3783         /* file data */
3784         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3785         bc = 0;
3786
3787         END_OF_SMB
3788
3789         return offset;
3790 }
3791
3792
3793 static const true_false_string tfs_write_mode_write_through = {
3794         "WRITE THROUGH requested",
3795         "Write through not requested"
3796 };
3797 static const true_false_string tfs_write_mode_return_remaining = {
3798         "RETURN REMAINING (pipe/dev) requested",
3799         "DON'T return remaining (pipe/dev)"
3800 };
3801 static const true_false_string tfs_write_mode_raw = {
3802         "Use WriteRawNamedPipe (pipe)",
3803         "DON'T use WriteRawNamedPipe (pipe)"
3804 };
3805 static const true_false_string tfs_write_mode_message_start = {
3806         "This is the START of a MESSAGE (pipe)",
3807         "This is NOT the start of a message (pipe)"
3808 };
3809 static const true_false_string tfs_write_mode_connectionless = {
3810         "CONNECTIONLESS mode requested",
3811         "Connectionless mode NOT requested"
3812 };
3813 static int
3814 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3815 {
3816         guint16 mask;
3817         proto_item *item = NULL;
3818         proto_tree *tree = NULL;
3819
3820         mask = tvb_get_letohs(tvb, offset);
3821
3822         if(parent_tree){
3823                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3824                         "Write Mode: 0x%04x", mask);
3825                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3826         }
3827
3828         if(bm&0x0080){
3829                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3830                         tvb, offset, 2, mask);
3831         }
3832         if(bm&0x0008){
3833                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3834                         tvb, offset, 2, mask);
3835         }
3836         if(bm&0x0004){
3837                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3838                         tvb, offset, 2, mask);
3839         }
3840         if(bm&0x0002){
3841                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3842                         tvb, offset, 2, mask);
3843         }
3844         if(bm&0x0001){
3845                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3846                         tvb, offset, 2, mask);
3847         }
3848
3849         offset += 2;
3850         return offset;
3851 }
3852
3853 static int
3854 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3855 {
3856         guint32 to;
3857         guint16 datalen=0, bc, fid;
3858         guint8 wc;
3859
3860         WORD_COUNT;
3861
3862         /* fid */
3863         fid = tvb_get_letohs(tvb, offset);
3864         add_fid(tvb, pinfo, tree, offset, 2, fid);
3865         offset += 2;
3866
3867         /* total data length */
3868         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3869         offset += 2;
3870
3871         /* 2 reserved bytes */
3872         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3873         offset += 2;
3874
3875         /* offset */
3876         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3877         offset += 4;
3878
3879         /* timeout */
3880         to = tvb_get_letohl(tvb, offset);
3881         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3882         offset += 4;
3883
3884         /* mode */
3885         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3886
3887         /* 4 reserved bytes */
3888         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3889         offset += 4;
3890
3891         /* data len */
3892         datalen = tvb_get_letohs(tvb, offset);
3893         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3894         offset += 2;
3895
3896         /* data offset */
3897         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3898         offset += 2;
3899
3900         BYTE_COUNT;
3901
3902         /* file data */
3903         /* XXX - use the data offset to determine where the data starts? */
3904         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3905         bc = 0;
3906
3907         END_OF_SMB
3908
3909         return offset;
3910 }
3911  
3912 static int
3913 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3914 {
3915         guint8 wc;
3916         guint16 bc;
3917
3918         WORD_COUNT;
3919
3920         /* remaining */
3921         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3922         offset += 2;
3923
3924         BYTE_COUNT;
3925
3926         END_OF_SMB
3927
3928         return offset;
3929 }
3930
3931 static int
3932 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3933 {
3934         guint32 to;
3935         guint16 datalen=0, bc, fid;
3936         guint8 wc;
3937
3938         WORD_COUNT;
3939
3940         /* fid */
3941         fid = tvb_get_letohs(tvb, offset);
3942         add_fid(tvb, pinfo, tree, offset, 2, fid);
3943         offset += 2;
3944
3945         /* total data length */
3946         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3947         offset += 2;
3948
3949         /* 2 reserved bytes */
3950         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3951         offset += 2;
3952
3953         /* offset */
3954         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3955         offset += 4;
3956
3957         /* timeout */
3958         to = tvb_get_letohl(tvb, offset);
3959         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3960         offset += 4;
3961
3962         /* mode */
3963         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3964
3965         /* request mask */
3966         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3967         offset += 4;
3968         
3969         /* data len */
3970         datalen = tvb_get_letohs(tvb, offset);
3971         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3972         offset += 2;
3973
3974         /* data offset */
3975         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3976         offset += 2;
3977
3978         BYTE_COUNT;
3979
3980         /* file data */
3981         /* XXX - use the data offset to determine where the data starts? */
3982         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3983         bc = 0;
3984
3985         END_OF_SMB
3986
3987         return offset;
3988 }
3989  
3990 static int
3991 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3992 {
3993         guint8 wc;
3994         guint16 bc;
3995
3996         WORD_COUNT;
3997
3998         /* response mask */
3999         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4000         offset += 4;
4001         
4002         BYTE_COUNT;
4003
4004         END_OF_SMB
4005
4006         return offset;
4007 }
4008
4009 static int
4010 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4011 {
4012         guint8 wc;
4013         guint16 bc;
4014
4015         WORD_COUNT;
4016
4017         /* sid */
4018         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
4019         offset += 2;
4020
4021         BYTE_COUNT;
4022
4023         END_OF_SMB
4024
4025         return offset;
4026 }
4027
4028 static int
4029 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4030     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
4031 {
4032         proto_item *item = NULL;
4033         proto_tree *tree = NULL;
4034         int fn_len;
4035         const char *fn;
4036         char fname[11+1];
4037
4038         if(parent_tree){
4039                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4040                         "Resume Key");
4041                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4042         }
4043
4044         /* reserved byte */
4045         CHECK_BYTE_COUNT_SUBR(1);
4046         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4047         COUNT_BYTES_SUBR(1);
4048
4049         /* file name */
4050         fn_len = 11;
4051         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4052                 TRUE, TRUE, bcp);
4053         CHECK_STRING_SUBR(fn);
4054         /* ensure that it's null-terminated */
4055         strncpy(fname, fn, 11);
4056         fname[11] = '\0';
4057         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4058                 fname);
4059         COUNT_BYTES_SUBR(fn_len);
4060
4061         /* server cookie */
4062         CHECK_BYTE_COUNT_SUBR(5);
4063         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4064         COUNT_BYTES_SUBR(5);
4065
4066         /* client cookie */
4067         CHECK_BYTE_COUNT_SUBR(4);
4068         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4069         COUNT_BYTES_SUBR(4);
4070
4071         *trunc = FALSE;
4072         return offset;
4073 }
4074
4075 static int
4076 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4077     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
4078 {
4079         proto_item *item = NULL;
4080         proto_tree *tree = NULL;
4081         int fn_len;
4082         const char *fn;
4083         char fname[13+1];
4084
4085         if(parent_tree){
4086                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4087                         "Directory Information");
4088                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4089         }
4090
4091         /* resume key */
4092         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
4093         if (*trunc)
4094                 return offset;
4095
4096         /* File Attributes */
4097         CHECK_BYTE_COUNT_SUBR(1);
4098         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
4099         *bcp -= 1;
4100
4101         /* last write time */
4102         CHECK_BYTE_COUNT_SUBR(4);
4103         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
4104                 hf_smb_last_write_time,
4105                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4106                 TRUE);
4107         *bcp -= 4;
4108
4109         /* File Size */
4110         CHECK_BYTE_COUNT_SUBR(4);
4111         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4112         COUNT_BYTES_SUBR(4);
4113
4114         /* file name */
4115         fn_len = 13;
4116         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4117                 TRUE, TRUE, bcp);
4118         CHECK_STRING_SUBR(fn);
4119         /* ensure that it's null-terminated */
4120         strncpy(fname, fn, 13);
4121         fname[13] = '\0';
4122         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4123                 fname);
4124         COUNT_BYTES_SUBR(fn_len);
4125
4126         *trunc = FALSE;
4127         return offset;
4128 }
4129
4130
4131 static int
4132 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4133 {
4134         int fn_len;
4135         const char *fn;
4136         guint16 rkl;
4137         guint8 wc;
4138         guint16 bc;
4139         gboolean trunc;
4140
4141         WORD_COUNT;
4142
4143         /* max count */
4144         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4145         offset += 2;
4146
4147         /* Search Attributes */
4148         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4149
4150         BYTE_COUNT;
4151
4152         /* buffer format */
4153         CHECK_BYTE_COUNT(1);
4154         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4155         COUNT_BYTES(1);
4156
4157         /* file name */
4158         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4159                 TRUE, FALSE, &bc);
4160         if (fn == NULL)
4161                 goto endofcommand;
4162         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4163                 fn);
4164         COUNT_BYTES(fn_len);
4165
4166         if (check_col(pinfo->cinfo, COL_INFO)) {
4167                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4168         }
4169
4170         /* buffer format */
4171         CHECK_BYTE_COUNT(1);
4172         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4173         COUNT_BYTES(1);
4174
4175         /* resume key length */
4176         CHECK_BYTE_COUNT(2);
4177         rkl = tvb_get_letohs(tvb, offset);
4178         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4179         COUNT_BYTES(2);
4180
4181         /* resume key */
4182         if(rkl){
4183                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4184                     &bc, &trunc);
4185                 if (trunc)
4186                         goto endofcommand;
4187         }
4188
4189         END_OF_SMB
4190
4191         return offset;
4192 }
4193
4194 static int
4195 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4196 {
4197         guint16 count=0;
4198         guint8 wc;
4199         guint16 bc;
4200         gboolean trunc;
4201
4202         WORD_COUNT;
4203
4204         /* count */
4205         count = tvb_get_letohs(tvb, offset);
4206         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4207         offset += 2;
4208
4209         BYTE_COUNT;
4210
4211         /* buffer format */
4212         CHECK_BYTE_COUNT(1);
4213         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4214         COUNT_BYTES(1);
4215
4216         /* data len */
4217         CHECK_BYTE_COUNT(2);
4218         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4219         COUNT_BYTES(2);
4220
4221         while(count--){
4222                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4223                     &bc, &trunc);
4224                 if (trunc)
4225                         goto endofcommand;
4226         }
4227
4228         END_OF_SMB
4229
4230         return offset;
4231 }
4232
4233 static const value_string locking_ol_vals[] = {
4234         {0,     "Client is not holding oplock on this file"},
4235         {1,     "Level 2 oplock currently held by client"},
4236         {0, NULL}
4237 };
4238
4239 static const true_false_string tfs_lock_type_large = {
4240         "Large file locking format requested",
4241         "Large file locking format not requested"
4242 };
4243 static const true_false_string tfs_lock_type_cancel = {
4244         "Cancel outstanding lock request",
4245         "Don't cancel outstanding lock request"
4246 };
4247 static const true_false_string tfs_lock_type_change = {
4248         "Change lock type",
4249         "Don't change lock type"
4250 };
4251 static const true_false_string tfs_lock_type_oplock = {
4252         "This is an oplock break notification/response",
4253         "This is not an oplock break notification/response"
4254 };
4255 static const true_false_string tfs_lock_type_shared = {
4256         "This is a shared lock",
4257         "This is an exclusive lock"
4258 };
4259 static int
4260 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4261 {
4262         guint8  wc, cmd=0xff, lt=0;
4263         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4264         guint32 to;
4265         proto_item *litem = NULL;
4266         proto_tree *ltree = NULL;
4267         proto_item *it = NULL;
4268         proto_tree *tr = NULL;
4269         int old_offset = offset;
4270
4271         WORD_COUNT;
4272
4273         /* next smb command */
4274         cmd = tvb_get_guint8(tvb, offset);
4275         if(cmd!=0xff){
4276                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4277         } else {
4278                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4279         }
4280         offset += 1;
4281
4282         /* reserved byte */
4283         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4284         offset += 1;
4285
4286         /* andxoffset */
4287         andxoffset = tvb_get_letohs(tvb, offset);
4288         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4289         offset += 2;
4290
4291         /* fid */
4292         fid = tvb_get_letohs(tvb, offset);
4293         add_fid(tvb, pinfo, tree, offset, 2, fid);
4294         offset += 2;
4295
4296         /* lock type */
4297         lt = tvb_get_guint8(tvb, offset);
4298         if(tree){
4299                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4300                         "Lock Type: 0x%02x", lt);
4301                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4302         }
4303         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4304                 tvb, offset, 1, lt);
4305         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4306                 tvb, offset, 1, lt);
4307         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4308                 tvb, offset, 1, lt);
4309         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4310                 tvb, offset, 1, lt);
4311         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4312                 tvb, offset, 1, lt);
4313         offset += 1;
4314
4315         /* oplock level */
4316         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4317         offset += 1;
4318
4319         /* timeout */
4320         to = tvb_get_letohl(tvb, offset);
4321         if (to == 0)
4322                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4323         else if (to == 0xffffffff)
4324                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4325         else
4326                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4327         offset += 4;
4328
4329         /* number of unlocks */
4330         un = tvb_get_letohs(tvb, offset);
4331         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4332         offset += 2;
4333
4334         /* number of locks */
4335         ln = tvb_get_letohs(tvb, offset);
4336         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4337         offset += 2;
4338
4339         BYTE_COUNT;
4340
4341         /* unlocks */
4342         if(un){
4343                 old_offset = offset;
4344
4345                 it = proto_tree_add_text(tree, tvb, offset, -1,
4346                         "Unlocks");
4347                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4348                 while(un--){
4349                         proto_item *litem = NULL;
4350                         proto_tree *ltree = NULL;
4351                         if(lt&0x10){
4352                                 /* large lock format */
4353                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4354                                         "Unlock");
4355                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4356                                 
4357                                 /* PID */
4358                                 CHECK_BYTE_COUNT(2);
4359                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4360                                 COUNT_BYTES(2);
4361
4362                                 /* 2 reserved bytes */
4363                                 CHECK_BYTE_COUNT(2);
4364                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4365                                 COUNT_BYTES(2);
4366
4367                                 /* offset */
4368                                 CHECK_BYTE_COUNT(8);
4369                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4370                                 COUNT_BYTES(8);
4371
4372                                 /* length */
4373                                 CHECK_BYTE_COUNT(8);
4374                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4375                                 COUNT_BYTES(8);
4376                         } else {
4377                                 /* normal lock format */
4378                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4379                                         "Unlock");
4380                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4381                                 
4382                                 /* PID */
4383                                 CHECK_BYTE_COUNT(2);
4384                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4385                                 COUNT_BYTES(2);
4386
4387                                 /* offset */
4388                                 CHECK_BYTE_COUNT(4);
4389                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4390                                 COUNT_BYTES(4);
4391
4392                                 /* lock count */
4393                                 CHECK_BYTE_COUNT(4);
4394                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4395                                 COUNT_BYTES(4);
4396                         }
4397                 }
4398                 proto_item_set_len(it, offset-old_offset);
4399                 it = NULL;
4400         }
4401
4402         /* locks */
4403         if(ln){
4404                 old_offset = offset;
4405
4406                 it = proto_tree_add_text(tree, tvb, offset, -1,
4407                         "Locks");
4408                 tr = proto_item_add_subtree(it, ett_smb_locks);
4409                 while(ln--){
4410                         proto_item *litem = NULL;
4411                         proto_tree *ltree = NULL;
4412                         if(lt&0x10){
4413                                 /* large lock format */
4414                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4415                                         "Lock");
4416                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4417                                 
4418                                 /* PID */
4419                                 CHECK_BYTE_COUNT(2);
4420                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4421                                 COUNT_BYTES(2);
4422
4423                                 /* 2 reserved bytes */
4424                                 CHECK_BYTE_COUNT(2);
4425                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4426                                 COUNT_BYTES(2);
4427
4428                                 /* offset */
4429                                 CHECK_BYTE_COUNT(8);
4430                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4431                                 COUNT_BYTES(8);
4432
4433                                 /* length */
4434                                 CHECK_BYTE_COUNT(8);
4435                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4436                                 COUNT_BYTES(8);
4437                         } else {
4438                                 /* normal lock format */
4439                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4440                                         "Unlock");
4441                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4442                                 
4443                                 /* PID */
4444                                 CHECK_BYTE_COUNT(2);
4445                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4446                                 COUNT_BYTES(2);
4447
4448                                 /* offset */
4449                                 CHECK_BYTE_COUNT(4);
4450                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4451                                 COUNT_BYTES(4);
4452
4453                                 /* lock count */
4454                                 CHECK_BYTE_COUNT(4);
4455                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4456                                 COUNT_BYTES(4);
4457                         }
4458                 }
4459                 proto_item_set_len(it, offset-old_offset);
4460                 it = NULL;
4461         }
4462
4463         END_OF_SMB
4464
4465         if (it != NULL) {
4466                 /*
4467                  * We ran out of byte count in the middle of dissecting
4468                  * the locks or the unlocks; set the site of the item
4469                  * we were dissecting.
4470                  */
4471                 proto_item_set_len(it, offset-old_offset);
4472         }
4473
4474         /* call AndXCommand (if there are any) */
4475         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4476
4477         return offset;
4478 }
4479
4480 static int
4481 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4482 {
4483         guint8  wc, cmd=0xff;
4484         guint16 andxoffset=0;
4485         guint16 bc;
4486
4487         WORD_COUNT;
4488
4489         /* next smb command */
4490         cmd = tvb_get_guint8(tvb, offset);
4491         if(cmd!=0xff){
4492                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4493         } else {
4494                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4495         }
4496         offset += 1;
4497
4498         /* reserved byte */
4499         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4500         offset += 1;
4501
4502         /* andxoffset */
4503         andxoffset = tvb_get_letohs(tvb, offset);
4504         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4505         offset += 2;
4506
4507         BYTE_COUNT;
4508
4509         END_OF_SMB
4510
4511         /* call AndXCommand (if there are any) */
4512         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4513
4514         return offset;
4515 }
4516
4517
4518 static const value_string oa_open_vals[] = {
4519         { 0,            "No action taken?"},
4520         { 1,            "The file existed and was opened"},
4521         { 2,            "The file did not exist but was created"},
4522         { 3,            "The file existed and was truncated"},
4523         {0,     NULL}
4524 };
4525 static const true_false_string tfs_oa_lock = {
4526         "File is currently opened only by this user",
4527         "File is opened by another user (or mode not supported by server)"
4528 };
4529 static int
4530 dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4531 {
4532         guint16 mask;
4533         proto_item *item = NULL;
4534         proto_tree *tree = NULL;
4535
4536         mask = tvb_get_letohs(tvb, offset);
4537
4538         if(parent_tree){
4539                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4540                         "Action: 0x%04x", mask);
4541                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4542         }
4543
4544         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4545                 tvb, offset, 2, mask);
4546         proto_tree_add_uint(tree, hf_smb_open_action_open,
4547                 tvb, offset, 2, mask);
4548
4549         offset += 2;
4550
4551         return offset;
4552 }
4553
4554 static const true_false_string tfs_open_flags_add_info = {
4555         "Additional information requested",
4556         "Additional information not requested"
4557 };
4558 static const true_false_string tfs_open_flags_ex_oplock = {
4559         "Exclusive oplock requested",
4560         "Exclusive oplock not requested"
4561 };
4562 static const true_false_string tfs_open_flags_batch_oplock = {
4563         "Batch oplock requested",
4564         "Batch oplock not requested"
4565 };
4566 static const true_false_string tfs_open_flags_ealen = {
4567         "Total length of EAs requested",
4568         "Total length of EAs not requested"
4569 };
4570 static int
4571 dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
4572 {
4573         guint16 mask;
4574         proto_item *item = NULL;
4575         proto_tree *tree = NULL;
4576
4577         mask = tvb_get_letohs(tvb, offset);
4578
4579         if(parent_tree){
4580                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4581                         "Flags: 0x%04x", mask);
4582                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4583         }
4584
4585         if(bm&0x0001){
4586                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4587                         tvb, offset, 2, mask);
4588         }
4589         if(bm&0x0002){
4590                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4591                         tvb, offset, 2, mask);
4592         }
4593         if(bm&0x0004){
4594                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4595                         tvb, offset, 2, mask);
4596         }
4597         if(bm&0x0008){
4598                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4599                         tvb, offset, 2, mask);
4600         }
4601
4602         offset += 2;
4603
4604         return offset;
4605 }
4606
4607 static const value_string filetype_vals[] = {
4608         { 0,            "Disk file or directory"},
4609         { 1,            "Named pipe in byte mode"},
4610         { 2,            "Named pipe in message mode"},
4611         { 3,            "Spooled printer"},
4612         {0, NULL}
4613 };
4614 static int
4615 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4616 {
4617         guint8  wc, cmd=0xff;
4618         guint16 andxoffset=0, bc;
4619         int fn_len;
4620         const char *fn;
4621
4622         WORD_COUNT;
4623
4624         /* next smb command */
4625         cmd = tvb_get_guint8(tvb, offset);
4626         if(cmd!=0xff){
4627                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4628         } else {
4629                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4630         }
4631         offset += 1;
4632
4633         /* reserved byte */
4634         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4635         offset += 1;
4636
4637         /* andxoffset */
4638         andxoffset = tvb_get_letohs(tvb, offset);
4639         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4640         offset += 2;
4641
4642         /* open flags */
4643         offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
4644
4645         /* desired access */
4646         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
4647
4648         /* Search Attributes */
4649         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4650
4651         /* File Attributes */
4652         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4653
4654         /* creation time */
4655         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
4656         
4657         /* open function */
4658         offset = dissect_open_function(tvb, pinfo, tree, offset);
4659
4660         /* allocation size */
4661         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4662         offset += 4;
4663
4664         /* 8 reserved bytes */
4665         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4666         offset += 8;
4667
4668         BYTE_COUNT;
4669
4670         /* file name */
4671         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4672                 FALSE, FALSE, &bc);
4673         if (fn == NULL)
4674                 goto endofcommand;
4675         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4676                 fn);
4677         COUNT_BYTES(fn_len);
4678
4679         if (check_col(pinfo->cinfo, COL_INFO)) {
4680                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4681         }
4682
4683         END_OF_SMB
4684
4685         /* call AndXCommand (if there are any) */
4686         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4687
4688         return offset;
4689 }
4690
4691 static const true_false_string tfs_ipc_state_nonblocking = {
4692         "Reads/writes return immediately if no data available",
4693         "Reads/writes block if no data available"
4694 };
4695 static const value_string ipc_state_endpoint_vals[] = {
4696         { 0,            "Consumer end of pipe"},
4697         { 1,            "Server end of pipe"},
4698         {0,     NULL}
4699 };
4700 static const value_string ipc_state_pipe_type_vals[] = {
4701         { 0,            "Byte stream pipe"},
4702         { 1,            "Message pipe"},
4703         {0,     NULL}
4704 };
4705 static const value_string ipc_state_read_mode_vals[] = {
4706         { 0,            "Read pipe as a byte stream"},
4707         { 1,            "Read messages from pipe"},
4708         {0,     NULL}
4709 };
4710
4711 int
4712 dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
4713     int offset, gboolean setstate)
4714 {
4715         guint16 mask;
4716         proto_item *item = NULL;
4717         proto_tree *tree = NULL;
4718
4719         mask = tvb_get_letohs(tvb, offset);
4720
4721         if(parent_tree){
4722                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4723                         "IPC State: 0x%04x", mask);
4724                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4725         }
4726
4727         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4728                 tvb, offset, 2, mask);
4729         if (!setstate) {
4730                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4731                         tvb, offset, 2, mask);
4732                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4733                         tvb, offset, 2, mask);
4734         }
4735         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4736                 tvb, offset, 2, mask);
4737         if (!setstate) {
4738                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4739                         tvb, offset, 2, mask);
4740         }
4741
4742         offset += 2;
4743
4744         return offset;
4745 }
4746
4747 static int
4748 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4749 {
4750         guint8  wc, cmd=0xff;
4751         guint16 andxoffset=0, bc;
4752         guint16 fid;
4753
4754         WORD_COUNT;
4755
4756         /* next smb command */
4757         cmd = tvb_get_guint8(tvb, offset);
4758         if(cmd!=0xff){
4759                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4760         } else {
4761                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4762         }
4763         offset += 1;
4764
4765         /* reserved byte */
4766         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4767         offset += 1;
4768
4769         /* andxoffset */
4770         andxoffset = tvb_get_letohs(tvb, offset);
4771         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4772         offset += 2;
4773
4774         /* fid */
4775         fid = tvb_get_letohs(tvb, offset);
4776         add_fid(tvb, pinfo, tree, offset, 2, fid);
4777         offset += 2;
4778
4779         /* File Attributes */
4780         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4781
4782         /* last write time */
4783         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
4784         
4785         /* File Size */
4786         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4787         offset += 4;
4788
4789         /* granted access */
4790         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
4791
4792         /* File Type */
4793         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
4794         offset += 2;
4795
4796         /* IPC State */
4797         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
4798
4799         /* open_action */
4800         offset = dissect_open_action(tvb, pinfo, tree, offset);
4801
4802         /* server fid */
4803         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
4804         offset += 4;
4805
4806         /* 2 reserved bytes */
4807         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4808         offset += 2;
4809
4810         BYTE_COUNT;
4811
4812         END_OF_SMB
4813
4814         /* call AndXCommand (if there are any) */
4815         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4816
4817         return offset;
4818 }
4819
4820 static int
4821 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4822 {
4823         guint8  wc, cmd=0xff;
4824         guint16 andxoffset=0, bc, maxcnt = 0;
4825         guint32 ofs = 0;
4826         smb_info_t *si;
4827         unsigned int fid;
4828
4829         WORD_COUNT;
4830
4831         /* next smb command */
4832         cmd = tvb_get_guint8(tvb, offset);
4833         if(cmd!=0xff){
4834                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4835         } else {
4836                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4837         }
4838         offset += 1;
4839
4840         /* reserved byte */
4841         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4842         offset += 1;
4843
4844         /* andxoffset */
4845         andxoffset = tvb_get_letohs(tvb, offset);
4846         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4847         offset += 2;
4848
4849         /* fid */
4850         fid = tvb_get_letohs(tvb, offset);
4851         add_fid(tvb, pinfo, tree, offset, 2, fid);
4852         offset += 2;
4853         if (!pinfo->fd->flags.visited) {
4854                 /* remember the FID for the processing of the response */
4855                 si = (smb_info_t *)pinfo->private_data;
4856                 si->sip->extra_info=(void *)fid;
4857         }
4858
4859         /* offset */
4860         ofs = tvb_get_letohl(tvb, offset);
4861         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4862         offset += 4;
4863
4864         /* max count */
4865         maxcnt = tvb_get_letohs(tvb, offset);
4866         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4867         offset += 2;
4868
4869         if (check_col(pinfo->cinfo, COL_INFO))
4870                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4871                                 ", %d byte%s at offset %d", maxcnt, 
4872                                 (maxcnt == 1) ? "" : "s", ofs);
4873
4874         /* min count */
4875         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4876         offset += 2;
4877
4878         /* XXX - max count high */
4879         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4880         offset += 4;
4881
4882         /* remaining */
4883         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4884         offset += 2;
4885
4886         if(wc==12){
4887                 /* high offset */
4888                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4889                 offset += 4;
4890         }
4891
4892         BYTE_COUNT;
4893
4894         END_OF_SMB
4895
4896         /* call AndXCommand (if there are any) */
4897         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4898
4899         return offset;
4900 }
4901
4902 static int
4903 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4904 {
4905         guint8  wc, cmd=0xff;
4906         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4907         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4908         int fid=0;
4909
4910         WORD_COUNT;
4911
4912         /* next smb command */
4913         cmd = tvb_get_guint8(tvb, offset);
4914         if(cmd!=0xff){
4915                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4916         } else {
4917                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4918         }
4919         offset += 1;
4920  
4921         /* reserved byte */
4922         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4923         offset += 1;
4924
4925         /* andxoffset */
4926         andxoffset = tvb_get_letohs(tvb, offset);
4927         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4928         offset += 2;
4929
4930         /* If we have seen the request, then print which FID this refers to */
4931         /* first check if we have seen the request */
4932         if(si->sip != NULL && si->sip->frame_req>0){
4933                 fid=(int)si->sip->extra_info;
4934                 add_fid(tvb, pinfo, tree, 0, 0, fid);
4935         }
4936
4937         /* remaining */
4938         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4939         offset += 2;
4940
4941         /* data compaction mode */
4942         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4943         offset += 2;
4944
4945         /* 2 reserved bytes */
4946         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4947         offset += 2;
4948
4949         /* data len */
4950         datalen = tvb_get_letohs(tvb, offset);
4951         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4952         offset += 2;
4953
4954         if (check_col(pinfo->cinfo, COL_INFO))
4955                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4956                                 ", %d byte%s", datalen, 
4957                                 (datalen == 1) ? "" : "s");
4958
4959         /* data offset */
4960         dataoffset=tvb_get_letohs(tvb, offset);
4961         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
4962         offset += 2;
4963
4964         /* 10 reserved bytes */
4965         /* XXX - first 2 bytes are data length high, not reserved */
4966         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4967         offset += 10;
4968
4969         BYTE_COUNT;
4970
4971         /* is this part of DCERPC over SMB reassembly?*/
4972         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
4973             && (bc<=tvb_length_remaining(tvb, offset)) ){
4974                 gpointer hash_value;
4975                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
4976                                                 si->ct->dcerpc_fid_to_frame,
4977                                                 si->sip->extra_info)) != NULL) {
4978                         fragment_data *fd_head;
4979                         guint32 frame = GPOINTER_TO_UINT(hash_value);
4980
4981                         /* first fragment is always from a SMB Trans command and
4982                            offset 0 of the following read/write SMB commands start
4983                            BEYOND the first Trans SMB payload. Look for offset
4984                            in first read fragment */
4985                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
4986                         if(fd_head){
4987                                 /* skip to last fragment  and add this data there*/
4988                                 while(fd_head->next){
4989                                         fd_head=fd_head->next;
4990                                 }
4991                                 /* if dataoffset was not specified in the SMB command
4992                                    then we try to guess it as good as we can
4993                                 */
4994                                 if(dataoffset==0){
4995                                         dataoffset=offset+bc-datalen;
4996                                 }
4997                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
4998                                         frame, dcerpc_fragment_table,
4999                                         fd_head->offset+fd_head->len, 
5000                                         datalen, TRUE);
5001                                 /* we completed reassembly, abort searching for more 
5002                                    fragments*/
5003                                 if(fd_head){
5004                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5005                                                 si->sip->extra_info);   
5006                                 }
5007                         }
5008                 }
5009         }
5010
5011         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
5012            read write */
5013         if(bc){
5014                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
5015                         /* dcerpc call */
5016                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5017                             top_tree, offset, bc, datalen, fid);
5018                 } else {
5019                         /* ordinary file data, or we didn't see the request,
5020                            so we don't know whether this is a DCERPC call
5021                            or not */
5022                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
5023                 }
5024                 bc = 0;
5025         }
5026
5027         END_OF_SMB
5028
5029         /* call AndXCommand (if there are any) */
5030         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5031
5032         return offset;
5033 }
5034
5035 static int
5036 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5037 {
5038         guint32 ofs=0;
5039         guint8  wc, cmd=0xff;
5040         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5041         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5042         unsigned int fid=0;
5043
5044         WORD_COUNT;
5045
5046         /* next smb command */
5047         cmd = tvb_get_guint8(tvb, offset);
5048         if(cmd!=0xff){
5049                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5050         } else {
5051                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5052         }
5053         offset += 1;
5054
5055         /* reserved byte */
5056         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5057         offset += 1;
5058
5059         /* andxoffset */
5060         andxoffset = tvb_get_letohs(tvb, offset);
5061         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5062         offset += 2;
5063
5064         /* fid */
5065         fid = tvb_get_letohs(tvb, offset);
5066         add_fid(tvb, pinfo, tree, offset, 2, fid);
5067         offset += 2;
5068         if (!pinfo->fd->flags.visited) {
5069                 /* remember the FID for the processing of the response */
5070                 si->sip->extra_info=(void *)fid;
5071         }
5072
5073         /* offset */
5074         ofs = tvb_get_letohl(tvb, offset);
5075         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5076         offset += 4;
5077
5078         /* reserved */
5079         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5080         offset += 4;
5081
5082         /* mode */
5083         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
5084
5085         /* remaining */
5086         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5087         offset += 2;
5088
5089         /* XXX - data length high */
5090         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5091         offset += 2;
5092
5093         /* data len */
5094         datalen = tvb_get_letohs(tvb, offset);
5095         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5096         offset += 2;
5097
5098         /* data offset */
5099         dataoffset=tvb_get_letohs(tvb, offset);
5100         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5101         offset += 2;
5102
5103         /* FIXME: add byte/offset to COL_INFO */
5104
5105         if(wc==14){
5106                 /* high offset */
5107                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5108                 offset += 4;
5109         }
5110
5111         BYTE_COUNT;
5112
5113         /* is this part of DCERPC over SMB reassembly?*/
5114         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5115                 gpointer hash_value;
5116                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5117                         si->sip->extra_info);
5118                 if(hash_value){
5119                         fragment_data *fd_head;
5120                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5121
5122                         /* first fragment is always from a SMB Trans command and
5123                            offset 0 of the following read/write SMB commands start
5124                            BEYOND the first Trans SMB payload. Look for offset
5125                            in first read fragment */
5126                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5127                         if(fd_head){
5128                                 /* skip to last fragment  and add this data there*/
5129                                 while(fd_head->next){
5130                                         fd_head=fd_head->next;
5131                                 }
5132                                 /* if dataoffset was not specified in the SMB command
5133                                    then we try to guess it as good as we can
5134                                 */
5135                                 if(dataoffset==0){
5136                                         dataoffset=offset+bc-datalen;
5137                                 }
5138                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5139                                         frame, dcerpc_fragment_table,
5140                                         fd_head->offset+fd_head->len, 
5141                                         datalen, TRUE);
5142                                 /* we completed reassembly, abort searching for more 
5143                                    fragments*/
5144                                 if(fd_head){
5145                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5146                                                 si->sip->extra_info);   
5147                                 }
5148                         }
5149                 }
5150         }
5151
5152         /* file data */
5153         if (bc != 0) {
5154                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5155                         /* dcerpc call */
5156                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5157                             top_tree, offset, bc, datalen, fid);
5158                 } else {
5159                         /* ordinary file data */
5160                         offset = dissect_file_data(tvb, pinfo, tree, offset,
5161                             bc, datalen);
5162                 }
5163                 bc = 0;
5164         }
5165
5166         END_OF_SMB
5167
5168         /* call AndXCommand (if there are any) */
5169         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5170
5171         return offset;
5172 }
5173
5174 static int
5175 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5176 {
5177         guint8  wc, cmd=0xff;
5178         guint16 andxoffset=0, bc;
5179         smb_info_t *si;
5180
5181         WORD_COUNT;
5182
5183         /* next smb command */
5184         cmd = tvb_get_guint8(tvb, offset);
5185         if(cmd!=0xff){
5186                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5187         } else {
5188                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5189         }
5190         offset += 1;
5191  
5192         /* reserved byte */
5193         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5194         offset += 1;
5195
5196         /* andxoffset */
5197         andxoffset = tvb_get_letohs(tvb, offset);
5198         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5199         offset += 2;
5200
5201         /* If we have seen the request, then print which FID this refers to */
5202         si = (smb_info_t *)pinfo->private_data;
5203         /* first check if we have seen the request */
5204         if(si->sip != NULL && si->sip->frame_req>0){
5205                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5206         }
5207
5208         /* write count */
5209         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5210         offset += 2;
5211
5212         /* remaining */
5213         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5214         offset += 2;
5215
5216         /* 4 reserved bytes */
5217         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5218         offset += 4;
5219
5220         BYTE_COUNT;
5221
5222         END_OF_SMB
5223
5224         /* call AndXCommand (if there are any) */
5225         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5226
5227         return offset;
5228 }
5229
5230
5231 static const true_false_string tfs_setup_action_guest = {
5232         "Logged in as GUEST",
5233         "Not logged in as GUEST"
5234 };
5235 static int
5236 dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5237 {
5238         guint16 mask;
5239         proto_item *item = NULL;
5240         proto_tree *tree = NULL;
5241
5242         mask = tvb_get_letohs(tvb, offset);
5243
5244         if(parent_tree){
5245                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5246                         "Action: 0x%04x", mask);
5247                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5248         }
5249
5250         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5251                 tvb, offset, 2, mask);
5252
5253         offset += 2;
5254
5255         return offset;
5256 }
5257  
5258
5259 static int
5260 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5261 {
5262         guint8  wc, cmd=0xff;
5263         guint16 bc;
5264         guint16 andxoffset=0;
5265         int an_len;
5266         const char *an;
5267         int dn_len;
5268         const char *dn;
5269         guint16 pwlen=0;
5270         guint16 sbloblen=0;
5271         guint16 apwlen=0, upwlen=0;
5272
5273         WORD_COUNT;
5274
5275         /* next smb command */
5276         cmd = tvb_get_guint8(tvb, offset);
5277         if(cmd!=0xff){
5278                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5279         } else {
5280                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5281         }
5282         offset += 1;
5283
5284         /* reserved byte */
5285         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5286         offset += 1;
5287
5288         /* andxoffset */
5289         andxoffset = tvb_get_letohs(tvb, offset);
5290         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5291         offset += 2;
5292
5293         /* Maximum Buffer Size */
5294         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5295         offset += 2;
5296
5297         /* Maximum Multiplex Count */
5298         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5299         offset += 2;
5300
5301         /* VC Number */
5302         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5303         offset += 2;
5304
5305         /* session key */
5306         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5307         offset += 4;
5308
5309         switch (wc) {
5310         case 10:
5311                 /* password length, ASCII*/
5312                 pwlen = tvb_get_letohs(tvb, offset);
5313                 proto_tree_add_uint(tree, hf_smb_password_len,
5314                         tvb, offset, 2, pwlen);
5315                 offset += 2;
5316
5317                 /* 4 reserved bytes */
5318                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5319                 offset += 4;
5320
5321                 break;
5322
5323         case 12:
5324                 /* security blob length */
5325                 sbloblen = tvb_get_letohs(tvb, offset);
5326                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5327                 offset += 2;
5328
5329                 /* 4 reserved bytes */
5330                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5331                 offset += 4;
5332
5333                 /* capabilities */
5334                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5335                 offset += 4;
5336
5337                 break;
5338
5339         case 13:
5340                 /* password length, ANSI*/
5341                 apwlen = tvb_get_letohs(tvb, offset);
5342                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5343                         tvb, offset, 2, apwlen);
5344                 offset += 2;
5345
5346                 /* password length, Unicode*/
5347                 upwlen = tvb_get_letohs(tvb, offset);
5348                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5349                         tvb, offset, 2, upwlen);
5350                 offset += 2;
5351
5352                 /* 4 reserved bytes */
5353                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5354                 offset += 4;
5355
5356                 /* capabilities */
5357                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5358                 offset += 4;
5359
5360                 break;
5361         }
5362
5363         BYTE_COUNT;
5364
5365         if (wc==12) {
5366                 /* security blob */
5367                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5368                    data structure, at least in NT 5.0-and-later
5369                    server replies? */
5370                 if(sbloblen){
5371                         CHECK_BYTE_COUNT(sbloblen);
5372                         proto_tree_add_item(tree, hf_smb_security_blob,
5373                                 tvb, offset, sbloblen, TRUE);
5374                         COUNT_BYTES(sbloblen);
5375                 }
5376
5377                 /* OS */
5378                 an = get_unicode_or_ascii_string(tvb, &offset,
5379                         pinfo, &an_len, FALSE, FALSE, &bc);
5380                 if (an == NULL)
5381                         goto endofcommand;
5382                 proto_tree_add_string(tree, hf_smb_os, tvb,
5383                         offset, an_len, an);
5384                 COUNT_BYTES(an_len);
5385
5386                 /* LANMAN */
5387                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5388                  * padding/null string/whatever in front of this. W2K doesn't
5389                  * appear to. I suspect that's a bug that got fixed; I also
5390                  * suspect that, in practice, nobody ever looks at that field
5391                  * because the bug didn't appear to get fixed until NT 5.0....
5392                  */
5393                 an = get_unicode_or_ascii_string(tvb, &offset,
5394                         pinfo, &an_len, FALSE, FALSE, &bc);
5395                 if (an == NULL)
5396                         goto endofcommand;
5397                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5398                         offset, an_len, an);
5399                 COUNT_BYTES(an_len);
5400
5401                 /* Primary domain */
5402                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5403                  * byte in front of this, at least if all the strings are
5404                  * ASCII and the account name is empty. Another bug?
5405                  */
5406                 dn = get_unicode_or_ascii_string(tvb, &offset,
5407                         pinfo, &dn_len, FALSE, FALSE, &bc);
5408                 if (dn == NULL)
5409                         goto endofcommand;
5410                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5411                         offset, dn_len, dn);
5412                 COUNT_BYTES(dn_len);
5413         } else {
5414                 switch (wc) {
5415
5416                 case 10:
5417                         if(pwlen){
5418                                 /* password, ASCII */
5419                                 CHECK_BYTE_COUNT(pwlen);
5420                                 proto_tree_add_item(tree, hf_smb_password, 
5421                                         tvb, offset, pwlen, TRUE);
5422                                 COUNT_BYTES(pwlen);
5423                         }
5424
5425                         break;
5426
5427                 case 13:
5428                         if(apwlen){
5429                                 /* password, ANSI */
5430                                 CHECK_BYTE_COUNT(apwlen);
5431                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5432                                         tvb, offset, apwlen, TRUE);
5433                                 COUNT_BYTES(apwlen);
5434                         }
5435
5436                         if(upwlen){
5437                                 /* password, Unicode */
5438                                 CHECK_BYTE_COUNT(upwlen);
5439                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5440                                         tvb, offset, upwlen, TRUE);
5441                                 COUNT_BYTES(upwlen);
5442                         }
5443
5444                         break;
5445                 }
5446
5447                 /* Account Name */
5448                 an = get_unicode_or_ascii_string(tvb, &offset,
5449                         pinfo, &an_len, FALSE, FALSE, &bc);
5450                 if (an == NULL)
5451                         goto endofcommand;
5452                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5453                         an);
5454                 COUNT_BYTES(an_len);
5455
5456                 /* Primary domain */
5457                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5458                  * byte in front of this, at least if all the strings are
5459                  * ASCII and the account name is empty. Another bug?
5460                  */
5461                 dn = get_unicode_or_ascii_string(tvb, &offset,
5462                         pinfo, &dn_len, FALSE, FALSE, &bc);
5463                 if (dn == NULL)
5464                         goto endofcommand;
5465                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5466                         offset, dn_len, dn);
5467                 COUNT_BYTES(dn_len);
5468
5469                 if (check_col(pinfo->cinfo, COL_INFO)) {
5470                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5471
5472                         if (!dn[0] && !an[0])
5473                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5474                                                 "anonymous");
5475                         else
5476                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5477                                                 "%s\\%s", dn,an);
5478                 }
5479
5480                 /* OS */
5481                 an = get_unicode_or_ascii_string(tvb, &offset,
5482                         pinfo, &an_len, FALSE, FALSE, &bc);
5483                 if (an == NULL)
5484                         goto endofcommand;
5485                 proto_tree_add_string(tree, hf_smb_os, tvb,
5486                         offset, an_len, an);
5487                 COUNT_BYTES(an_len);
5488
5489                 /* LANMAN */
5490                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5491                  * padding/null string/whatever in front of this. W2K doesn't
5492                  * appear to. I suspect that's a bug that got fixed; I also
5493                  * suspect that, in practice, nobody ever looks at that field
5494                  * because the bug didn't appear to get fixed until NT 5.0....
5495                  */
5496                 an = get_unicode_or_ascii_string(tvb, &offset,
5497                         pinfo, &an_len, FALSE, FALSE, &bc);
5498                 if (an == NULL)
5499                         goto endofcommand;
5500                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5501                         offset, an_len, an);
5502                 COUNT_BYTES(an_len);
5503         }
5504
5505         END_OF_SMB
5506
5507         /* call AndXCommand (if there are any) */
5508         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5509
5510         return offset;
5511 }
5512
5513 static int
5514 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5515 {
5516         guint8  wc, cmd=0xff;
5517         guint16 andxoffset=0, bc;
5518         guint16 sbloblen=0;
5519         int an_len;
5520         const char *an;
5521
5522         WORD_COUNT;
5523
5524         /* next smb command */
5525         cmd = tvb_get_guint8(tvb, offset);
5526         if(cmd!=0xff){
5527                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5528         } else {
5529                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5530         }
5531         offset += 1;
5532
5533         /* reserved byte */
5534         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5535         offset += 1;
5536
5537         /* andxoffset */
5538         andxoffset = tvb_get_letohs(tvb, offset);
5539         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5540         offset += 2;
5541
5542         /* flags */
5543         offset = dissect_setup_action(tvb, pinfo, tree, offset);
5544
5545         if(wc==4){
5546                 /* security blob length */
5547                 sbloblen = tvb_get_letohs(tvb, offset);
5548                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5549                 offset += 2;
5550         }
5551
5552         BYTE_COUNT;
5553
5554         if(wc==4) {
5555                 /* security blob */
5556                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5557                    data structure, at least in NT 5.0-and-later
5558                    server replies? */
5559                 if(sbloblen){
5560                         CHECK_BYTE_COUNT(sbloblen);
5561                         proto_tree_add_item(tree, hf_smb_security_blob,
5562                                 tvb, offset, sbloblen, TRUE);
5563                         COUNT_BYTES(sbloblen);
5564                 }
5565         }
5566
5567         /* OS */
5568         an = get_unicode_or_ascii_string(tvb, &offset,
5569                 pinfo, &an_len, FALSE, FALSE, &bc);
5570         if (an == NULL)
5571                 goto endofcommand;
5572         proto_tree_add_string(tree, hf_smb_os, tvb,
5573                 offset, an_len, an);
5574         COUNT_BYTES(an_len);
5575
5576         /* LANMAN */
5577         an = get_unicode_or_ascii_string(tvb, &offset,
5578                 pinfo, &an_len, FALSE, FALSE, &bc);
5579         if (an == NULL)
5580                 goto endofcommand;
5581         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5582                 offset, an_len, an);
5583         COUNT_BYTES(an_len);
5584
5585         if(wc==3) {
5586                 /* Primary domain */
5587                 an = get_unicode_or_ascii_string(tvb, &offset,
5588                         pinfo, &an_len, FALSE, FALSE, &bc);
5589                 if (an == NULL)
5590                         goto endofcommand;
5591                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5592                         offset, an_len, an);
5593                 COUNT_BYTES(an_len);
5594         }
5595
5596         END_OF_SMB
5597
5598         /* call AndXCommand (if there are any) */
5599         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5600
5601         return offset;
5602 }
5603
5604  
5605 static int
5606 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5607 {
5608         guint8  wc, cmd=0xff;
5609         guint16 andxoffset=0;
5610         guint16 bc;
5611
5612         WORD_COUNT;
5613
5614         /* next smb command */
5615         cmd = tvb_get_guint8(tvb, offset);
5616         if(cmd!=0xff){
5617                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5618         } else {
5619                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5620         }
5621         offset += 1;
5622
5623         /* reserved byte */
5624         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5625         offset += 1;
5626
5627         /* andxoffset */
5628         andxoffset = tvb_get_letohs(tvb, offset);
5629         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5630         offset += 2;
5631
5632         BYTE_COUNT;
5633
5634         END_OF_SMB
5635
5636         /* call AndXCommand (if there are any) */
5637         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5638
5639         return offset;
5640 }
5641
5642  
5643 static const true_false_string tfs_connect_support_search = {
5644         "Exclusive search bits supported",
5645         "Exclusive search bits not supported"
5646 };
5647 static const true_false_string tfs_connect_support_in_dfs = {
5648         "Share is in Dfs",
5649         "Share isn't in Dfs"
5650 };
5651
5652 static int
5653 dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5654 {
5655         guint16 mask;
5656         proto_item *item = NULL;
5657         proto_tree *tree = NULL;
5658
5659         mask = tvb_get_letohs(tvb, offset);
5660
5661         if(parent_tree){
5662                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5663                         "Optional Support: 0x%04x", mask);
5664                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5665         }
5666
5667         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5668                 tvb, offset, 2, mask);
5669         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5670                 tvb, offset, 2, mask);
5671
5672         offset += 2;
5673
5674         return offset;
5675 }
5676
5677 static const true_false_string tfs_disconnect_tid = {
5678         "DISCONNECT TID",
5679         "Do NOT disconnect TID"
5680 };
5681
5682 static int
5683 dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5684 {
5685         guint16 mask;
5686         proto_item *item = NULL;
5687         proto_tree *tree = NULL;
5688
5689         mask = tvb_get_letohs(tvb, offset);
5690
5691         if(parent_tree){
5692                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5693                         "Flags: 0x%04x", mask);
5694                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5695         }
5696
5697         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5698                 tvb, offset, 2, mask);
5699
5700         offset += 2;
5701
5702         return offset;
5703 }
5704
5705 static int
5706 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5707 {
5708         guint8  wc, cmd=0xff;
5709         guint16 bc;
5710         guint16 andxoffset=0, pwlen=0;
5711         int an_len;
5712         const char *an;
5713
5714         WORD_COUNT;
5715
5716         /* next smb command */
5717         cmd = tvb_get_guint8(tvb, offset);
5718         if(cmd!=0xff){
5719                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5720         } else {
5721                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5722         }
5723         offset += 1;
5724
5725         /* reserved byte */
5726         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5727         offset += 1;
5728
5729         /* andxoffset */
5730         andxoffset = tvb_get_letohs(tvb, offset);
5731         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5732         offset += 2;
5733
5734         /* flags */
5735         offset = dissect_connect_flags(tvb, pinfo, tree, offset);
5736
5737         /* password length*/
5738         pwlen = tvb_get_letohs(tvb, offset);
5739         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5740         offset += 2;
5741
5742         BYTE_COUNT;
5743
5744         /* password */
5745         CHECK_BYTE_COUNT(pwlen);
5746         proto_tree_add_item(tree, hf_smb_password, 
5747                 tvb, offset, pwlen, TRUE);
5748         COUNT_BYTES(pwlen);
5749
5750         /* Path */
5751         an = get_unicode_or_ascii_string(tvb, &offset,
5752                 pinfo, &an_len, FALSE, FALSE, &bc);
5753         if (an == NULL)
5754                 goto endofcommand;
5755         proto_tree_add_string(tree, hf_smb_path, tvb,
5756                 offset, an_len, an);
5757         COUNT_BYTES(an_len);
5758
5759         if (check_col(pinfo->cinfo, COL_INFO)) {
5760                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
5761         }
5762
5763         /*
5764          * NOTE: the Service string is always ASCII, even if the
5765          * "strings are Unicode" bit is set in the flags2 field
5766          * of the SMB.
5767          */
5768
5769         /* Service */
5770         /* XXX - what if this runs past bc? */
5771         an_len = tvb_strsize(tvb, offset);
5772         CHECK_BYTE_COUNT(an_len);
5773         an = tvb_get_ptr(tvb, offset, an_len);
5774         proto_tree_add_string(tree, hf_smb_service, tvb,
5775                 offset, an_len, an);
5776         COUNT_BYTES(an_len);
5777
5778         END_OF_SMB
5779
5780         /* call AndXCommand (if there are any) */
5781         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5782
5783         return offset;
5784 }
5785
5786
5787 static int
5788 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5789 {
5790         guint8  wc, wleft, cmd=0xff;
5791         guint16 andxoffset=0;
5792         guint16 bc;
5793         int an_len;
5794         const char *an;
5795
5796         WORD_COUNT;
5797
5798         wleft = wc;     /* this is at least 1 */
5799
5800         /* next smb command */
5801         cmd = tvb_get_guint8(tvb, offset);
5802         if(cmd!=0xff){
5803                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5804         } else {
5805                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5806         }
5807         offset += 1;
5808
5809         /* reserved byte */
5810         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5811         offset += 1;
5812
5813         wleft--;
5814         if (wleft == 0)
5815                 goto bytecount;
5816
5817         /* andxoffset */
5818         andxoffset = tvb_get_letohs(tvb, offset);
5819         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5820         offset += 2;
5821         wleft--;
5822         if (wleft == 0)
5823                 goto bytecount;
5824
5825         /* flags */
5826         offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
5827         wleft--;
5828
5829         /* XXX - I've seen captures where this is 7, but I have no
5830            idea how to dissect it.  I'm guessing the third word
5831            contains connect support bits, which looks plausible
5832            from the values I've seen. */
5833
5834         while (wleft != 0) {
5835                 proto_tree_add_text(tree, tvb, offset, 2,
5836                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
5837                 offset += 2;
5838                 wleft--;
5839         }
5840
5841         BYTE_COUNT;
5842
5843         /*
5844          * NOTE: even though the SNIA CIFS spec doesn't say there's
5845          * a "Service" string if there's a word count of 2, the
5846          * document at
5847          *
5848          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
5849          *
5850          * (it's in an ugly format - text intended to be sent to a
5851          * printer, with backspaces and overstrikes used for boldfacing
5852          * and underlining; UNIX "col -b" can be used to strip the
5853          * overstrikes out) says there's a "Service" string there, and
5854          * some network traffic has it.
5855          */
5856
5857         /*
5858          * NOTE: the Service string is always ASCII, even if the
5859          * "strings are Unicode" bit is set in the flags2 field
5860          * of the SMB.
5861          */
5862
5863         /* Service */
5864         /* XXX - what if this runs past bc? */
5865         an_len = tvb_strsize(tvb, offset);
5866         CHECK_BYTE_COUNT(an_len);
5867         an = tvb_get_ptr(tvb, offset, an_len);
5868         proto_tree_add_string(tree, hf_smb_service, tvb,
5869                 offset, an_len, an);
5870         COUNT_BYTES(an_len);
5871
5872         /* Now when we know the service type, store it so that we know it for later commands down
5873            this tree */
5874         if(!pinfo->fd->flags.visited){
5875                 smb_info_t *si = (smb_info_t *)pinfo->private_data;
5876                 /* Remove any previous entry for this TID */
5877                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5878                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5879                 }
5880                 if(strcmp(an,"IPC") == 0){
5881                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5882                 } else {
5883                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
5884                 }
5885         }
5886
5887
5888         if(wc==3){
5889                 if (bc != 0) {
5890                         /*
5891                          * Sometimes this isn't present.
5892                          */
5893
5894                         /* Native FS */
5895                         an = get_unicode_or_ascii_string(tvb, &offset,
5896                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
5897                         if (an == NULL)
5898                                 goto endofcommand;
5899                         proto_tree_add_string(tree, hf_smb_fs, tvb,
5900                                 offset, an_len, an);
5901                         COUNT_BYTES(an_len);
5902                 }
5903         }
5904
5905         END_OF_SMB
5906
5907         /* call AndXCommand (if there are any) */
5908         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5909
5910         return offset;
5911 }
5912
5913
5914
5915 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5916    NT Transaction command  begins here
5917    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
5918 #define NT_TRANS_CREATE         1
5919 #define NT_TRANS_IOCTL          2
5920 #define NT_TRANS_SSD            3
5921 #define NT_TRANS_NOTIFY         4
5922 #define NT_TRANS_RENAME         5
5923 #define NT_TRANS_QSD            6
5924 #define NT_TRANS_GET_USER_QUOTA 7
5925 #define NT_TRANS_SET_USER_QUOTA 8
5926 static const value_string nt_cmd_vals[] = {
5927         {NT_TRANS_CREATE,               "NT CREATE"},
5928         {NT_TRANS_IOCTL,                "NT IOCTL"},
5929         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
5930         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
5931         {NT_TRANS_RENAME,               "NT RENAME"},
5932         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
5933         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
5934         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
5935         {0, NULL}
5936 };
5937
5938 static const value_string nt_ioctl_isfsctl_vals[] = {
5939         {0,     "Device IOCTL"},
5940         {1,     "FS control : FSCTL"},
5941         {0, NULL}
5942 };
5943
5944 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
5945 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
5946         "Apply the command to share root handle (MUST BE Dfs)",
5947         "Apply to this share",
5948 };
5949
5950 static const value_string nt_notify_action_vals[] = {
5951         {1,     "ADDED (object was added"},
5952         {2,     "REMOVED (object was removed)"},
5953         {3,     "MODIFIED (object was modified)"},
5954         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
5955         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
5956         {6,     "ADDED_STREAM (a stream was added)"},
5957         {7,     "REMOVED_STREAM (a stream was removed)"},
5958         {8,     "MODIFIED_STREAM (a stream was modified)"},
5959         {0, NULL}
5960 };
5961
5962 static const value_string watch_tree_vals[] = {
5963         {0,     "Current directory only"},
5964         {1,     "Subdirectories also"},
5965         {0, NULL}
5966 };
5967
5968 #define NT_NOTIFY_STREAM_WRITE  0x00000800
5969 #define NT_NOTIFY_STREAM_SIZE   0x00000400
5970 #define NT_NOTIFY_STREAM_NAME   0x00000200
5971 #define NT_NOTIFY_SECURITY      0x00000100
5972 #define NT_NOTIFY_EA            0x00000080
5973 #define NT_NOTIFY_CREATION      0x00000040
5974 #define NT_NOTIFY_LAST_ACCESS   0x00000020
5975 #define NT_NOTIFY_LAST_WRITE    0x00000010
5976 #define NT_NOTIFY_SIZE          0x00000008
5977 #define NT_NOTIFY_ATTRIBUTES    0x00000004
5978 #define NT_NOTIFY_DIR_NAME      0x00000002
5979 #define NT_NOTIFY_FILE_NAME     0x00000001
5980 static const true_false_string tfs_nt_notify_stream_write = {
5981         "Notify on changes to STREAM WRITE",
5982         "Do NOT notify on changes to stream write",
5983 };
5984 static const true_false_string tfs_nt_notify_stream_size = {
5985         "Notify on changes to STREAM SIZE",
5986         "Do NOT notify on changes to stream size",
5987 };
5988 static const true_false_string tfs_nt_notify_stream_name = {
5989         "Notify on changes to STREAM NAME",
5990         "Do NOT notify on changes to stream name",
5991 };
5992 static const true_false_string tfs_nt_notify_security = {
5993         "Notify on changes to SECURITY",
5994         "Do NOT notify on changes to security",
5995 };
5996 static const true_false_string tfs_nt_notify_ea = {
5997         "Notify on changes to EA",
5998         "Do NOT notify on changes to EA",
5999 };
6000 static const true_false_string tfs_nt_notify_creation = {
6001         "Notify on changes to CREATION TIME",
6002         "Do NOT notify on changes to creation time",
6003 };
6004 static const true_false_string tfs_nt_notify_last_access = {
6005         "Notify on changes to LAST ACCESS TIME",
6006         "Do NOT notify on changes to last access time",
6007 };
6008 static const true_false_string tfs_nt_notify_last_write = {
6009         "Notify on changes to LAST WRITE TIME",
6010         "Do NOT notify on changes to last write time",
6011 };
6012 static const true_false_string tfs_nt_notify_size = {
6013         "Notify on changes to SIZE",
6014         "Do NOT notify on changes to size",
6015 };
6016 static const true_false_string tfs_nt_notify_attributes = {
6017         "Notify on changes to ATTRIBUTES",
6018         "Do NOT notify on changes to attributes",
6019 };
6020 static const true_false_string tfs_nt_notify_dir_name = {
6021         "Notify on changes to DIR NAME",
6022         "Do NOT notify on changes to dir name",
6023 };
6024 static const true_false_string tfs_nt_notify_file_name = {
6025         "Notify on changes to FILE NAME",
6026         "Do NOT notify on changes to file name",
6027 };
6028
6029 static const value_string create_disposition_vals[] = {
6030         {0,     "Supersede (supersede existing file (if it exists))"},
6031         {1,     "Open (if file exists open it, else fail)"},
6032         {2,     "Create (if file exists fail, else create it)"},
6033         {3,     "Open If (if file exists open it, else create it)"},
6034         {4,     "Overwrite (if file exists overwrite, else fail)"},
6035         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6036         {0, NULL}
6037 };
6038
6039 static const value_string impersonation_level_vals[] = {
6040         {0,     "Anonymous"},
6041         {1,     "Identification"},
6042         {2,     "Impersonation"},
6043         {3,     "Delegation"},
6044         {0, NULL}
6045 };
6046
6047 static const true_false_string tfs_nt_security_flags_context_tracking = {
6048         "Security tracking mode is DYNAMIC",
6049         "Security tracking mode is STATIC",
6050 };
6051
6052 static const true_false_string tfs_nt_security_flags_effective_only = {
6053         "ONLY ENABLED aspects of the client's security context are available",
6054         "ALL aspects of the client's security context are available",
6055 };
6056
6057 static const true_false_string tfs_nt_create_bits_oplock = {
6058         "Requesting OPLOCK",
6059         "Does NOT request oplock"
6060 };
6061
6062 static const true_false_string tfs_nt_create_bits_boplock = {
6063         "Requesting BATCH OPLOCK",
6064         "Does NOT request batch oplock"
6065 };
6066
6067 /*
6068  * XXX - must be a directory, and can be a file, or can be a directory,
6069  * and must be a file?
6070  */
6071 static const true_false_string tfs_nt_create_bits_dir = {
6072         "Target of open MUST be a DIRECTORY",
6073         "Target of open can be a file"
6074 };
6075
6076 static const true_false_string tfs_nt_access_mask_generic_read = {
6077         "GENERIC READ is set",
6078         "Generic read is NOT set"
6079 };
6080 static const true_false_string tfs_nt_access_mask_generic_write = {
6081         "GENERIC WRITE is set",
6082         "Generic write is NOT set"
6083 };
6084 static const true_false_string tfs_nt_access_mask_generic_execute = {
6085         "GENERIC EXECUTE is set",
6086         "Generic execute is NOT set"
6087 };
6088 static const true_false_string tfs_nt_access_mask_generic_all = {
6089         "GENERIC ALL is set",
6090         "Generic all is NOT set"
6091 };
6092 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6093         "MAXIMUM ALLOWED is set",
6094         "Maximum allowed is NOT set"
6095 };
6096 static const true_false_string tfs_nt_access_mask_system_security = {
6097         "SYSTEM SECURITY is set",
6098         "System security is NOT set"
6099 };
6100 static const true_false_string tfs_nt_access_mask_synchronize = {
6101         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6102         "Can NOT wait on handle to synchronize on completion of I/O"
6103 };
6104 static const true_false_string tfs_nt_access_mask_write_owner = {
6105         "Can WRITE OWNER (take ownership)",
6106         "Can NOT write owner (take ownership)"
6107 };
6108 static const true_false_string tfs_nt_access_mask_write_dac = {
6109         "OWNER may WRITE the DAC",
6110         "Owner may NOT write to the DAC"
6111 };
6112 static const true_false_string tfs_nt_access_mask_read_control = {
6113         "READ ACCESS to owner, group and ACL of the SID",
6114         "Read access is NOT granted to owner, group and ACL of the SID"
6115 };
6116 static const true_false_string tfs_nt_access_mask_delete = {
6117         "DELETE access",
6118         "NO delete access"
6119 };
6120 static const true_false_string tfs_nt_access_mask_write_attributes = {
6121         "WRITE ATTRIBUTES access",
6122         "NO write attributes access"
6123 };
6124 static const true_false_string tfs_nt_access_mask_read_attributes = {
6125         "READ ATTRIBUTES access",
6126         "NO read attributes access"
6127 };
6128 static const true_false_string tfs_nt_access_mask_delete_child = {
6129         "DELETE CHILD access",
6130         "NO delete child access"
6131 };
6132 static const true_false_string tfs_nt_access_mask_execute = {
6133         "EXECUTE access",
6134         "NO execute access"
6135 };
6136 static const true_false_string tfs_nt_access_mask_write_ea = {
6137         "WRITE EXTENDED ATTRIBUTES access",
6138         "NO write extended attributes access"
6139 };
6140 static const true_false_string tfs_nt_access_mask_read_ea = {
6141         "READ EXTENDED ATTRIBUTES access",
6142         "NO read extended attributes access"
6143 };
6144 static const true_false_string tfs_nt_access_mask_append = {
6145         "APPEND access",
6146         "NO append access"
6147 };
6148 static const true_false_string tfs_nt_access_mask_write = {
6149         "WRITE access",
6150         "NO write access"
6151 };
6152 static const true_false_string tfs_nt_access_mask_read = {
6153         "READ access",
6154         "NO read access"
6155 };
6156
6157 static const true_false_string tfs_nt_share_access_delete = {
6158         "Object can be shared for DELETE",
6159         "Object can NOT be shared for delete"
6160 };
6161 static const true_false_string tfs_nt_share_access_write = {
6162         "Object can be shared for WRITE",
6163         "Object can NOT be shared for write"
6164 };
6165 static const true_false_string tfs_nt_share_access_read = {
6166         "Object can be shared for READ",
6167         "Object can NOT be shared for delete"
6168 };
6169
6170 static const value_string oplock_level_vals[] = {
6171         {0,     "No oplock granted"},
6172         {1,     "Exclusive oplock granted"},
6173         {2,     "Batch oplock granted"},
6174         {3,     "Level II oplock granted"},
6175         {0, NULL}
6176 };
6177
6178 static const value_string device_type_vals[] = {
6179         {0x00000001,    "Beep"},
6180         {0x00000002,    "CDROM"},
6181         {0x00000003,    "CDROM Filesystem"},
6182         {0x00000004,    "Controller"},
6183         {0x00000005,    "Datalink"},
6184         {0x00000006,    "Dfs"},
6185         {0x00000007,    "Disk"},
6186         {0x00000008,    "Disk Filesystem"},
6187         {0x00000009,    "Filesystem"},
6188         {0x0000000a,    "Inport Port"},
6189         {0x0000000b,    "Keyboard"},
6190         {0x0000000c,    "Mailslot"},
6191         {0x0000000d,    "MIDI-In"},
6192         {0x0000000e,    "MIDI-Out"},
6193         {0x0000000f,    "Mouse"},
6194         {0x00000010,    "Multi UNC Provider"},
6195         {0x00000011,    "Named Pipe"},
6196         {0x00000012,    "Network"},
6197         {0x00000013,    "Network Browser"},
6198         {0x00000014,    "Network Filesystem"},
6199         {0x00000015,    "NULL"},
6200         {0x00000016,    "Parallel Port"},
6201         {0x00000017,    "Physical card"},
6202         {0x00000018,    "Printer"},
6203         {0x00000019,    "Scanner"},
6204         {0x0000001a,    "Serial Mouse port"},
6205         {0x0000001b,    "Serial port"},
6206         {0x0000001c,    "Screen"},
6207         {0x0000001d,    "Sound"},
6208         {0x0000001e,    "Streams"},
6209         {0x0000001f,    "Tape"},
6210         {0x00000020,    "Tape Filesystem"},
6211         {0x00000021,    "Transport"},
6212         {0x00000022,    "Unknown"},
6213         {0x00000023,    "Video"},
6214         {0x00000024,    "Virtual Disk"},
6215         {0x00000025,    "WAVE-In"},
6216         {0x00000026,    "WAVE-Out"},
6217         {0x00000027,    "8042 Port"},
6218         {0x00000028,    "Network Redirector"},
6219         {0x00000029,    "Battery"},
6220         {0x0000002a,    "Bus Extender"},
6221         {0x0000002b,    "Modem"},
6222         {0x0000002c,    "VDM"},
6223         {0,     NULL}
6224 };
6225
6226 static const value_string is_directory_vals[] = {
6227         {0,     "This is NOT a directory"},
6228         {1,     "This is a DIRECTORY"},
6229         {0, NULL}
6230 };
6231
6232 typedef struct _nt_trans_data {
6233         int subcmd;
6234         guint32 sd_len;
6235         guint32 ea_len;
6236 } nt_trans_data;
6237
6238
6239
6240 static int
6241 dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6242 {
6243         guint8 mask;
6244         proto_item *item = NULL;
6245         proto_tree *tree = NULL;
6246
6247         mask = tvb_get_guint8(tvb, offset);
6248
6249         if(parent_tree){
6250                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6251                         "Security Flags: 0x%02x", mask);
6252                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6253         }
6254
6255         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6256                 tvb, offset, 1, mask);
6257         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6258                 tvb, offset, 1, mask);
6259
6260         offset += 1;
6261
6262         return offset;
6263 }
6264
6265 static int
6266 dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6267 {
6268         guint32 mask;
6269         proto_item *item = NULL;
6270         proto_tree *tree = NULL;
6271
6272         mask = tvb_get_letohl(tvb, offset);
6273
6274         if(parent_tree){
6275                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6276                         "Share Access: 0x%08x", mask);
6277                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6278         }
6279
6280         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6281                 tvb, offset, 4, mask);
6282         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6283                 tvb, offset, 4, mask);
6284         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6285                 tvb, offset, 4, mask);
6286
6287         offset += 4;
6288
6289         return offset;
6290 }
6291
6292
6293 static int
6294 dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6295 {
6296         guint32 mask;
6297         proto_item *item = NULL;
6298         proto_tree *tree = NULL;
6299
6300         mask = tvb_get_letohl(tvb, offset);
6301
6302         if(parent_tree){
6303                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6304                         "Access Mask: 0x%08x", mask);
6305                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6306         }
6307
6308         /*
6309          * Some of these bits come from 
6310          *
6311          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6312          *
6313          * and others come from the section on ZwOpenFile in "Windows(R)
6314          * NT(R)/2000 Native API Reference".
6315          */
6316         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6317                 tvb, offset, 4, mask);
6318         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6319                 tvb, offset, 4, mask);
6320         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6321                 tvb, offset, 4, mask);
6322         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6323                 tvb, offset, 4, mask);
6324         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6325                 tvb, offset, 4, mask);
6326         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6327                 tvb, offset, 4, mask);
6328         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6329                 tvb, offset, 4, mask);
6330         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6331                 tvb, offset, 4, mask);
6332         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6333                 tvb, offset, 4, mask);
6334         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6335                 tvb, offset, 4, mask);
6336         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6337                 tvb, offset, 4, mask);
6338         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6339                 tvb, offset, 4, mask);
6340         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6341                 tvb, offset, 4, mask);
6342         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6343                 tvb, offset, 4, mask);
6344         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6345                 tvb, offset, 4, mask);
6346         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6347                 tvb, offset, 4, mask);
6348         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6349                 tvb, offset, 4, mask);
6350         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6351                 tvb, offset, 4, mask);
6352         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6353                 tvb, offset, 4, mask);
6354         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6355                 tvb, offset, 4, mask);
6356
6357         offset += 4;
6358
6359         return offset;
6360 }
6361
6362 static int
6363 dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6364 {
6365         guint32 mask;
6366         proto_item *item = NULL;
6367         proto_tree *tree = NULL;
6368
6369         mask = tvb_get_letohl(tvb, offset);
6370
6371         if(parent_tree){
6372                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6373                         "Create Flags: 0x%08x", mask);
6374                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6375         }
6376
6377         /*
6378          * XXX - it's 0x00000016 in at least one capture, but
6379          * Network Monitor doesn't say what the 0x00000010 bit is.
6380          * Does the Win32 API documentation, or NT Native API book,
6381          * suggest anything?
6382          */
6383         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6384                 tvb, offset, 4, mask);
6385         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6386                 tvb, offset, 4, mask);
6387         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6388                 tvb, offset, 4, mask);
6389
6390         offset += 4;
6391
6392         return offset;
6393 }
6394
6395 /*
6396  * XXX - there are some more flags in the description of "ZwOpenFile()"
6397  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6398  * the wire as well?  (The spec at
6399  *
6400  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6401  *
6402  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6403  * via the SMB protocol.  The NT redirector should convert this option
6404  * to FILE_WRITE_THROUGH."
6405  *
6406  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6407  * values one would infer from their position in the list of flags for
6408  * "ZwOpenFile()".  Most of the others probably have those values
6409  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6410  * which might go over the wire (for the benefit of backup/restore software).
6411  */
6412 static const true_false_string tfs_nt_create_options_directory = {
6413         "File being created/opened must be a directory",
6414         "File being created/opened must not be a directory"
6415 };
6416 static const true_false_string tfs_nt_create_options_write_through = {
6417         "Writes should flush buffered data before completing",
6418         "Writes need not flush buffered data before completing"
6419 };
6420 static const true_false_string tfs_nt_create_options_sequential_only = {
6421         "The file will only be accessed sequentially",
6422         "The file might not only be accessed sequentially"
6423 };
6424 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6425         "All operations SYNCHRONOUS, waits subject to termination from alert",
6426         "Operations NOT necessarily synchronous"
6427 };
6428 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6429         "All operations SYNCHRONOUS, waits not subject to alert",
6430         "Operations NOT necessarily synchronous"
6431 };
6432 static const true_false_string tfs_nt_create_options_non_directory = {
6433         "File being created/opened must not be a directory",
6434         "File being created/opened must be a directory"
6435 };
6436 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6437         "The client does not understand extended attributes",
6438         "The client understands extended attributes"
6439 };
6440 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6441         "The client understands only 8.3 file names",
6442         "The client understands long file names"
6443 };
6444 static const true_false_string tfs_nt_create_options_random_access = {
6445         "The file will be accessed randomly",
6446         "The file will not be accessed randomly"
6447 };
6448 static const true_false_string tfs_nt_create_options_delete_on_close = {
6449         "The file should be deleted when it is closed",
6450         "The file should not be deleted when it is closed"
6451 };
6452
6453 static int
6454 dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6455 {
6456         guint32 mask;
6457         proto_item *item = NULL;
6458         proto_tree *tree = NULL;
6459
6460         mask = tvb_get_letohl(tvb, offset);
6461
6462         if(parent_tree){
6463                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6464                         "Create Options: 0x%08x", mask);
6465                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6466         }
6467
6468         /*
6469          * From
6470          *
6471          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6472          */
6473         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6474                 tvb, offset, 4, mask);
6475         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6476                 tvb, offset, 4, mask);
6477         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6478                 tvb, offset, 4, mask);
6479         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6480                 tvb, offset, 4, mask);
6481         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6482                 tvb, offset, 4, mask);
6483         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6484                 tvb, offset, 4, mask);
6485         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6486                 tvb, offset, 4, mask);
6487         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6488                 tvb, offset, 4, mask);
6489         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6490                 tvb, offset, 4, mask);
6491         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6492                 tvb, offset, 4, mask);
6493
6494         offset += 4;
6495
6496         return offset;
6497 }
6498  
6499 static int
6500 dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6501 {
6502         guint32 mask;
6503         proto_item *item = NULL;
6504         proto_tree *tree = NULL;
6505
6506         mask = tvb_get_letohl(tvb, offset);
6507
6508         if(parent_tree){
6509                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6510                         "Completion Filter: 0x%08x", mask);
6511                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6512         }
6513  
6514         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6515                 tvb, offset, 4, mask);
6516         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6517                 tvb, offset, 4, mask);
6518         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6519                 tvb, offset, 4, mask);
6520         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6521                 tvb, offset, 4, mask);
6522         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6523                 tvb, offset, 4, mask);
6524         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6525                 tvb, offset, 4, mask);
6526         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6527                 tvb, offset, 4, mask);
6528         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6529                 tvb, offset, 4, mask);
6530         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6531                 tvb, offset, 4, mask);
6532         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6533                 tvb, offset, 4, mask);
6534         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6535                 tvb, offset, 4, mask);
6536         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6537                 tvb, offset, 4, mask);
6538
6539         offset += 4;
6540         return offset;
6541 }
6542  
6543 static int
6544 dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6545 {
6546         guint8 mask;
6547         proto_item *item = NULL;
6548         proto_tree *tree = NULL;
6549
6550         mask = tvb_get_guint8(tvb, offset);
6551
6552         if(parent_tree){
6553                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6554                         "Completion Filter: 0x%02x", mask);
6555                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6556         }
6557
6558         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6559                 tvb, offset, 1, mask);
6560
6561         offset += 1;
6562         return offset;
6563 }
6564
6565 /*
6566  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6567  * Native API Reference".
6568  */
6569 static const true_false_string tfs_nt_qsd_owner = {
6570         "Requesting OWNER security information",
6571         "NOT requesting owner security information",
6572 };
6573
6574 static const true_false_string tfs_nt_qsd_group = {
6575         "Requesting GROUP security information",
6576         "NOT requesting group security information",
6577 };
6578
6579 static const true_false_string tfs_nt_qsd_dacl = {
6580         "Requesting DACL security information",
6581         "NOT requesting DACL security information",
6582 };
6583
6584 static const true_false_string tfs_nt_qsd_sacl = {
6585         "Requesting SACL security information",
6586         "NOT requesting SACL security information",
6587 };
6588
6589 #define NT_QSD_OWNER    0x00000001
6590 #define NT_QSD_GROUP    0x00000002
6591 #define NT_QSD_DACL     0x00000004
6592 #define NT_QSD_SACL     0x00000008
6593
6594 static int
6595 dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6596 {
6597         guint32 mask;
6598         proto_item *item = NULL;
6599         proto_tree *tree = NULL;
6600
6601         mask = tvb_get_letohl(tvb, offset);
6602
6603         if(parent_tree){
6604                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6605                         "Security Information: 0x%08x", mask);
6606                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6607         }
6608
6609         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6610                 tvb, offset, 4, mask);
6611         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6612                 tvb, offset, 4, mask);
6613         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6614                 tvb, offset, 4, mask);
6615         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6616                 tvb, offset, 4, mask);
6617
6618         offset += 4;
6619
6620         return offset;
6621 }
6622
6623 static void
6624 free_g_string(void *arg)
6625 {
6626         GString *gstring = arg;
6627
6628         g_string_free(arg, TRUE);
6629 }
6630
6631 int
6632 dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6633 {
6634         proto_item *item = NULL;
6635         proto_tree *tree = NULL;
6636         int old_offset = offset, sa_offset = offset;
6637         guint *s_auths = NULL;
6638         guint rid;
6639         guint8 revision;
6640         guint8 num_auth;
6641         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6642         int i;
6643         GString *gstr;
6644
6645         if(parent_tree){
6646                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6647                                            "NT %s SID", name);
6648                 tree = proto_item_add_subtree(item, ett_smb_sid);
6649         }
6650
6651         /* revision of sid */
6652         revision = tvb_get_guint8(tvb, offset);
6653         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6654         offset += 1;
6655
6656         switch(revision){
6657         case 1:  
6658         case 2:  /* Not sure what the different revision numbers mean */
6659           /* number of authorities*/
6660           num_auth = tvb_get_guint8(tvb, offset);
6661           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6662           offset += 1;
6663
6664           /* XXX perhaps we should have these thing searchable?
6665              a new FT_xxx thingie? SMB is quite common!*/
6666           /* identifier authorities */
6667
6668           /* FIXME: We should dynamically allocate the authorities array,
6669              which is only one thing. Then we don't have to allocate two
6670              strings below etc ...
6671           */
6672
6673           for(i=0;i<6;i++){
6674             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
6675
6676             offset++;
6677           }
6678
6679           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
6680
6681           sa_offset = offset;
6682
6683           CLEANUP_PUSH(free, s_auths);
6684
6685           s_auths = g_malloc(sizeof(guint) * num_auth);
6686
6687           /* sub authorities, leave RID to last */
6688           /* FIXME: If we take an exception now, we lose the whole 
6689              sub-authorities string thang */
6690           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
6691             /* XXX should not be letohl but native byteorder according to
6692                samba header files. considering that all non-x86 NT ports
6693                are dead we can (?) assume that non le byte encodings
6694                will be "uncommon"?*/
6695               s_auths[i] = tvb_get_letohl(tvb, offset);
6696               offset+=4;
6697           }
6698
6699           CLEANUP_CALL_AND_POP;
6700
6701           gstr = g_string_new("");
6702           
6703           for (i = 0; i < (num_auth>4?(num_auth - 1):num_auth); i++)
6704               g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"), s_auths[i]);
6705
6706           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
6707
6708           if (num_auth > 4) {
6709             rid = tvb_get_letohl(tvb, offset);
6710             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
6711             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
6712             offset+=4;
6713           }
6714           else {
6715             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
6716           }
6717
6718         }
6719
6720         proto_item_set_len(item, offset-old_offset);
6721         return offset;
6722 }
6723
6724
6725 static const value_string ace_type_vals[] = {
6726   { 0, "Access Allowed"},
6727   { 1, "Access Denied"},
6728   { 2, "System Audit"},
6729   { 3, "System Alarm"},
6730   { 0, NULL}
6731 };
6732 static const true_false_string tfs_ace_flags_object_inherit = {
6733   "Subordinate files will inherit this ACE",
6734   "Subordinate files will not inherit this ACE"
6735 };
6736 static const true_false_string tfs_ace_flags_container_inherit = {
6737   "Subordinate containers will inherit this ACE",
6738   "Subordinate containers will not inherit this ACE"
6739 };
6740 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
6741   "Subordinate object will not propagate the inherited ACE further",
6742   "Subordinate object will propagate the inherited ACE further"
6743 };
6744 static const true_false_string tfs_ace_flags_inherit_only = {
6745   "This ACE does not apply to the current object",
6746   "This ACE applies to the current object"
6747 };
6748 static const true_false_string tfs_ace_flags_inherited_ace = {
6749   "This ACE was inherited from its parent object",
6750   "This ACE was not inherited from its parent object"
6751 };
6752 static const true_false_string tfs_ace_flags_successful_access = {
6753   "Successful accesses will be audited",
6754   "Successful accesses will not be audited"
6755 };
6756 static const true_false_string tfs_ace_flags_failed_access = {
6757   "Failed accesses will be audited",
6758   "Failed accesses will not be audited"
6759 };
6760
6761 #define APPEND_ACE_TEXT(flag, item, string) \
6762         if(flag){                                                       \
6763                 if(item)                                                \
6764                         proto_item_append_text(item, string, sep);      \
6765                 sep = ", ";                                             \
6766         }
6767
6768 static int
6769 dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6770 {
6771         proto_item *item = NULL;
6772         proto_tree *tree = NULL;
6773         guint8 mask;
6774         char *sep = " ";
6775
6776         mask = tvb_get_guint8(tvb, offset);
6777         if(parent_tree){
6778                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6779                                            "NT ACE Flags: 0x%02x", mask);
6780                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
6781         }
6782
6783         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
6784                        tvb, offset, 1, mask);
6785         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
6786
6787         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
6788                        tvb, offset, 1, mask);
6789         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
6790
6791         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
6792                        tvb, offset, 1, mask);
6793         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
6794
6795         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
6796                        tvb, offset, 1, mask);
6797         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
6798
6799         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
6800                        tvb, offset, 1, mask);
6801         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
6802
6803         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
6804                        tvb, offset, 1, mask);
6805         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
6806
6807         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
6808                        tvb, offset, 1, mask);
6809         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
6810
6811
6812         offset += 1;
6813         return offset;
6814 }
6815
6816 static int
6817 dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6818 {
6819         proto_item *item = NULL;
6820         proto_tree *tree = NULL;
6821         int old_offset = offset;
6822         
6823         if(parent_tree){
6824                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6825                                            "NT ACE: ");
6826                 tree = proto_item_add_subtree(item, ett_smb_ace);
6827         }
6828
6829         /* type */
6830         if(item){
6831           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
6832         }
6833         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
6834         offset += 1;
6835
6836         /* flags */
6837         offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
6838
6839         /* size */
6840         proto_tree_add_item(tree, hf_smb_ace_size, tvb, offset, 2, TRUE);
6841         offset += 2;
6842
6843         /* access mask */
6844         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6845
6846         /* SID */
6847         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
6848
6849         proto_item_set_len(item, offset-old_offset);
6850         return offset;
6851 }
6852
6853 static int
6854 dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6855 {
6856         proto_item *item = NULL;
6857         proto_tree *tree = NULL;
6858         int old_offset = offset;
6859         guint16 revision, size;
6860         guint32 num_aces;
6861
6862         if(parent_tree){
6863                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6864                                            "NT %s ACL", name);
6865                 tree = proto_item_add_subtree(item, ett_smb_acl);
6866         }
6867
6868         /* revision */
6869         revision = tvb_get_letohs(tvb, offset);
6870         proto_tree_add_uint(tree, hf_smb_acl_revision,
6871                 tvb, offset, 2, revision);
6872         offset += 2;
6873
6874         switch(revision){
6875         case 2:  /* only version we will ever see of this structure?*/
6876         case 3:
6877           /* size */
6878           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
6879           offset += 2;
6880
6881           /* number of ace structures */
6882           num_aces = tvb_get_letohl(tvb, offset);
6883           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
6884                               tvb, offset, 4, num_aces);
6885           offset += 4;
6886
6887           while(num_aces--){
6888             offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
6889           }
6890         }
6891
6892         proto_item_set_len(item, offset-old_offset);
6893         return offset;
6894 }
6895
6896 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
6897   "OWNER is DEFAULTED",
6898   "Owner is NOT defaulted"
6899 };
6900 static const true_false_string tfs_sec_desc_type_group_defaulted = {
6901   "GROUP is DEFAULTED",
6902   "Group is NOT defaulted"
6903 };
6904 static const true_false_string tfs_sec_desc_type_dacl_present = {
6905   "DACL is PRESENT",
6906   "DACL is NOT present"
6907 };
6908 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
6909   "DACL is DEFAULTED",
6910   "DACL is NOT defaulted"
6911 };
6912 static const true_false_string tfs_sec_desc_type_sacl_present = {
6913   "SACL is PRESENT",
6914   "SACL is NOT present"
6915 };
6916 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
6917   "SACL is DEFAULTED",
6918   "SACL is NOT defaulted"
6919 };
6920 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
6921   "DACL has AUTO INHERIT REQUIRED",
6922   "DACL does NOT require auto inherit"
6923 };
6924 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
6925   "SACL has AUTO INHERIT REQUIRED",
6926   "SACL does NOT require auto inherit"
6927 };
6928 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
6929   "DACL is AUTO INHERITED",
6930   "DACL is NOT auto inherited"
6931 };
6932 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
6933   "SACL is AUTO INHERITED",
6934   "SACL is NOT auto inherited"
6935 };
6936 static const true_false_string tfs_sec_desc_type_dacl_protected = {
6937   "The DACL is PROTECTED",
6938   "The DACL is NOT protected"
6939 };
6940 static const true_false_string tfs_sec_desc_type_sacl_protected = {
6941   "The SACL is PROTECTED",
6942   "The SACL is NOT protected"
6943 };
6944 static const true_false_string tfs_sec_desc_type_self_relative = {
6945   "This SecDesc is SELF RELATIVE",
6946   "This SecDesc is NOT self relative"
6947 };
6948
6949
6950 static int
6951 dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6952 {
6953         proto_item *item = NULL;
6954         proto_tree *tree = NULL;
6955         guint16 mask;
6956
6957         mask = tvb_get_letohs(tvb, offset);
6958         if(parent_tree){
6959                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6960                                            "Type: 0x%04x", mask);
6961                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
6962         }
6963
6964         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
6965                                tvb, offset, 2, mask);
6966         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
6967                                tvb, offset, 2, mask);
6968         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
6969                                tvb, offset, 2, mask);
6970         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
6971                                tvb, offset, 2, mask);
6972         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
6973                                tvb, offset, 2, mask);
6974         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
6975                                tvb, offset, 2, mask);
6976         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
6977                                tvb, offset, 2, mask);
6978         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
6979                                tvb, offset, 2, mask);
6980         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
6981                                tvb, offset, 2, mask);
6982         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
6983                                tvb, offset, 2, mask);
6984         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
6985                                tvb, offset, 2, mask);
6986         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
6987                                tvb, offset, 2, mask);
6988         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
6989                                tvb, offset, 2, mask);
6990
6991
6992         offset += 2;
6993         return offset;
6994 }
6995
6996 /* This function is also called from DCREPC services; it may be that, in
6997    some cases, the NDR syntax must be followed, but that's not the case,
6998    for example, for the security descriptor inside an LSA Security
6999    Descriptor structure.
7000
7001    A "len" of -1 means that the NDR syntax must be followed.
7002    In that case, we assume that owner SID, group SID, SACL, and DACL objects
7003    are always stored in order (when present) and that all of them are aligned
7004    on a 4 byte boundary, and we no longer use the xxx_offset other than to
7005    check that they are non-NULL to be compatible with DCERPC NDR Unique.
7006
7007    Otherwise, we use the offsets to see where the owner SID, group SID,
7008    SACL, and DACL are stored. */
7009 int
7010 dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
7011 {
7012         proto_item *item = NULL;
7013         proto_tree *tree = NULL;
7014         guint16 revision;
7015         int old_offset = offset;
7016         guint32 owner_sid_offset;
7017         guint32 group_sid_offset;
7018         guint32 sacl_offset;
7019         guint32 dacl_offset;
7020
7021         if(parent_tree){
7022                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7023                                            "NT Security Descriptor");
7024                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7025         }
7026
7027         /* revision */
7028         revision = tvb_get_letohs(tvb, offset);
7029         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7030                 tvb, offset, 2, revision);
7031         offset += 2;
7032
7033         switch(revision){
7034         case 1:  /* only version we will ever see of this structure?*/
7035           /* type */
7036           offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
7037
7038           /* offset to owner sid */
7039           owner_sid_offset = tvb_get_letohl(tvb, offset);
7040           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
7041           offset += 4;
7042
7043           /* offset to group sid */
7044           group_sid_offset = tvb_get_letohl(tvb, offset);
7045           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
7046           offset += 4;
7047
7048           /* offset to sacl */
7049           sacl_offset = tvb_get_letohl(tvb, offset);
7050           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
7051           offset += 4;
7052
7053           /* offset to dacl */
7054           dacl_offset = tvb_get_letohl(tvb, offset);
7055           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
7056           offset += 4;
7057
7058           /*owner SID*/
7059           if(owner_sid_offset){
7060             if (len == -1)
7061               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Owner");
7062             else
7063               dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
7064           }
7065
7066           /*group SID*/
7067           if(group_sid_offset){
7068             if (len == -1)
7069               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Group");
7070             else
7071               dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
7072           }
7073
7074           /* sacl */
7075           if(sacl_offset){
7076             if (len == -1)
7077               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "System (SACL)");
7078             else
7079               dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
7080           }
7081
7082           /* dacl */
7083           if(dacl_offset){
7084             if (len == -1)
7085               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "User (DACL)");
7086             else
7087               dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
7088           }
7089
7090         }
7091
7092         if (len == -1) {
7093                 proto_item_set_len(item, offset-old_offset);
7094                 return offset;
7095         } else
7096                 return offset+len;
7097 }
7098
7099 static int
7100 dissect_nt_user_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
7101 {
7102         int old_offset, old_sid_offset;
7103         guint32 qsize;
7104
7105         do {
7106                 old_offset=offset;
7107
7108                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7109                 qsize=tvb_get_letohl(tvb, offset);
7110                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7111                 COUNT_BYTES_TRANS_SUBR(4);
7112
7113                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7114                 /* length of SID */
7115                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7116                 COUNT_BYTES_TRANS_SUBR(4);
7117
7118                 /* 16 unknown bytes */
7119                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7120                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7121                             offset, 8, TRUE);
7122                 COUNT_BYTES_TRANS_SUBR(8);
7123
7124                 /* number of bytes for used quota */
7125                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7126                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7127                 COUNT_BYTES_TRANS_SUBR(8);
7128
7129                 /* number of bytes for quota warning */
7130                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7131                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7132                 COUNT_BYTES_TRANS_SUBR(8);
7133
7134                 /* number of bytes for quota limit */
7135                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7136                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7137                 COUNT_BYTES_TRANS_SUBR(8);
7138
7139                 /* SID of the user */
7140                 old_sid_offset=offset;
7141                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7142                 *bcp -= (offset-old_sid_offset);
7143
7144                 if(qsize){
7145                         offset = old_offset+qsize;
7146                 }
7147         }while(qsize);
7148
7149
7150         return offset;
7151 }
7152
7153
7154 static int
7155 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7156 {
7157         proto_item *item = NULL;
7158         proto_tree *tree = NULL;
7159         smb_info_t *si;
7160         int old_offset = offset;
7161         guint16 bcp=bc; /* XXX fixme */
7162
7163         si = (smb_info_t *)pinfo->private_data;
7164
7165         if(parent_tree){
7166                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7167                                 "%s Data",
7168                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7169                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7170         }
7171
7172         switch(ntd->subcmd){
7173         case NT_TRANS_CREATE:
7174                 /* security descriptor */
7175                 if(ntd->sd_len){
7176                         offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
7177                 }
7178
7179                 /* extended attributes */
7180                 if(ntd->ea_len){
7181                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7182                         offset += ntd->ea_len;
7183                 }
7184
7185                 break;
7186         case NT_TRANS_IOCTL:
7187                 /* ioctl data */
7188                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7189                 offset += bc;
7190
7191                 break;
7192         case NT_TRANS_SSD:
7193                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, bc);
7194                 break;
7195         case NT_TRANS_NOTIFY:
7196                 break;
7197         case NT_TRANS_RENAME:
7198                 /* XXX not documented */
7199                 break;
7200         case NT_TRANS_QSD:
7201                 break;
7202         case NT_TRANS_GET_USER_QUOTA:
7203                 /* unknown 4 bytes */
7204                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7205                             offset, 4, TRUE);
7206                 offset += 4;
7207
7208                 /* length of SID */
7209                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7210                 offset +=4;
7211
7212                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7213                 break;
7214         case NT_TRANS_SET_USER_QUOTA:
7215                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7216                 break;
7217         }
7218
7219         /* ooops there were data we didnt know how to process */
7220         if((offset-old_offset) < bc){
7221                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7222                     bc - (offset-old_offset), TRUE);
7223                 offset += bc - (offset-old_offset);
7224         }
7225
7226         return offset;
7227 }
7228
7229 static int
7230 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)
7231 {
7232         proto_item *item = NULL;
7233         proto_tree *tree = NULL;
7234         smb_info_t *si;
7235         guint32 fn_len;
7236         const char *fn;
7237
7238         si = (smb_info_t *)pinfo->private_data;
7239
7240         if(parent_tree){
7241                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7242                                 "%s Parameters",
7243                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7244                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7245         }
7246
7247         switch(ntd->subcmd){
7248         case NT_TRANS_CREATE:
7249                 /* Create flags */
7250                 offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
7251                 bc -= 4;
7252
7253                 /* root directory fid */
7254                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7255                 COUNT_BYTES(4);
7256
7257                 /* nt access mask */
7258                 offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
7259                 bc -= 4;
7260         
7261                 /* allocation size */
7262                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7263                 COUNT_BYTES(8);
7264         
7265                 /* Extended File Attributes */
7266                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7267                 bc -= 4;
7268
7269                 /* share access */
7270                 offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
7271                 bc -= 4;
7272         
7273                 /* create disposition */
7274                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7275                 COUNT_BYTES(4);
7276
7277                 /* create options */
7278                 offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
7279                 bc -= 4;
7280
7281                 /* sd length */
7282                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7283                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7284                 COUNT_BYTES(4);
7285
7286                 /* ea length */
7287                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7288                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7289                 COUNT_BYTES(4);
7290
7291                 /* file name len */
7292                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7293                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7294                 COUNT_BYTES(4);
7295
7296                 /* impersonation level */
7297                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7298                 COUNT_BYTES(4);
7299         
7300                 /* security flags */
7301                 offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
7302                 bc -= 1;
7303
7304                 /* file name */
7305                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7306                 if (fn != NULL) {
7307                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7308                                 fn);
7309                         COUNT_BYTES(fn_len);
7310                 }
7311
7312                 break;
7313         case NT_TRANS_IOCTL:
7314                 break;
7315         case NT_TRANS_SSD: {
7316                 guint16 fid;
7317
7318                 /* fid */
7319                 fid = tvb_get_letohs(tvb, offset);
7320                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7321                 offset += 2;
7322
7323                 /* 2 reserved bytes */
7324                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7325                 offset += 2;
7326
7327                 /* security information */
7328                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7329                 break;
7330         }
7331         case NT_TRANS_NOTIFY:
7332                 break;
7333         case NT_TRANS_RENAME:
7334                 /* XXX not documented */
7335                 break;
7336         case NT_TRANS_QSD: {
7337                 guint16 fid;
7338
7339                 /* fid */
7340                 fid = tvb_get_letohs(tvb, offset);
7341                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7342                 offset += 2;
7343
7344                 /* 2 reserved bytes */
7345                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7346                 offset += 2;
7347
7348                 /* security information */
7349                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7350                 break;
7351         }
7352         case NT_TRANS_GET_USER_QUOTA:
7353                 /* not decoded yet */
7354                 break;
7355         case NT_TRANS_SET_USER_QUOTA:
7356                 /* not decoded yet */
7357                 break;
7358         }
7359
7360         return offset;
7361 }
7362
7363 static int
7364 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7365 {
7366         proto_item *item = NULL;
7367         proto_tree *tree = NULL;
7368         smb_info_t *si;
7369         int old_offset = offset;
7370
7371         si = (smb_info_t *)pinfo->private_data;
7372
7373         if(parent_tree){
7374                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7375                                 "%s Setup",
7376                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7377                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7378         }
7379  
7380         switch(ntd->subcmd){
7381         case NT_TRANS_CREATE:
7382                 break;
7383         case NT_TRANS_IOCTL: {
7384                 guint16 fid;
7385
7386                 /* function code */
7387                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7388                 offset += 4;
7389
7390                 /* fid */
7391                 fid = tvb_get_letohs(tvb, offset);
7392                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7393                 offset += 2;
7394
7395                 /* isfsctl */
7396                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7397                 offset += 1;
7398
7399                 /* isflags */
7400                 offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
7401
7402                 break;
7403         }
7404         case NT_TRANS_SSD:
7405                 break;
7406         case NT_TRANS_NOTIFY: {
7407                 guint16 fid;
7408
7409                 /* completion filter */
7410                 offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
7411
7412                 /* fid */
7413                 fid = tvb_get_letohs(tvb, offset);
7414                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7415                 offset += 2;
7416
7417                 /* watch tree */
7418                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7419                 offset += 1;
7420
7421                 /* reserved byte */
7422                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7423                 offset += 1;
7424
7425                 break;
7426         }
7427         case NT_TRANS_RENAME:
7428                 /* XXX not documented */
7429                 break;
7430         case NT_TRANS_QSD:
7431                 break;
7432         case NT_TRANS_GET_USER_QUOTA:
7433                 /* not decoded yet */
7434                 break;
7435         case NT_TRANS_SET_USER_QUOTA:
7436                 /* not decoded yet */
7437                 break;
7438         }
7439  
7440         return old_offset+len;
7441 }
7442
7443
7444 static int
7445 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7446 {
7447         guint8 wc, sc;
7448         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7449         smb_info_t *si;
7450         smb_saved_info_t *sip;
7451         int subcmd;
7452         nt_trans_data ntd;
7453         guint16 bc;
7454         int padcnt;
7455         smb_nt_transact_info_t *nti;
7456
7457         si = (smb_info_t *)pinfo->private_data;
7458         sip = si->sip;
7459
7460         WORD_COUNT;
7461
7462         if(wc>=19){
7463                 /* primary request */
7464                 /* max setup count */
7465                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7466                 offset += 1;
7467
7468                 /* 2 reserved bytes */
7469                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7470                 offset += 2;
7471         } else {
7472                 /* secondary request */
7473                 /* 3 reserved bytes */
7474                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7475                 offset += 3;
7476         }
7477
7478
7479         /* total param count */
7480         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7481         offset += 4;
7482         
7483         /* total data count */
7484         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7485         offset += 4;
7486
7487         if(wc>=19){
7488                 /* primary request */
7489                 /* max param count */
7490                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7491                 offset += 4;
7492
7493                 /* max data count */
7494                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7495                 offset += 4;
7496         }
7497
7498         /* param count */
7499         pc = tvb_get_letohl(tvb, offset);
7500         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7501         offset += 4;
7502         
7503         /* param offset */
7504         po = tvb_get_letohl(tvb, offset);
7505         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7506         offset += 4;
7507
7508         /* param displacement */
7509         if(wc>=19){
7510                 /* primary request*/
7511                 pd = 0;
7512         } else {
7513                 /* secondary request */
7514                 pd = tvb_get_letohl(tvb, offset);
7515                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7516                 offset += 4;
7517         }
7518
7519         /* data count */
7520         dc = tvb_get_letohl(tvb, offset);
7521         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7522         offset += 4;
7523
7524         /* data offset */
7525         od = tvb_get_letohl(tvb, offset);
7526         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7527         offset += 4;
7528
7529         /* data displacement */
7530         if(wc>=19){
7531                 /* primary request */
7532                 dd = 0;
7533         } else {
7534                 /* secondary request */
7535                 dd = tvb_get_letohl(tvb, offset);
7536                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7537                 offset += 4;
7538         }
7539
7540         /* setup count */
7541         if(wc>=19){
7542                 /* primary request */
7543                 sc = tvb_get_guint8(tvb, offset);
7544                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7545                 offset += 1;
7546         } else {
7547                 /* secondary request */
7548                 sc = 0;
7549         }
7550
7551         /* function */
7552         if(wc>=19){
7553                 /* primary request */
7554                 subcmd = tvb_get_letohs(tvb, offset);
7555                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7556                 if(check_col(pinfo->cinfo, COL_INFO)){
7557                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7558                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7559                 }
7560                 ntd.subcmd = subcmd;
7561                 if (!si->unidir) {
7562                         if(!pinfo->fd->flags.visited){
7563                                 /* 
7564                                  * Allocate a new smb_nt_transact_info_t
7565                                  * structure.
7566                                  */
7567                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7568                                 nti->subcmd = subcmd;
7569                                 sip->extra_info = nti;
7570                         }
7571                 }
7572         } else {
7573                 /* secondary request */
7574                 if(check_col(pinfo->cinfo, COL_INFO)){
7575                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7576                 }
7577         }
7578         offset += 2;
7579
7580         /* this is a padding byte */
7581         if(offset%1){
7582                 /* pad byte */
7583                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7584                 offset += 1;
7585         }
7586
7587         /* if there were any setup bytes, decode them */
7588         if(sc){
7589                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7590                 offset += sc*2;
7591         }
7592
7593         BYTE_COUNT;
7594         
7595         /* parameters */
7596         if(po>(guint32)offset){
7597                 /* We have some initial padding bytes.
7598                 */
7599                 padcnt = po-offset;
7600                 if (padcnt > bc)
7601                         padcnt = bc;
7602                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7603                 COUNT_BYTES(padcnt);
7604         }
7605         if(pc){
7606                 CHECK_BYTE_COUNT(pc);
7607                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7608                 COUNT_BYTES(pc);
7609         }
7610
7611         /* data */
7612         if(od>(guint32)offset){
7613                 /* We have some initial padding bytes.
7614                 */
7615                 padcnt = od-offset;
7616                 if (padcnt > bc)
7617                         padcnt = bc;
7618                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7619                 COUNT_BYTES(padcnt);
7620         }
7621         if(dc){
7622                 CHECK_BYTE_COUNT(dc);
7623                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7624                 COUNT_BYTES(dc);
7625         }
7626
7627         END_OF_SMB
7628
7629         return offset;
7630 }
7631
7632
7633
7634 static int
7635 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7636 {
7637         proto_item *item = NULL;
7638         proto_tree *tree = NULL;
7639         smb_info_t *si;
7640         smb_nt_transact_info_t *nti;
7641         guint16 bcp;
7642
7643         si = (smb_info_t *)pinfo->private_data;
7644         if (si->sip != NULL)
7645                 nti = si->sip->extra_info;
7646         else
7647                 nti = NULL;
7648
7649         if(parent_tree){
7650                 if(nti != NULL){
7651                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7652                                 "%s Data",
7653                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7654                 } else {
7655                         /*
7656                          * We never saw the request to which this is a
7657                          * response.
7658                          */
7659                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7660                                 "Unknown NT Transaction Data (matching request not seen)");
7661                 }
7662                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7663         }
7664
7665         if (nti == NULL) {
7666                 offset += len;
7667                 return offset;
7668         }
7669         switch(nti->subcmd){
7670         case NT_TRANS_CREATE:
7671                 break;
7672         case NT_TRANS_IOCTL:
7673                 /* ioctl data */
7674                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7675                 offset += len;
7676
7677                 break;
7678         case NT_TRANS_SSD:
7679                 break;
7680         case NT_TRANS_NOTIFY:
7681                 break;
7682         case NT_TRANS_RENAME:
7683                 /* XXX not documented */
7684                 break;
7685         case NT_TRANS_QSD:
7686                 /*
7687                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7688                  * which may be documented in the Win32 documentation
7689                  * somewhere.
7690                  */
7691                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
7692                 break;
7693         case NT_TRANS_GET_USER_QUOTA:
7694                 bcp=len;
7695                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7696                 break;
7697         case NT_TRANS_SET_USER_QUOTA:
7698                 /* not decoded yet */
7699                 break;
7700         }
7701
7702         return offset;
7703 }
7704  
7705 static int
7706 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)
7707 {
7708         proto_item *item = NULL;
7709         proto_tree *tree = NULL;
7710         guint32 fn_len;
7711         const char *fn;
7712         smb_info_t *si;
7713         smb_nt_transact_info_t *nti;
7714         guint16 fid;
7715         int old_offset;
7716         guint32 neo;
7717         int padcnt;
7718
7719         si = (smb_info_t *)pinfo->private_data;
7720         if (si->sip != NULL)
7721                 nti = si->sip->extra_info;
7722         else
7723                 nti = NULL;
7724
7725         if(parent_tree){
7726                 if(nti != NULL){
7727                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7728                                 "%s Parameters",
7729                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7730                 } else {
7731                         /*
7732                          * We never saw the request to which this is a
7733                          * response.
7734                          */
7735                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7736                                 "Unknown NT Transaction Parameters (matching request not seen)");
7737                 }
7738                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7739         }
7740
7741         if (nti == NULL) {
7742                 offset += len;
7743                 return offset;
7744         }
7745         switch(nti->subcmd){
7746         case NT_TRANS_CREATE:
7747                 /* oplock level */
7748                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7749                 offset += 1;
7750
7751                 /* reserved byte */
7752                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7753                 offset += 1;
7754                 
7755                 /* fid */
7756                 fid = tvb_get_letohs(tvb, offset);
7757                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7758                 offset += 2;
7759
7760                 /* create action */
7761                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7762                 offset += 4;
7763
7764                 /* ea error offset */
7765                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7766                 offset += 4;
7767
7768                 /* create time */
7769                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7770                         hf_smb_create_time);
7771         
7772                 /* access time */
7773                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7774                         hf_smb_access_time);
7775         
7776                 /* last write time */
7777                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7778                         hf_smb_last_write_time);
7779         
7780                 /* last change time */
7781                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7782                         hf_smb_change_time);
7783         
7784                 /* Extended File Attributes */
7785                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7786
7787                 /* allocation size */
7788                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7789                 offset += 8;
7790
7791                 /* end of file */
7792                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7793                 offset += 8;
7794
7795                 /* File Type */
7796                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7797                 offset += 2;
7798
7799                 /* device state */
7800                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
7801
7802                 /* is directory */
7803                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7804                 offset += 1;
7805                 break;
7806         case NT_TRANS_IOCTL:
7807                 break;
7808         case NT_TRANS_SSD:
7809                 break;
7810         case NT_TRANS_NOTIFY:
7811                 while(len){
7812                         old_offset = offset;
7813
7814                         /* next entry offset */
7815                         neo = tvb_get_letohl(tvb, offset);
7816                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
7817                         COUNT_BYTES(4);
7818                         len -= 4;
7819                         /* broken implementations */
7820                         if(len<0)break;
7821         
7822                         /* action */
7823                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
7824                         COUNT_BYTES(4);
7825                         len -= 4;
7826                         /* broken implementations */
7827                         if(len<0)break;
7828
7829                         /* file name len */
7830                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
7831                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7832                         COUNT_BYTES(4);
7833                         len -= 4;
7834                         /* broken implementations */
7835                         if(len<0)break;
7836
7837                         /* file name */
7838                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7839                         if (fn == NULL)
7840                                 break;
7841                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7842                                 fn);
7843                         COUNT_BYTES(fn_len);
7844                         len -= fn_len;
7845                         /* broken implementations */
7846                         if(len<0)break;
7847
7848                         if (neo == 0)
7849                                 break;  /* no more structures */
7850
7851                         /* skip to next structure */
7852                         padcnt = (old_offset + neo) - offset;
7853                         if (padcnt < 0) {
7854                                 /*
7855                                  * XXX - this is bogus; flag it?
7856                                  */
7857                                 padcnt = 0;
7858                         }
7859                         if (padcnt != 0) {
7860                                 COUNT_BYTES(padcnt);
7861                                 len -= padcnt;
7862                                 /* broken implementations */
7863                                 if(len<0)break;
7864                         }
7865                 }
7866                 break;
7867         case NT_TRANS_RENAME:
7868                 /* XXX not documented */
7869                 break;
7870         case NT_TRANS_QSD:
7871                 /*
7872                  * This appears to be the size of the security
7873                  * descriptor; the calling sequence of
7874                  * "ZwQuerySecurityObject()" suggests that it would
7875                  * be.  The actual security descriptor wouldn't
7876                  * follow if the max data count in the request
7877                  * was smaller; this lets the client know how
7878                  * big a buffer it needs to provide.
7879                  */
7880                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
7881                 offset += 4;
7882                 break;
7883         case NT_TRANS_GET_USER_QUOTA:
7884                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
7885                         tvb_get_letohl(tvb, offset));
7886                 offset += 4;
7887                 break;
7888         case NT_TRANS_SET_USER_QUOTA:
7889                 /* not decoded yet */
7890                 break;
7891         }
7892
7893         return offset;
7894 }
7895  
7896 static int
7897 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7898 {
7899         proto_item *item = NULL;
7900         proto_tree *tree = NULL;
7901         smb_info_t *si;
7902         smb_nt_transact_info_t *nti;
7903
7904         si = (smb_info_t *)pinfo->private_data;
7905         if (si->sip != NULL)
7906                 nti = si->sip->extra_info;
7907         else
7908                 nti = NULL;
7909
7910         if(parent_tree){
7911                 if(nti != NULL){
7912                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7913                                 "%s Setup",
7914                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7915                 } else {
7916                         /*
7917                          * We never saw the request to which this is a
7918                          * response.
7919                          */
7920                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7921                                 "Unknown NT Transaction Setup (matching request not seen)");
7922                 }
7923                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7924         }
7925
7926         if (nti == NULL) {
7927                 offset += len;
7928                 return offset;
7929         }
7930         switch(nti->subcmd){
7931         case NT_TRANS_CREATE:
7932                 break;
7933         case NT_TRANS_IOCTL:
7934                 break;
7935         case NT_TRANS_SSD:
7936                 break;
7937         case NT_TRANS_NOTIFY:
7938                 break;
7939         case NT_TRANS_RENAME:
7940                 /* XXX not documented */
7941                 break;
7942         case NT_TRANS_QSD:
7943                 break;
7944         case NT_TRANS_GET_USER_QUOTA:
7945                 /* not decoded yet */
7946                 break;
7947         case NT_TRANS_SET_USER_QUOTA:
7948                 /* not decoded yet */
7949                 break;
7950         }
7951
7952         return offset;
7953 }
7954
7955 static int
7956 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7957 {
7958         guint8 wc, sc;
7959         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
7960         guint32 td=0, tp=0;
7961         smb_info_t *si;
7962         smb_nt_transact_info_t *nti;
7963         static nt_trans_data ntd;
7964         guint16 bc;
7965         int padcnt;
7966         fragment_data *r_fd = NULL;
7967         tvbuff_t *pd_tvb=NULL;
7968         gboolean save_fragmented;
7969
7970         si = (smb_info_t *)pinfo->private_data;
7971         if (si->sip != NULL)
7972                 nti = si->sip->extra_info;
7973         else
7974                 nti = NULL;
7975
7976         /* primary request */
7977         if(nti != NULL){
7978                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
7979                 if(check_col(pinfo->cinfo, COL_INFO)){
7980                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7981                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
7982                 }
7983         } else {
7984                 proto_tree_add_text(tree, tvb, offset, 0,
7985                         "Function: <unknown function - could not find matching request>");
7986                 if(check_col(pinfo->cinfo, COL_INFO)){
7987                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
7988                 }
7989         }
7990
7991         WORD_COUNT;
7992
7993         /* 3 reserved bytes */
7994         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7995         offset += 3;
7996
7997         /* total param count */
7998         tp = tvb_get_letohl(tvb, offset);
7999         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8000         offset += 4;
8001         
8002         /* total data count */
8003         td = tvb_get_letohl(tvb, offset);
8004         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8005         offset += 4;
8006
8007         /* param count */
8008         pc = tvb_get_letohl(tvb, offset);
8009         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8010         offset += 4;
8011         
8012         /* param offset */
8013         po = tvb_get_letohl(tvb, offset);
8014         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8015         offset += 4;
8016
8017         /* param displacement */
8018         pd = tvb_get_letohl(tvb, offset);
8019         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8020         offset += 4;
8021
8022         /* data count */
8023         dc = tvb_get_letohl(tvb, offset);
8024         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8025         offset += 4;
8026
8027         /* data offset */
8028         od = tvb_get_letohl(tvb, offset);
8029         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8030         offset += 4;
8031
8032         /* data displacement */
8033         dd = tvb_get_letohl(tvb, offset);
8034         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8035         offset += 4;
8036
8037         /* setup count */
8038         sc = tvb_get_guint8(tvb, offset);
8039         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8040         offset += 1;
8041
8042         /* setup data */        
8043         if(sc){
8044                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8045                 offset += sc*2;
8046         }
8047
8048         BYTE_COUNT;
8049
8050         /* reassembly of SMB NT Transaction data payload.
8051            In this section we do reassembly of both the data and parameters
8052            blocks of the SMB transaction command.
8053         */
8054         save_fragmented = pinfo->fragmented;
8055         /* do we need reassembly? */
8056         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8057                 /* oh yeah, either data or parameter section needs 
8058                    reassembly...
8059                 */
8060                 pinfo->fragmented = TRUE;
8061                 if(smb_trans_reassembly){
8062                         /* ...and we were told to do reassembly */
8063                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8064                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8065                                                              po, pc, pd, td+tp);
8066                                 
8067                         }
8068                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8069                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8070                                                              od, dc, dd+tp, td+tp);
8071                         }
8072                 }
8073         }
8074
8075         /* if we got a reassembled fd structure from the reassembly routine we
8076            must create pd_tvb from it 
8077         */
8078         if(r_fd){
8079                 proto_tree *tr;
8080                 proto_item *it;
8081                 fragment_data *fd;
8082                 
8083                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8084                                              r_fd->datalen);
8085                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8086                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
8087                 pinfo->fragmented = FALSE;
8088
8089                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
8090                 tr = proto_item_add_subtree(it, ett_smb_segments);
8091                 for(fd=r_fd->next;fd;fd=fd->next){
8092                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
8093                                             "Frame:%u Data:%u-%u",
8094                                             fd->frame, fd->offset,
8095                                             fd->offset+fd->len-1);
8096                 }
8097         }
8098
8099
8100         if(pd_tvb){
8101           /* we have reassembled data, grab param and data from there */
8102           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8103                                           &ntd, tvb_length(pd_tvb));
8104           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8105         } else {
8106           /* we do not have reassembled data, just use what we have in the 
8107              packet as well as we can */
8108           /* parameters */
8109           if(po>(guint32)offset){
8110             /* We have some initial padding bytes.
8111              */
8112             padcnt = po-offset;
8113             if (padcnt > bc)
8114               padcnt = bc;
8115             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8116             COUNT_BYTES(padcnt);
8117           }
8118           if(pc){
8119             CHECK_BYTE_COUNT(pc);
8120             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8121             COUNT_BYTES(pc);
8122           }
8123           
8124           /* data */
8125           if(od>(guint32)offset){
8126             /* We have some initial padding bytes.
8127              */
8128             padcnt = od-offset;
8129             if (padcnt > bc)
8130               padcnt = bc;
8131             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8132             COUNT_BYTES(padcnt);
8133           }
8134           if(dc){
8135             CHECK_BYTE_COUNT(dc);
8136             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8137             COUNT_BYTES(dc);
8138           }
8139         }
8140         pinfo->fragmented = save_fragmented;
8141
8142         END_OF_SMB
8143
8144         return offset;
8145 }
8146
8147 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8148    NT Transaction command  ends here
8149    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8150
8151 static const value_string print_mode_vals[] = {
8152         {0,     "Text Mode"},
8153         {1,     "Graphics Mode"},
8154         {0, NULL}
8155 };
8156  
8157 static int
8158 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8159 {
8160         int fn_len;
8161         const char *fn;
8162         guint8 wc;
8163         guint16 bc;
8164
8165         WORD_COUNT;
8166
8167         /* setup len */
8168         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8169         offset += 2;
8170
8171         /* print mode */
8172         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8173         offset += 2;
8174
8175         BYTE_COUNT;
8176
8177         /* buffer format */
8178         CHECK_BYTE_COUNT(1);
8179         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8180         COUNT_BYTES(1);
8181
8182         /* print identifier */
8183         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
8184         if (fn == NULL)
8185                 goto endofcommand;
8186         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8187                 fn);
8188         COUNT_BYTES(fn_len);
8189
8190         END_OF_SMB
8191
8192         return offset;
8193 }
8194
8195
8196 static int
8197 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8198 {
8199         int cnt;
8200         guint8 wc;
8201         guint16 bc, fid;
8202
8203         WORD_COUNT;
8204
8205         /* fid */
8206         fid = tvb_get_letohs(tvb, offset);
8207         add_fid(tvb, pinfo, tree, offset, 2, fid);
8208         offset += 2;
8209
8210         BYTE_COUNT;
8211
8212         /* buffer format */
8213         CHECK_BYTE_COUNT(1);
8214         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8215         COUNT_BYTES(1);
8216
8217         /* data len */
8218         CHECK_BYTE_COUNT(2);
8219         cnt = tvb_get_letohs(tvb, offset);
8220         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8221         COUNT_BYTES(2);
8222
8223         /* file data */
8224         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
8225
8226         END_OF_SMB
8227
8228         return offset;
8229 }
8230
8231
8232 static const value_string print_status_vals[] = {
8233         {1,     "Held or Stopped"},
8234         {2,     "Printing"},
8235         {3,     "Awaiting print"},
8236         {4,     "In intercept"},
8237         {5,     "File had error"},
8238         {6,     "Printer error"},
8239         {0, NULL}
8240 };
8241  
8242 static int
8243 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8244 {
8245         guint8 wc;
8246         guint16 bc;
8247
8248         WORD_COUNT;
8249
8250         /* max count */
8251         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8252         offset += 2;
8253
8254         /* start index */
8255         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8256         offset += 2;
8257
8258         BYTE_COUNT;
8259
8260         END_OF_SMB
8261
8262         return offset;
8263 }
8264
8265 static int
8266 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8267     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8268 {
8269         proto_item *item = NULL;
8270         proto_tree *tree = NULL;
8271         int fn_len;
8272         const char *fn;
8273
8274         if(parent_tree){
8275                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8276                         "Queue entry");
8277                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8278         }
8279
8280         /* queued time */
8281         CHECK_BYTE_COUNT_SUBR(4);
8282         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8283                 hf_smb_print_queue_date,
8284                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8285         *bcp -= 4;
8286
8287         /* status */
8288         CHECK_BYTE_COUNT_SUBR(1);
8289         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8290         COUNT_BYTES_SUBR(1);
8291
8292         /* spool file number */
8293         CHECK_BYTE_COUNT_SUBR(2);
8294         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8295         COUNT_BYTES_SUBR(2);
8296
8297         /* spool file size */
8298         CHECK_BYTE_COUNT_SUBR(4);
8299         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8300         COUNT_BYTES_SUBR(4);
8301
8302         /* reserved byte */
8303         CHECK_BYTE_COUNT_SUBR(1);
8304         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8305         COUNT_BYTES_SUBR(1);
8306
8307         /* file name */
8308         fn_len = 16;
8309         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
8310         CHECK_STRING_SUBR(fn);
8311         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8312                 fn);
8313         COUNT_BYTES_SUBR(fn_len);
8314
8315         *trunc = FALSE;
8316         return offset;
8317 }
8318
8319 static int
8320 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8321 {
8322         guint16 cnt=0, len;
8323         guint8 wc;
8324         guint16 bc;
8325         gboolean trunc;
8326
8327         WORD_COUNT;
8328
8329         /* count */
8330         cnt = tvb_get_letohs(tvb, offset);
8331         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8332         offset += 2;
8333
8334         /* restart index */
8335         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8336         offset += 2;
8337
8338         BYTE_COUNT;
8339
8340         /* buffer format */
8341         CHECK_BYTE_COUNT(1);
8342         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8343         COUNT_BYTES(1);
8344
8345         /* data len */
8346         CHECK_BYTE_COUNT(2);
8347         len = tvb_get_letohs(tvb, offset);
8348         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8349         COUNT_BYTES(2);
8350
8351         /* queue elements */
8352         while(cnt--){
8353                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8354                     &bc, &trunc);
8355                 if (trunc)
8356                         goto endofcommand;
8357         }
8358
8359         END_OF_SMB
8360
8361         return offset;
8362 }
8363
8364
8365 static int
8366 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8367 {
8368         guint8  wc, cmd=0xff;
8369         guint16 andxoffset=0;
8370         guint16 bc;
8371         int fn_len;
8372         const char *fn;
8373
8374         WORD_COUNT;
8375
8376         /* next smb command */
8377         cmd = tvb_get_guint8(tvb, offset);
8378         if(cmd!=0xff){
8379                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8380         } else {
8381                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8382         }
8383         offset += 1;
8384
8385         /* reserved byte */
8386         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8387         offset += 1;
8388
8389         /* andxoffset */
8390         andxoffset = tvb_get_letohs(tvb, offset);
8391         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8392         offset += 2;
8393
8394         /* reserved byte */
8395         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8396         offset += 1;
8397
8398         /* file name len */
8399         fn_len = tvb_get_letohs(tvb, offset);
8400         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8401         offset += 2;
8402
8403         /* Create flags */
8404         offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
8405
8406         /* root directory fid */
8407         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8408         offset += 4;
8409
8410         /* nt access mask */
8411         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
8412
8413         /* allocation size */
8414         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8415         offset += 8;
8416
8417         /* Extended File Attributes */
8418         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8419
8420         /* share access */
8421         offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
8422
8423         /* create disposition */
8424         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8425         offset += 4;
8426
8427         /* create options */
8428         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
8429
8430         /* impersonation level */
8431         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8432         offset += 4;
8433
8434         /* security flags */
8435         offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
8436
8437         BYTE_COUNT;
8438
8439         /* file name */
8440         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8441         if (fn == NULL)
8442                 goto endofcommand;
8443         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8444                 fn);
8445         COUNT_BYTES(fn_len);
8446
8447         if (check_col(pinfo->cinfo, COL_INFO)) {
8448                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8449         }
8450
8451         END_OF_SMB
8452
8453         /* call AndXCommand (if there are any) */
8454         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8455
8456         return offset;
8457 }
8458  
8459
8460 static int
8461 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8462 {
8463         guint8  wc, cmd=0xff;
8464         guint16 andxoffset=0;
8465         guint16 bc;
8466         guint16 fid;
8467
8468         WORD_COUNT;
8469
8470         /* next smb command */
8471         cmd = tvb_get_guint8(tvb, offset);
8472         if(cmd!=0xff){
8473                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8474         } else {
8475                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8476         }
8477         offset += 1;
8478
8479         /* reserved byte */
8480         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8481         offset += 1;
8482
8483         /* andxoffset */
8484         andxoffset = tvb_get_letohs(tvb, offset);
8485         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8486         offset += 2;
8487
8488         /* oplock level */
8489         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8490         offset += 1;
8491
8492         /* fid */
8493         fid = tvb_get_letohs(tvb, offset);
8494         add_fid(tvb, pinfo, tree, offset, 2, fid);
8495         offset += 2;
8496
8497         /* create action */
8498         /*XXX is this really the same as create disposition in the request? it looks so*/
8499         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8500         offset += 4;
8501
8502         /* create time */
8503         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8504                 hf_smb_create_time);
8505         
8506         /* access time */
8507         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8508                 hf_smb_access_time);
8509         
8510         /* last write time */
8511         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8512                 hf_smb_last_write_time);
8513
8514         /* last change time */
8515         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8516                 hf_smb_change_time);
8517         
8518         /* Extended File Attributes */
8519         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8520
8521         /* allocation size */
8522         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8523         offset += 8;
8524
8525         /* end of file */
8526         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8527         offset += 8;
8528
8529         /* File Type */
8530         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8531         offset += 2;
8532
8533         /* IPC State */
8534         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
8535
8536         /* is directory */
8537         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8538         offset += 1;
8539
8540         BYTE_COUNT;
8541
8542         END_OF_SMB
8543
8544         /* call AndXCommand (if there are any) */
8545         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8546
8547         return offset;
8548 }
8549
8550
8551 static int
8552 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8553 {
8554         guint8 wc;
8555         guint16 bc;
8556
8557         WORD_COUNT;
8558  
8559         BYTE_COUNT;
8560
8561         END_OF_SMB
8562
8563         return offset;
8564 }
8565
8566 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8567    BEGIN Transaction/Transaction2 Primary and secondary requests
8568    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8569
8570
8571 static const value_string trans2_cmd_vals[] = {
8572         { 0x00,         "OPEN2" },
8573         { 0x01,         "FIND_FIRST2" },
8574         { 0x02,         "FIND_NEXT2" },
8575         { 0x03,         "QUERY_FS_INFORMATION" },
8576         { 0x04,         "SET_FS_QUOTA" },
8577         { 0x05,         "QUERY_PATH_INFORMATION" },
8578         { 0x06,         "SET_PATH_INFORMATION" },
8579         { 0x07,         "QUERY_FILE_INFORMATION" },
8580         { 0x08,         "SET_FILE_INFORMATION" },
8581         { 0x09,         "FSCTL" },
8582         { 0x0A,         "IOCTL2" },
8583         { 0x0B,         "FIND_NOTIFY_FIRST" },
8584         { 0x0C,         "FIND_NOTIFY_NEXT" },
8585         { 0x0D,         "CREATE_DIRECTORY" },
8586         { 0x0E,         "SESSION_SETUP" },
8587         { 0x10,         "GET_DFS_REFERRAL" },
8588         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
8589         { 0,    NULL }
8590 };
8591
8592 static const true_false_string tfs_tf_dtid = {
8593         "Also DISCONNECT TID",
8594         "Do NOT disconnect TID"
8595 };
8596 static const true_false_string tfs_tf_owt = {
8597         "One Way Transaction (NO RESPONSE)",
8598         "Two way transaction"
8599 };
8600
8601 static const true_false_string tfs_ff2_backup = {
8602         "Find WITH backup intent",
8603         "No backup intent"
8604 };
8605 static const true_false_string tfs_ff2_continue = {
8606         "CONTINUE search from previous position",
8607         "New search, do NOT continue from previous position"
8608 };
8609 static const true_false_string tfs_ff2_resume = {
8610         "Return RESUME keys",
8611         "Do NOT return resume keys"
8612 };
8613 static const true_false_string tfs_ff2_close_eos = {
8614         "CLOSE search if END OF SEARCH is reached",
8615         "Do NOT close search if end of search reached"
8616 };
8617 static const true_false_string tfs_ff2_close = {
8618         "CLOSE search after this request",
8619         "Do NOT close search after this request"
8620 };
8621
8622 /* used by
8623    TRANS2_FIND_FIRST2
8624 */
8625 static const value_string ff2_il_vals[] = {
8626         { 1,            "Info Standard  (4.3.4.1)"},
8627         { 2,            "Info Query EA Size  (4.3.4.2)"},
8628         { 3,            "Info Query EAs From List  (4.3.4.2)"},
8629         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
8630         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
8631         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
8632         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
8633         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
8634         {0, NULL}
8635 };
8636
8637 /* values used by :
8638         TRANS2_QUERY_PATH_INFORMATION
8639         TRANS2_SET_PATH_INFORMATION
8640 */
8641 static const value_string qpi_loi_vals[] = {
8642         { 1,            "Info Standard  (4.2.14.1)"},
8643         { 2,            "Info Query EA Size  (4.2.14.1)"},
8644         { 3,            "Info Query EAs From List  (4.2.14.2)"},
8645         { 4,            "Info Query All EAs  (4.2.14.2)"},
8646         { 6,            "Info Is Name Valid  (4.2.14.3)"},
8647         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
8648         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
8649         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
8650         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
8651         { 0x0107,       "Query File All Info  (4.2.14.8)"},
8652         { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
8653         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
8654         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
8655         { 0x0200,       "Set File Unix Basic"},
8656         { 0x0201,       "Set File Unix Link"},
8657         { 0x0202,       "Set File Unix HardLink"},
8658         {0, NULL}
8659 };
8660
8661 static const value_string qfsi_vals[] = {
8662         { 1,            "Info Allocation"},
8663         { 2,            "Info Volume"},
8664         { 0x0102,       "Query FS Volume Info"},
8665         { 0x0103,       "Query FS Size Info"},
8666         { 0x0104,       "Query FS Device Info"},
8667         { 0x0105,       "Query FS Attribute Info"},
8668         { 1006,         "Query FS Quota Info"},
8669         {0, NULL}
8670 };
8671
8672 static const value_string nt_rename_vals[] = {
8673         { 0x0103,       "Create Hard Link"},
8674         {0, NULL}
8675 };
8676
8677
8678 static const value_string delete_pending_vals[] = {
8679         {0,     "Normal, no pending delete"},
8680         {1,     "This object has DELETE PENDING"},
8681         {0, NULL}
8682 };
8683
8684 static const value_string alignment_vals[] = {
8685         {0,     "Byte alignment"},
8686         {1,     "Word (16bit) alignment"},
8687         {3,     "Long (32bit) alignment"},
8688         {7,     "8 byte boundary alignment"},
8689         {0x0f,  "16 byte boundary alignment"},
8690         {0x1f,  "32 byte boundary alignment"},
8691         {0x3f,  "64 byte boundary alignment"},
8692         {0x7f,  "128 byte boundary alignment"},
8693         {0xff,  "256 byte boundary alignment"},
8694         {0x1ff, "512 byte boundary alignment"},
8695         {0, NULL}
8696 };
8697
8698
8699 static const true_false_string tfs_get_dfs_server_hold_storage = {
8700         "Referral SERVER HOLDS STORAGE for the file",
8701         "Referral server does NOT hold storage for the file"
8702 };
8703 static const true_false_string tfs_get_dfs_fielding = {
8704         "The server in referral is FIELDING CAPABLE",
8705         "The server in referrals is NOT fielding capable"
8706 };
8707
8708 static const true_false_string tfs_dfs_referral_flags_strip = {
8709         "STRIP off pathconsumed characters before submitting",
8710         "Do NOT strip off any characters"
8711 };
8712
8713 static const value_string dfs_referral_server_type_vals[] = {
8714         {0,     "Don't know"},
8715         {1,     "SMB Server"},
8716         {2,     "Netware Server"},
8717         {3,     "Domain Server"},
8718         {0, NULL}
8719 };
8720
8721
8722 static const true_false_string tfs_device_char_removable = {
8723         "This is a REMOVABLE device",
8724         "This is NOT a removable device"
8725 };
8726 static const true_false_string tfs_device_char_read_only = {
8727         "This is a READ-ONLY device",
8728         "This is NOT a read-only device"
8729 };
8730 static const true_false_string tfs_device_char_floppy = {
8731         "This is a FLOPPY DISK device",
8732         "This is NOT a floppy disk device"
8733 };
8734 static const true_false_string tfs_device_char_write_once = {
8735         "This is a WRITE-ONCE device",
8736         "This is NOT a write-once device"
8737 };
8738 static const true_false_string tfs_device_char_remote = {
8739         "This is a REMOTE device",
8740         "This is NOT a remote device"
8741 };
8742 static const true_false_string tfs_device_char_mounted = {
8743         "This device is MOUNTED",
8744         "This device is NOT mounted"
8745 };
8746 static const true_false_string tfs_device_char_virtual = {
8747         "This is a VIRTUAL device",
8748         "This is NOT a virtual device"
8749 };
8750
8751
8752 static const true_false_string tfs_fs_attr_css = {
8753         "This FS supports CASE SENSITIVE SEARCHes",
8754         "This FS does NOT support case sensitive searches"
8755 };
8756 static const true_false_string tfs_fs_attr_cpn = {
8757         "This FS supports CASE PRESERVED NAMES",
8758         "This FS does NOT support case preserved names"
8759 };
8760 static const true_false_string tfs_fs_attr_pacls = {
8761         "This FS supports PERSISTENT ACLs",
8762         "This FS does NOT support persistent acls"
8763 };
8764 static const true_false_string tfs_fs_attr_fc = {
8765         "This FS supports COMPRESSED FILES",
8766         "This FS does NOT support compressed files"
8767 };
8768 static const true_false_string tfs_fs_attr_vq = {
8769         "This FS supports VOLUME QUOTAS",
8770         "This FS does NOT support volume quotas"
8771 };
8772 static const true_false_string tfs_fs_attr_dim = {
8773         "This FS is on a MOUNTED DEVICE",
8774         "This FS is NOT on a mounted device"
8775 };
8776 static const true_false_string tfs_fs_attr_vic = {
8777         "This FS is on a COMPRESSED VOLUME",
8778         "This FS is NOT on a compressed volume"
8779 };
8780
8781
8782
8783 static int
8784 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8785 {
8786         guint16 mask;
8787         proto_item *item = NULL;
8788         proto_tree *tree = NULL;
8789
8790         mask = tvb_get_letohs(tvb, offset);
8791
8792         if(parent_tree){
8793                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8794                         "Flags: 0x%04x", mask);
8795                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
8796         }
8797
8798         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
8799                 tvb, offset, 2, mask);
8800         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
8801                 tvb, offset, 2, mask);
8802         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
8803                 tvb, offset, 2, mask);
8804         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
8805                 tvb, offset, 2, mask);
8806         proto_tree_add_boolean(tree, hf_smb_ff2_close,
8807                 tvb, offset, 2, mask);
8808
8809         offset += 2;
8810
8811         return offset;
8812 }
8813
8814 static int
8815 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
8816     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
8817 {
8818         proto_item *item = NULL;
8819         proto_tree *tree = NULL;
8820         smb_info_t *si;
8821         smb_transact2_info_t *t2i;
8822         int fn_len;
8823         const char *fn;
8824         int old_offset = offset;
8825
8826         si = (smb_info_t *)pinfo->private_data;
8827         if (si->sip != NULL)
8828                 t2i = si->sip->extra_info;
8829         else
8830                 t2i = NULL;
8831
8832         if(parent_tree){
8833                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8834                                 "%s Parameters",
8835                                 val_to_str(subcmd, trans2_cmd_vals, 
8836                                            "Unknown (0x%02x)"));
8837                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
8838         }
8839
8840         switch(subcmd){
8841         case 0x00:      /*TRANS2_OPEN2*/
8842                 /* open flags */
8843                 CHECK_BYTE_COUNT_TRANS(2);
8844                 offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
8845                 bc -= 2;
8846
8847                 /* desired access */
8848                 CHECK_BYTE_COUNT_TRANS(2);
8849                 offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
8850                 bc -= 2;
8851
8852                 /* 2 reserved bytes */
8853                 CHECK_BYTE_COUNT_TRANS(2);
8854                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8855                 COUNT_BYTES_TRANS(2);
8856
8857                 /* File Attributes */
8858                 CHECK_BYTE_COUNT_TRANS(2);
8859                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8860                 bc -= 2;
8861
8862                 /* create time */
8863                 CHECK_BYTE_COUNT_TRANS(4);
8864                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8865                         hf_smb_create_time,
8866                         hf_smb_create_dos_date, hf_smb_create_dos_time,
8867                         TRUE);
8868                 bc -= 4;
8869
8870                 /* open function */
8871                 CHECK_BYTE_COUNT_TRANS(2);
8872                 offset = dissect_open_function(tvb, pinfo, tree, offset);
8873                 bc -= 2;
8874
8875                 /* allocation size */
8876                 CHECK_BYTE_COUNT_TRANS(4);
8877                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
8878                 COUNT_BYTES_TRANS(4);
8879
8880                 /* 10 reserved bytes */
8881                 CHECK_BYTE_COUNT_TRANS(10);
8882                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
8883                 COUNT_BYTES_TRANS(10);
8884
8885                 /* file name */
8886                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8887                 CHECK_STRING_TRANS(fn);
8888                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8889                         fn);
8890                 COUNT_BYTES_TRANS(fn_len);
8891
8892                 if (check_col(pinfo->cinfo, COL_INFO)) {
8893                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8894                         fn);
8895                 }
8896
8897                 /* XXX dont know how to decode FEAList */
8898                 break;
8899         case 0x01:      /*TRANS2_FIND_FIRST2*/
8900                 /* Search Attributes */
8901                 CHECK_BYTE_COUNT_TRANS(2);
8902                 offset = dissect_search_attributes(tvb, pinfo, tree, offset);
8903                 bc -= 2;
8904
8905                 /* search count */
8906                 CHECK_BYTE_COUNT_TRANS(2);
8907                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8908                 COUNT_BYTES_TRANS(2);
8909
8910                 /* Find First2 flags */
8911                 CHECK_BYTE_COUNT_TRANS(2);
8912                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8913                 bc -= 2;
8914
8915                 /* Find First2 information level */
8916                 CHECK_BYTE_COUNT_TRANS(2);
8917                 si->info_level = tvb_get_letohs(tvb, offset);
8918                 if (!pinfo->fd->flags.visited)
8919                         t2i->info_level = si->info_level;
8920                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8921                 COUNT_BYTES_TRANS(2);
8922
8923                 /* storage type */
8924                 CHECK_BYTE_COUNT_TRANS(4);
8925                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
8926                 COUNT_BYTES_TRANS(4);
8927
8928                 /* search pattern */
8929                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8930                 CHECK_STRING_TRANS(fn);
8931                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
8932                         fn);
8933                 COUNT_BYTES_TRANS(fn_len);
8934
8935                 if (check_col(pinfo->cinfo, COL_INFO)) {
8936                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
8937                         fn);
8938                 }
8939
8940                 /* XXX dont know how to decode FEAList */
8941
8942                 break;
8943         case 0x02:      /*TRANS2_FIND_NEXT2*/
8944                 /* sid */
8945                 CHECK_BYTE_COUNT_TRANS(2);
8946                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
8947                 COUNT_BYTES_TRANS(2);
8948
8949                 /* search count */
8950                 CHECK_BYTE_COUNT_TRANS(2);
8951                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8952                 COUNT_BYTES_TRANS(2);
8953
8954                 /* Find First2 information level */
8955                 CHECK_BYTE_COUNT_TRANS(2);
8956                 si->info_level = tvb_get_letohs(tvb, offset);
8957                 if (!pinfo->fd->flags.visited)
8958                         t2i->info_level = si->info_level;
8959                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8960                 COUNT_BYTES_TRANS(2);
8961
8962                 /* resume key */
8963                 CHECK_BYTE_COUNT_TRANS(4);
8964                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
8965                 COUNT_BYTES_TRANS(4);
8966
8967                 /* Find First2 flags */
8968                 CHECK_BYTE_COUNT_TRANS(2);
8969                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8970                 bc -= 2;
8971
8972                 /* file name */
8973                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8974                 CHECK_STRING_TRANS(fn);
8975                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8976                         fn);
8977                 COUNT_BYTES_TRANS(fn_len);
8978
8979                 if (check_col(pinfo->cinfo, COL_INFO)) {
8980                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
8981                         fn);
8982                 }
8983
8984                 break;
8985         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
8986                 /* level of interest */
8987                 CHECK_BYTE_COUNT_TRANS(2);
8988                 si->info_level = tvb_get_letohs(tvb, offset);
8989                 if (!pinfo->fd->flags.visited)
8990                         t2i->info_level = si->info_level;
8991                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
8992                 COUNT_BYTES_TRANS(2);
8993
8994                 break;
8995         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
8996                 /* level of interest */
8997                 CHECK_BYTE_COUNT_TRANS(2);
8998                 si->info_level = tvb_get_letohs(tvb, offset);
8999                 if (!pinfo->fd->flags.visited)
9000                         t2i->info_level = si->info_level;
9001                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9002                 COUNT_BYTES_TRANS(2);
9003                 
9004                 /* 4 reserved bytes */
9005                 CHECK_BYTE_COUNT_TRANS(4);
9006                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9007                 COUNT_BYTES_TRANS(4);
9008
9009                 /* file name */
9010                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9011                 CHECK_STRING_TRANS(fn);
9012                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9013                         fn);
9014                 COUNT_BYTES_TRANS(fn_len);
9015
9016                 if (check_col(pinfo->cinfo, COL_INFO)) {
9017                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9018                         fn);
9019                 }
9020
9021                 break;
9022         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9023                 /* level of interest */
9024                 CHECK_BYTE_COUNT_TRANS(2);
9025                 si->info_level = tvb_get_letohs(tvb, offset);
9026                 if (!pinfo->fd->flags.visited)
9027                         t2i->info_level = si->info_level;
9028                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9029                 COUNT_BYTES_TRANS(2);
9030                 
9031                 /* 4 reserved bytes */
9032                 CHECK_BYTE_COUNT_TRANS(4);
9033                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9034                 COUNT_BYTES_TRANS(4);
9035
9036                 /* file name */
9037                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9038                 CHECK_STRING_TRANS(fn);
9039                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9040                         fn);
9041                 COUNT_BYTES_TRANS(fn_len);
9042
9043                 if (check_col(pinfo->cinfo, COL_INFO)) {
9044                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9045                         fn);
9046                 }
9047
9048                 break;
9049         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9050                 guint16 fid;
9051
9052                 /* fid */
9053                 CHECK_BYTE_COUNT_TRANS(2);
9054                 fid = tvb_get_letohs(tvb, offset);
9055                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9056                 COUNT_BYTES_TRANS(2);
9057
9058                 /* level of interest */
9059                 CHECK_BYTE_COUNT_TRANS(2);
9060                 si->info_level = tvb_get_letohs(tvb, offset);
9061                 if (!pinfo->fd->flags.visited)
9062                         t2i->info_level = si->info_level;
9063                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9064                 COUNT_BYTES_TRANS(2);
9065                 
9066                 break;
9067         }
9068         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9069                 guint16 fid;
9070
9071                 /* fid */
9072                 CHECK_BYTE_COUNT_TRANS(2);
9073                 fid = tvb_get_letohs(tvb, offset);
9074                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9075                 COUNT_BYTES_TRANS(2);
9076
9077                 /* level of interest */
9078                 CHECK_BYTE_COUNT_TRANS(2);
9079                 si->info_level = tvb_get_letohs(tvb, offset);
9080                 if (!pinfo->fd->flags.visited)
9081                         t2i->info_level = si->info_level;
9082                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9083                 COUNT_BYTES_TRANS(2);
9084                 
9085                 /* 2 reserved bytes */
9086                 CHECK_BYTE_COUNT_TRANS(2);
9087                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9088                 COUNT_BYTES_TRANS(2);
9089
9090                 break;
9091         }
9092         case 0x09:      /*TRANS2_FSCTL*/
9093         case 0x0a:      /*TRANS2_IOCTL2*/
9094                 /* these calls have no parameter block in the request */
9095                 break;
9096         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
9097         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
9098                 /* XXX unknown structure*/
9099                 break;
9100         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9101                 /* 4 reserved bytes */
9102                 CHECK_BYTE_COUNT_TRANS(4);
9103                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9104                 COUNT_BYTES_TRANS(4);
9105
9106                 /* dir name */
9107                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
9108                         FALSE, FALSE, &bc);
9109                 CHECK_STRING_TRANS(fn);
9110                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9111                         fn);
9112                 COUNT_BYTES_TRANS(fn_len);
9113
9114                 if (check_col(pinfo->cinfo, COL_INFO)) {
9115                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9116                         fn);
9117                 }
9118
9119                 /* XXX optional FEAList, unknown what FEAList looks like*/
9120                 break;
9121         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9122                 /* XXX unknown structure*/
9123                 break;
9124         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9125                 /* referral level */
9126                 CHECK_BYTE_COUNT_TRANS(2);
9127                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9128                 COUNT_BYTES_TRANS(2);
9129                 
9130                 /* file name */
9131                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9132                 CHECK_STRING_TRANS(fn);
9133                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9134                         fn);
9135                 COUNT_BYTES_TRANS(fn_len);
9136
9137                 if (check_col(pinfo->cinfo, COL_INFO)) {
9138                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9139                         fn);
9140                 }
9141
9142                 break;
9143         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9144                 /* file name */
9145                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9146                 CHECK_STRING_TRANS(fn);
9147                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9148                         fn);
9149                 COUNT_BYTES_TRANS(fn_len);
9150
9151                 if (check_col(pinfo->cinfo, COL_INFO)) {
9152                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9153                         fn);
9154                 }
9155
9156                 break;
9157         }
9158
9159         /* ooops there were data we didnt know how to process */
9160         if((offset-old_offset) < bc){
9161                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9162                     bc - (offset-old_offset), TRUE);
9163                 offset += bc - (offset-old_offset);
9164         }
9165
9166         return offset;
9167 }
9168
9169 /*
9170  * XXX - just use "dissect_connect_flags()" here?
9171  */
9172 static guint16
9173 dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9174 {
9175         guint16 mask;
9176         proto_item *item = NULL;
9177         proto_tree *tree = NULL;
9178
9179         mask = tvb_get_letohs(tvb, offset);
9180
9181         if(parent_tree){
9182                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9183                         "Flags: 0x%04x", mask);
9184                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9185         }
9186
9187         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9188                 tvb, offset, 2, mask);
9189         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9190                 tvb, offset, 2, mask);
9191
9192         return mask;
9193 }
9194  
9195
9196 static int
9197 dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9198 {
9199         guint16 mask;
9200         proto_item *item = NULL;
9201         proto_tree *tree = NULL;
9202
9203         mask = tvb_get_letohs(tvb, offset);
9204
9205         if(parent_tree){
9206                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9207                         "Flags: 0x%04x", mask);
9208                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9209         }
9210
9211         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9212                 tvb, offset, 2, mask);
9213         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9214                 tvb, offset, 2, mask);
9215
9216         offset += 2;
9217         return offset;
9218 }
9219
9220 static int
9221 dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9222 {
9223         guint16 mask;
9224         proto_item *item = NULL;
9225         proto_tree *tree = NULL;
9226
9227         mask = tvb_get_letohs(tvb, offset);
9228
9229         if(parent_tree){
9230                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9231                         "Flags: 0x%04x", mask);
9232                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9233         }
9234
9235         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9236                 tvb, offset, 2, mask);
9237
9238         offset += 2;
9239
9240         return offset;
9241 }
9242
9243
9244 /* dfs inconsistency data  (4.4.2)
9245 */
9246 static int
9247 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9248     proto_tree *tree, int offset, guint16 *bcp)
9249 {
9250         int fn_len;
9251         const char *fn;
9252
9253         /*XXX shouldn this data hold version and size? unclear from doc*/
9254         /* referral version */
9255         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9256         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9257         COUNT_BYTES_TRANS_SUBR(2);
9258
9259         /* referral size */
9260         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9261         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9262         COUNT_BYTES_TRANS_SUBR(2);
9263
9264         /* referral server type */
9265         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9266         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9267         COUNT_BYTES_TRANS_SUBR(2);
9268
9269         /* referral flags */
9270         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9271         offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
9272         *bcp -= 2;
9273
9274         /* node name */
9275         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9276         CHECK_STRING_TRANS_SUBR(fn);
9277         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9278                 fn);
9279         COUNT_BYTES_TRANS_SUBR(fn_len);
9280
9281         return offset;
9282 }
9283
9284 /* get dfs referral data  (4.4.1)
9285 */
9286 static int
9287 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9288     proto_tree *tree, int offset, guint16 *bcp)
9289 {
9290         guint16 numref;
9291         guint16 refsize;
9292         guint16 pathoffset;
9293         guint16 altpathoffset;
9294         guint16 nodeoffset;
9295         int fn_len;
9296         int stroffset;
9297         int offsetoffset;
9298         guint16 save_bc;
9299         const char *fn;
9300         int unklen;
9301         int ucstring_end;
9302         int ucstring_len;
9303
9304         /* path consumed */
9305         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9306         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9307         COUNT_BYTES_TRANS_SUBR(2);
9308
9309         /* num referrals */
9310         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9311         numref = tvb_get_letohs(tvb, offset);
9312         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9313         COUNT_BYTES_TRANS_SUBR(2);
9314
9315         /* get dfs flags */
9316         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9317         offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
9318         *bcp -= 2;
9319
9320         /* XXX - in at least one capture there appears to be 2 bytes
9321            of stuff after the Dfs flags, perhaps so that the header
9322            in front of the referral list is a multiple of 4 bytes long. */
9323         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9324         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9325         COUNT_BYTES_TRANS_SUBR(2);
9326
9327         /* if there are any referrals */
9328         if(numref){
9329                 proto_item *ref_item = NULL;
9330                 proto_tree *ref_tree = NULL;
9331                 int old_offset=offset;
9332
9333                 if(tree){
9334                         ref_item = proto_tree_add_text(tree,
9335                                 tvb, offset, *bcp, "Referrals");
9336                         ref_tree = proto_item_add_subtree(ref_item,
9337                                 ett_smb_dfs_referrals);
9338                 }
9339                 ucstring_end = -1;
9340
9341                 while(numref--){
9342                         proto_item *ri = NULL;
9343                         proto_tree *rt = NULL;
9344                         int old_offset=offset;
9345                         guint16 version;
9346
9347                         if(tree){
9348                                 ri = proto_tree_add_text(ref_tree,
9349                                         tvb, offset, *bcp, "Referral");
9350                                 rt = proto_item_add_subtree(ri,
9351                                         ett_smb_dfs_referral);
9352                         }
9353                 
9354                         /* referral version */
9355                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9356                         version = tvb_get_letohs(tvb, offset);
9357                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9358                                 tvb, offset, 2, version);
9359                         COUNT_BYTES_TRANS_SUBR(2);
9360
9361                         /* referral size */
9362                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9363                         refsize = tvb_get_letohs(tvb, offset);
9364                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9365                         COUNT_BYTES_TRANS_SUBR(2);
9366
9367                         /* referral server type */
9368                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9369                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9370                         COUNT_BYTES_TRANS_SUBR(2);
9371
9372                         /* referral flags */
9373                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9374                         offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
9375                         *bcp -= 2;
9376
9377                         switch(version){
9378
9379                         case 1:
9380                                 /* node name */
9381                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9382                                 CHECK_STRING_TRANS_SUBR(fn);
9383                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9384                                         fn);
9385                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9386                                 break;
9387
9388                         case 2:
9389                         case 3: /* XXX - like version 2, but not identical;
9390                                    seen in a capture, but the format isn't
9391                                    documented */
9392                                 /* proximity */
9393                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9394                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9395                                 COUNT_BYTES_TRANS_SUBR(2);
9396
9397                                 /* ttl */
9398                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9399                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9400                                 COUNT_BYTES_TRANS_SUBR(2);
9401
9402                                 /* path offset */
9403                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9404                                 pathoffset = tvb_get_letohs(tvb, offset);
9405                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9406                                 COUNT_BYTES_TRANS_SUBR(2);
9407
9408                                 /* alt path offset */
9409                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9410                                 altpathoffset = tvb_get_letohs(tvb, offset);
9411                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
9412                                 COUNT_BYTES_TRANS_SUBR(2);
9413
9414                                 /* node offset */
9415                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9416                                 nodeoffset = tvb_get_letohs(tvb, offset);
9417                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
9418                                 COUNT_BYTES_TRANS_SUBR(2);
9419
9420                                 /* path */
9421                                 if (pathoffset != 0) {
9422                                         stroffset = old_offset + pathoffset;
9423                                         offsetoffset = stroffset - offset;
9424                                         if (offsetoffset > 0 &&
9425                                             *bcp > offsetoffset) {
9426                                                 save_bc = *bcp;
9427                                                 *bcp -= offsetoffset;
9428                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9429                                                 CHECK_STRING_TRANS_SUBR(fn);
9430                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
9431                                                         fn);
9432                                                 stroffset += fn_len;
9433                                                 if (ucstring_end < stroffset)
9434                                                         ucstring_end = stroffset;
9435                                                 *bcp = save_bc;
9436                                         }
9437                                 }
9438                         
9439                                 /* alt path */
9440                                 if (altpathoffset != 0) {
9441                                         stroffset = old_offset + altpathoffset;
9442                                         offsetoffset = stroffset - offset;
9443                                         if (offsetoffset > 0 &&
9444                                             *bcp > offsetoffset) {
9445                                                 save_bc = *bcp;
9446                                                 *bcp -= offsetoffset;
9447                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9448                                                 CHECK_STRING_TRANS_SUBR(fn);
9449                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
9450                                                         fn);
9451                                                 stroffset += fn_len;
9452                                                 if (ucstring_end < stroffset)
9453                                                         ucstring_end = stroffset;
9454                                                 *bcp = save_bc;
9455                                         }
9456                                 }
9457                         
9458                                 /* node */
9459                                 if (nodeoffset != 0) {
9460                                         stroffset = old_offset + nodeoffset;
9461                                         offsetoffset = stroffset - offset;
9462                                         if (offsetoffset > 0 &&
9463                                             *bcp > offsetoffset) {
9464                                                 save_bc = *bcp;
9465                                                 *bcp -= offsetoffset;
9466                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9467                                                 CHECK_STRING_TRANS_SUBR(fn);
9468                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
9469                                                         fn);
9470                                                 stroffset += fn_len;
9471                                                 if (ucstring_end < stroffset)
9472                                                         ucstring_end = stroffset;
9473                                                 *bcp = save_bc;
9474                                         }
9475                                 }
9476                                 break;
9477                         }
9478
9479                         /*
9480                          * Show anything beyond the length of the referral
9481                          * as unknown data.
9482                          */
9483                         unklen = (old_offset + refsize) - offset;
9484                         if (unklen < 0) {
9485                                 /*
9486                                  * XXX - the length is bogus.
9487                                  */
9488                                 unklen = 0;
9489                         }
9490                         if (unklen != 0) {
9491                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
9492                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
9493                                     offset, unklen, TRUE);
9494                                 COUNT_BYTES_TRANS_SUBR(unklen);
9495                         }
9496
9497                         proto_item_set_len(ri, offset-old_offset);
9498                 }
9499
9500                 /*
9501                  * Treat the offset past the end of the last Unicode
9502                  * string after the referrals (if any) as the last
9503                  * offset.
9504                  */
9505                 if (ucstring_end > offset) {
9506                         ucstring_len = ucstring_end - offset;
9507                         if (*bcp < ucstring_len)
9508                                 ucstring_len = *bcp;
9509                         offset += ucstring_len;
9510                         *bcp -= ucstring_len;
9511                 }
9512                 proto_item_set_len(ref_item, offset-old_offset);
9513         }
9514
9515         return offset;
9516 }
9517
9518
9519 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
9520    as described in 4.2.14.1
9521 */
9522 static int
9523 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9524     int offset, guint16 *bcp, gboolean *trunc)
9525 {
9526         /* create time */
9527         CHECK_BYTE_COUNT_SUBR(4);
9528         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9529                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
9530                 FALSE);
9531         *bcp -= 4;
9532
9533         /* access time */
9534         CHECK_BYTE_COUNT_SUBR(4);
9535         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9536                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
9537                 FALSE);
9538         *bcp -= 4;
9539
9540         /* last write time */
9541         CHECK_BYTE_COUNT_SUBR(4);
9542         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9543                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
9544                 FALSE);
9545         *bcp -= 4;
9546
9547         /* data size */
9548         CHECK_BYTE_COUNT_SUBR(4);
9549         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9550         COUNT_BYTES_SUBR(4);
9551
9552         /* allocation size */
9553         CHECK_BYTE_COUNT_SUBR(4);
9554         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9555         COUNT_BYTES_SUBR(4);
9556
9557         /* File Attributes */
9558         CHECK_BYTE_COUNT_SUBR(2);
9559         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9560         *bcp -= 2;
9561
9562         /* ea size */
9563         CHECK_BYTE_COUNT_SUBR(4);
9564         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9565         COUNT_BYTES_SUBR(4);
9566
9567         *trunc = FALSE;
9568         return offset;
9569 }
9570
9571 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
9572    as described in 4.2.14.2
9573 */
9574 static int
9575 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9576     int offset, guint16 *bcp, gboolean *trunc)
9577 {
9578         /* list length */
9579         CHECK_BYTE_COUNT_SUBR(4);
9580         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
9581         COUNT_BYTES_SUBR(4);
9582
9583         *trunc = FALSE;
9584         return offset;
9585 }
9586
9587 /* this dissects the SMB_INFO_IS_NAME_VALID
9588    as described in 4.2.14.3
9589 */
9590 static int
9591 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9592     int offset, guint16 *bcp, gboolean *trunc)
9593 {
9594         int fn_len;
9595         const char *fn;
9596
9597         /* file name */
9598         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9599         CHECK_STRING_SUBR(fn);
9600         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9601                 fn);
9602         COUNT_BYTES_SUBR(fn_len);
9603
9604         *trunc = FALSE;
9605         return offset;
9606 }
9607
9608 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
9609    as described in 4.2.14.4
9610 */
9611 static int
9612 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9613     int offset, guint16 *bcp, gboolean *trunc)
9614 {
9615         /* create time */
9616         CHECK_BYTE_COUNT_SUBR(8);
9617         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9618                 hf_smb_create_time);
9619         *bcp -= 8;
9620         
9621         /* access time */
9622         CHECK_BYTE_COUNT_SUBR(8);
9623         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9624                 hf_smb_access_time);
9625         *bcp -= 8;
9626         
9627         /* last write time */
9628         CHECK_BYTE_COUNT_SUBR(8);
9629         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9630                 hf_smb_last_write_time);
9631         *bcp -= 8;
9632         
9633         /* last change time */
9634         CHECK_BYTE_COUNT_SUBR(8);
9635         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9636                 hf_smb_change_time);
9637         *bcp -= 8;
9638         
9639         /* File Attributes */
9640         CHECK_BYTE_COUNT_SUBR(2);
9641         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9642         *bcp -= 2;
9643
9644         *trunc = FALSE;
9645         return offset;
9646 }
9647
9648 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
9649    as described in 4.2.14.5
9650 */
9651 static int
9652 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9653     int offset, guint16 *bcp, gboolean *trunc)
9654 {
9655         /* allocation size */
9656         CHECK_BYTE_COUNT_SUBR(8);
9657         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9658         COUNT_BYTES_SUBR(8);
9659
9660         /* end of file */
9661         CHECK_BYTE_COUNT_SUBR(8);
9662         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9663         COUNT_BYTES_SUBR(8);
9664
9665         /* number of links */
9666         CHECK_BYTE_COUNT_SUBR(4);
9667         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
9668         COUNT_BYTES_SUBR(4);
9669
9670         /* delete pending */
9671         CHECK_BYTE_COUNT_SUBR(2);
9672         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
9673         COUNT_BYTES_SUBR(2);
9674
9675         /* is directory */
9676         CHECK_BYTE_COUNT_SUBR(1);
9677         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9678         COUNT_BYTES_SUBR(1);
9679
9680         *trunc = FALSE;
9681         return offset;
9682 }
9683
9684 /* this dissects the SMB_QUERY_FILE_EA_INFO
9685    as described in 4.2.14.6
9686 */
9687 static int
9688 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9689     int offset, guint16 *bcp, gboolean *trunc)
9690 {
9691         /* ea size */
9692         CHECK_BYTE_COUNT_SUBR(4);
9693         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9694         COUNT_BYTES_SUBR(4);
9695
9696         *trunc = FALSE;
9697         return offset;
9698 }
9699
9700 /* this dissects the SMB_QUERY_FILE_NAME_INFO
9701    as described in 4.2.14.7
9702    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
9703    as described in 4.2.14.9
9704 */
9705 static int
9706 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9707     int offset, guint16 *bcp, gboolean *trunc)
9708 {
9709         int fn_len;
9710         const char *fn;
9711
9712         /* file name len */
9713         CHECK_BYTE_COUNT_SUBR(4);
9714         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
9715         COUNT_BYTES_SUBR(4);
9716
9717         /* file name */
9718         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9719         CHECK_STRING_SUBR(fn);
9720         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9721                 fn);
9722         COUNT_BYTES_SUBR(fn_len);
9723
9724         *trunc = FALSE;
9725         return offset;
9726 }
9727
9728 /* this dissects the SMB_QUERY_FILE_ALL_INFO
9729    as described in 4.2.14.8
9730 */
9731 static int
9732 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9733     int offset, guint16 *bcp, gboolean *trunc)
9734 {
9735
9736         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
9737         if (trunc)
9738                 return offset;
9739         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
9740         if (trunc)
9741                 return offset;
9742
9743         /* index number */
9744         CHECK_BYTE_COUNT_SUBR(8);
9745         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9746         COUNT_BYTES_SUBR(8);
9747
9748         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9749         if (trunc)
9750                 return offset;
9751
9752         /* access flags */
9753         CHECK_BYTE_COUNT_SUBR(4);
9754         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
9755         COUNT_BYTES_SUBR(4);
9756
9757         /* index number */
9758         CHECK_BYTE_COUNT_SUBR(8);
9759         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9760         COUNT_BYTES_SUBR(8);
9761
9762         /* current offset */
9763         CHECK_BYTE_COUNT_SUBR(8);
9764         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
9765         COUNT_BYTES_SUBR(8);
9766
9767         /* mode */
9768         CHECK_BYTE_COUNT_SUBR(4);
9769         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
9770         *bcp -= 4;
9771
9772         /* alignment */
9773         CHECK_BYTE_COUNT_SUBR(4);
9774         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
9775         COUNT_BYTES_SUBR(4);
9776         
9777         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9778
9779         return offset;
9780 }
9781
9782 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
9783    as described in 4.2.14.10
9784 */
9785 static int
9786 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9787     int offset, guint16 *bcp, gboolean *trunc)
9788 {
9789         proto_item *item;
9790         proto_tree *tree;
9791         int old_offset;
9792         guint32 neo;
9793         int fn_len;
9794         const char *fn;
9795         int padcnt;
9796
9797         for (;;) {
9798                 old_offset = offset;
9799
9800                 /* next entry offset */
9801                 CHECK_BYTE_COUNT_SUBR(4);
9802                 if(parent_tree){
9803                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
9804                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9805                 } else {
9806                         item = NULL;
9807                         tree = NULL;
9808                 }
9809
9810                 neo = tvb_get_letohl(tvb, offset);
9811                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9812                 COUNT_BYTES_SUBR(4);
9813         
9814                 /* stream name len */
9815                 CHECK_BYTE_COUNT_SUBR(4);
9816                 fn_len = tvb_get_letohl(tvb, offset);
9817                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
9818                 COUNT_BYTES_SUBR(4);
9819         
9820                 /* stream size */
9821                 CHECK_BYTE_COUNT_SUBR(8);
9822                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
9823                 COUNT_BYTES_SUBR(8);
9824
9825                 /* allocation size */
9826                 CHECK_BYTE_COUNT_SUBR(8);
9827                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9828                 COUNT_BYTES_SUBR(8);
9829
9830                 /* stream name */
9831                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9832                 CHECK_STRING_SUBR(fn);
9833                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
9834                         fn);
9835                 COUNT_BYTES_SUBR(fn_len);
9836  
9837                 proto_item_append_text(item, ": %s", fn);
9838                 proto_item_set_len(item, offset-old_offset);
9839
9840                 if (neo == 0)
9841                         break;  /* no more structures */
9842
9843                 /* skip to next structure */
9844                 padcnt = (old_offset + neo) - offset;
9845                 if (padcnt < 0) {
9846                         /*
9847                          * XXX - this is bogus; flag it?
9848                          */
9849                         padcnt = 0;
9850                 }
9851                 if (padcnt != 0) {
9852                         CHECK_BYTE_COUNT_SUBR(padcnt);
9853                         COUNT_BYTES_SUBR(padcnt);
9854                 }
9855         }
9856
9857         *trunc = FALSE;
9858         return offset;
9859 }
9860
9861 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
9862    as described in 4.2.14.11
9863 */
9864 static int
9865 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9866     int offset, guint16 *bcp, gboolean *trunc)
9867 {
9868         /* compressed file size */
9869         CHECK_BYTE_COUNT_SUBR(8);
9870         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
9871         COUNT_BYTES_SUBR(8);
9872
9873         /* compression format */
9874         CHECK_BYTE_COUNT_SUBR(2);
9875         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
9876         COUNT_BYTES_SUBR(2);
9877         
9878         /* compression unit shift */
9879         CHECK_BYTE_COUNT_SUBR(1);
9880         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
9881         COUNT_BYTES_SUBR(1);
9882         
9883         /* compression chunk shift */
9884         CHECK_BYTE_COUNT_SUBR(1);
9885         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
9886         COUNT_BYTES_SUBR(1);
9887         
9888         /* compression cluster shift */
9889         CHECK_BYTE_COUNT_SUBR(1);
9890         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
9891         COUNT_BYTES_SUBR(1);
9892         
9893         /* 3 reserved bytes */
9894         CHECK_BYTE_COUNT_SUBR(3);
9895         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9896         COUNT_BYTES_SUBR(3);
9897
9898         *trunc = FALSE;
9899         return offset;
9900 }
9901
9902
9903
9904 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
9905 static int
9906 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
9907     int offset, guint16 *bcp)
9908 {
9909         smb_info_t *si;
9910         gboolean trunc;
9911
9912         if(!*bcp){
9913                 return offset;
9914         }
9915         
9916         si = (smb_info_t *)pinfo->private_data;
9917         switch(si->info_level){
9918         case 1:         /*Info Standard*/
9919         case 2:         /*Info Query EA Size*/
9920                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
9921                     &trunc);
9922                 break;
9923         case 3:         /*Info Query EAs From List*/
9924         case 4:         /*Info Query All EAs*/
9925                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
9926                     &trunc);
9927                 break;
9928         case 6:         /*Info Is Name Valid*/
9929                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
9930                     &trunc);
9931                 break;
9932         case 0x0101:    /*Query File Basic Info*/
9933                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
9934                     &trunc);
9935                 break;
9936         case 0x0102:    /*Query File Standard Info*/
9937                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
9938                     &trunc);
9939                 break;
9940         case 0x0103:    /*Query File EA Info*/
9941                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
9942                     &trunc);
9943                 break;
9944         case 0x0104:    /*Query File Name Info*/
9945                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9946                     &trunc);
9947                 break;
9948         case 0x0107:    /*Query File All Info*/
9949                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
9950                     &trunc);
9951                 break;
9952         case 0x0108:    /*Query File Alt File Info*/
9953                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9954                     &trunc);
9955                 break;
9956         case 0x0109:    /*Query File Stream Info*/
9957                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
9958                     &trunc);
9959                 break;
9960         case 0x010b:    /*Query File Compression Info*/
9961                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
9962                     &trunc);
9963                 break;
9964         case 0x0200:    /*Set File Unix Basic*/
9965                 /* XXX add this from the SNIA doc */
9966                 break;
9967         case 0x0201:    /*Set File Unix Link*/
9968                 /* XXX add this from the SNIA doc */
9969                 break;
9970         case 0x0202:    /*Set File Unix HardLink*/
9971                 /* XXX add this from the SNIA doc */
9972                 break;
9973         }
9974         
9975         return offset;
9976 }
9977
9978
9979 static const true_false_string tfs_quota_flags_deny_disk = {
9980         "DENY DISK SPACE for users exceeding quota limit",
9981         "Do NOT deny disk space for users exceeding quota limit"
9982 };
9983 static const true_false_string tfs_quota_flags_log_limit = {
9984         "LOG EVENT when a user exceeds their QUOTA LIMIT",
9985         "Do NOT log event when a user exceeds their quota limit"
9986 };
9987 static const true_false_string tfs_quota_flags_log_warning = {
9988         "LOG EVENT when a user exceeds their WARNING LEVEL",
9989         "Do NOT log event when a user exceeds their warning level"
9990 };
9991 static const true_false_string tfs_quota_flags_enabled = {
9992         "Quotas are ENABLED of this fs",
9993         "Quotas are NOT enabled on this fs"
9994 };
9995 static void
9996 dissect_quota_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9997 {
9998         guint8 mask;
9999         proto_item *item = NULL;
10000         proto_tree *tree = NULL;
10001
10002         mask = tvb_get_guint8(tvb, offset);
10003
10004         if(parent_tree){
10005                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10006                         "Quota Flags: 0x%02x %s", mask,
10007                         mask?"Enabled":"Disabled");
10008                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10009         }
10010
10011         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10012                 tvb, offset, 1, mask);
10013         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10014                 tvb, offset, 1, mask);
10015         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10016                 tvb, offset, 1, mask);
10017
10018         if(mask && (!(mask&0x01))){
10019                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10020                         tvb, offset, 1, 0x01);
10021         } else {
10022                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10023                         tvb, offset, 1, mask);
10024         }
10025
10026 }
10027
10028 static int
10029 dissect_nt_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
10030 {
10031         /* first 24 bytes are unknown */
10032         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10033         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10034                     offset, 24, TRUE);
10035         COUNT_BYTES_TRANS_SUBR(24);
10036
10037         /* number of bytes for quota warning */
10038         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10039         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10040         COUNT_BYTES_TRANS_SUBR(8);
10041
10042         /* number of bytes for quota limit */
10043         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10044         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10045         COUNT_BYTES_TRANS_SUBR(8);
10046
10047         /* one byte of quota flags */
10048         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10049         dissect_quota_flags(tvb, pinfo, tree, offset);
10050         COUNT_BYTES_TRANS_SUBR(1);
10051
10052         /* these 7 bytes are unknown */
10053         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10054         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10055                     offset, 7, TRUE);
10056         COUNT_BYTES_TRANS_SUBR(7);
10057
10058         return offset;
10059 }
10060
10061 static int
10062 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10063     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10064 {
10065         proto_item *item = NULL;
10066         proto_tree *tree = NULL;
10067         smb_info_t *si;
10068
10069         si = (smb_info_t *)pinfo->private_data;
10070
10071         if(parent_tree){
10072                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10073                                 "%s Data",
10074                                 val_to_str(subcmd, trans2_cmd_vals, 
10075                                                 "Unknown (0x%02x)"));
10076                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10077         }
10078
10079         switch(subcmd){
10080         case 0x00:      /*TRANS2_OPEN2*/
10081                 /* XXX FAEList here?*/
10082                 break;
10083         case 0x01:      /*TRANS2_FIND_FIRST2*/
10084                 /* XXX FAEList here?*/
10085                 break;
10086         case 0x02:      /*TRANS2_FIND_NEXT2*/
10087                 /* no data field in this request */
10088                 break;
10089         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10090                 /* no data field in this request */
10091                 break;
10092         case 0x04:      /* TRANS2_SET_QUOTA */
10093                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, &dc);
10094                 break;
10095         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10096                 /* no data field in this request */
10097                 break;
10098         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10099                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10100                 break;
10101         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10102                 /* no data field in this request */
10103                 break;
10104         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10105                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10106                 break;
10107         case 0x09:      /*TRANS2_FSCTL*/
10108                 /*XXX dont know how to decode this yet */
10109                 break;
10110         case 0x0a:      /*TRANS2_IOCTL2*/
10111                 /*XXX dont know how to decode this yet */
10112                 break;
10113         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10114                 /*XXX dont know how to decode this yet */
10115                 break;
10116         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10117                 /*XXX dont know how to decode this yet */
10118                 break;
10119         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10120                 /* no data block for this one */
10121                 break;
10122         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10123                 /*XXX dont know how to decode this yet */
10124                 break;
10125         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10126                 /* no data field in this request */
10127                 break;
10128         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10129                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10130                 break;
10131         }
10132
10133         /* ooops there were data we didnt know how to process */
10134         if(dc != 0){
10135                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10136                 offset += dc;
10137         }
10138
10139         return offset;
10140 }
10141
10142
10143 static void
10144 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10145     packet_info *pinfo, proto_tree *tree)
10146 {
10147         int i;
10148         int offset;
10149         guint length;
10150
10151         /*
10152          * Show the setup words.
10153          */
10154         if (s_tvb != NULL) {
10155                 length = tvb_reported_length(s_tvb);
10156                 for (i = 0, offset = 0; length >= 2;
10157                     i++, offset += 2, length -= 2) {
10158                         /*
10159                          * XXX - add a setup word filterable field?
10160                          */
10161                         proto_tree_add_text(tree, s_tvb, offset, 2,
10162                             "Setup Word %d: 0x%04x", i,
10163                             tvb_get_letohs(s_tvb, offset));
10164                 }
10165         }
10166
10167         /*
10168          * Show the parameters, if any.
10169          */
10170         if (p_tvb != NULL) {
10171                 length = tvb_reported_length(p_tvb);
10172                 if (length != 0) {
10173                         proto_tree_add_text(tree, p_tvb, 0, length,
10174                             "Parameters: %s",
10175                             tvb_bytes_to_str(p_tvb, 0, length));
10176                 }
10177         }
10178
10179         /*
10180          * Show the data, if any.
10181          */
10182         if (d_tvb != NULL) {
10183                 length = tvb_reported_length(d_tvb);
10184                 if (length != 0) {
10185                         proto_tree_add_text(tree, d_tvb, 0, length,
10186                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10187                 }
10188         }
10189 }
10190
10191 /* This routine handles the following 4 calls
10192    Transaction  0x25
10193    Transaction Secondary 0x26
10194    Transaction2 0x32
10195    Transaction2 Secondary 0x33
10196 */
10197 static int
10198 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
10199 {
10200         guint8 wc, sc=0;
10201         int so=offset;
10202         int sl=0;
10203         int spo=offset;
10204         int spc=0;
10205         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10206         int subcmd = -1;
10207         guint32 to;
10208         int an_len;
10209         const char *an = NULL;
10210         smb_info_t *si;
10211         smb_transact2_info_t *t2i;
10212         smb_transact_info_t *tri;
10213         guint16 bc;
10214         int padcnt;
10215         gboolean dissected_trans;
10216
10217         si = (smb_info_t *)pinfo->private_data;
10218
10219         WORD_COUNT;
10220
10221         if(wc==8){
10222                 /*secondary client request*/
10223
10224                 /* total param count, only a 16bit integer here*/
10225                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10226                 offset += 2;
10227         
10228                 /* total data count , only 16bit integer here*/
10229                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10230                 offset += 2;
10231
10232                 /* param count */
10233                 pc = tvb_get_letohs(tvb, offset);
10234                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10235                 offset += 2;
10236
10237                 /* param offset */
10238                 po = tvb_get_letohs(tvb, offset);
10239                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10240                 offset += 2;
10241
10242                 /* param disp */
10243                 pd = tvb_get_letohs(tvb, offset);
10244                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10245                 offset += 2;
10246         
10247                 /* data count */
10248                 dc = tvb_get_letohs(tvb, offset);
10249                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10250                 offset += 2;
10251
10252                 /* data offset */
10253                 od = tvb_get_letohs(tvb, offset);
10254                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10255                 offset += 2;
10256         
10257                 /* data disp */
10258                 dd = tvb_get_letohs(tvb, offset);
10259                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10260                 offset += 2;
10261
10262                 if(si->cmd==SMB_COM_TRANSACTION2){
10263                         guint16 fid;
10264
10265                         /* fid */
10266                         fid = tvb_get_letohs(tvb, offset);
10267                         add_fid(tvb, pinfo, tree, offset, 2, fid);
10268
10269                         offset += 2;
10270                 }
10271
10272                 /* There are no setup words. */
10273                 so = offset;
10274                 sc = 0;
10275                 sl = 0;
10276         } else {
10277                 /* it is not a secondary request */
10278
10279                 /* total param count , only a 16 bit integer here*/
10280                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10281                 offset += 2;
10282
10283                 /* total data count , only 16bit integer here*/
10284                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10285                 offset += 2;
10286
10287                 /* max param count , only 16bit integer here*/
10288                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10289                 offset += 2;
10290
10291                 /* max data count, only 16bit integer here*/
10292                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10293                 offset += 2;
10294
10295                 /* max setup count, only 16bit integer here*/
10296                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10297                 offset += 1;
10298
10299                 /* reserved byte */
10300                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10301                 offset += 1;
10302
10303                 /* transaction flags */
10304                 tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
10305                 offset += 2;
10306
10307                 /* timeout */
10308                 to = tvb_get_letohl(tvb, offset);
10309                 if (to == 0)
10310                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
10311                 else if (to == 0xffffffff)
10312                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
10313                 else
10314                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
10315                 offset += 4;
10316
10317                 /* 2 reserved bytes */
10318                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10319                 offset += 2;
10320
10321                 /* param count */
10322                 pc = tvb_get_letohs(tvb, offset);
10323                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10324                 offset += 2;
10325         
10326                 /* param offset */
10327                 po = tvb_get_letohs(tvb, offset);
10328                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10329                 offset += 2;
10330
10331                 /* param displacement is zero here */
10332                 pd = 0;
10333
10334                 /* data count */
10335                 dc = tvb_get_letohs(tvb, offset);
10336                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10337                 offset += 2;
10338
10339                 /* data offset */
10340                 od = tvb_get_letohs(tvb, offset);
10341                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10342                 offset += 2;
10343
10344                 /* data displacement is zero here */
10345                 dd = 0;
10346
10347                 /* setup count */
10348                 sc = tvb_get_guint8(tvb, offset);
10349                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10350                 offset += 1;
10351
10352                 /* reserved byte */
10353                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10354                 offset += 1;
10355                 
10356                 /* this is where the setup bytes, if any start */       
10357                 so = offset;
10358                 sl = sc*2;
10359
10360                 /* if there were any setup bytes, decode them */
10361                 if(sc){
10362                         switch(si->cmd){
10363
10364                         case SMB_COM_TRANSACTION2:
10365                                 /* TRANSACTION2 only has one setup word and
10366                                    that is the subcommand code. */
10367                                 subcmd = tvb_get_letohs(tvb, offset);
10368                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
10369                                     tvb, offset, 2, subcmd);
10370                                 if (check_col(pinfo->cinfo, COL_INFO)) {
10371                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10372                                             val_to_str(subcmd, trans2_cmd_vals, 
10373                                                 "Unknown (0x%02x)"));
10374                                 }
10375                                 if (!si->unidir) {
10376                                         if(!pinfo->fd->flags.visited){
10377                                                 /* 
10378                                                  * Allocate a new
10379                                                  * smb_transact2_info_t
10380                                                  * structure.
10381                                                  */
10382                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
10383                                                 t2i->subcmd = subcmd;
10384                                                 t2i->info_level = -1;
10385                                                 si->sip->extra_info = t2i;
10386                                         }
10387                                 }     
10388                                 break;
10389
10390                         case SMB_COM_TRANSACTION:
10391                                 /* TRANSACTION setup words processed below */
10392                                 break;
10393                         }
10394
10395                         offset += sl;
10396                 }
10397         }
10398
10399         BYTE_COUNT;
10400         
10401         if(wc!=8){
10402                 /* primary request */
10403                 /* name is NULL if transaction2 */
10404                 if(si->cmd == SMB_COM_TRANSACTION){
10405                         /* Transaction Name */
10406                         an = get_unicode_or_ascii_string(tvb, &offset,
10407                                 pinfo, &an_len, FALSE, FALSE, &bc);
10408                         if (an == NULL)
10409                                 goto endofcommand;
10410                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
10411                                 offset, an_len, an);
10412                         COUNT_BYTES(an_len);
10413                 }
10414         }
10415
10416         /*
10417          * The pipe or mailslot arguments for Transaction start with
10418          * the first setup word (or where the first setup word would
10419          * be if there were any setup words), and run to the current
10420          * offset (which could mean that there aren't any).
10421          */
10422         spo = so;
10423         spc = offset - spo;
10424
10425         /* parameters */
10426         if(po>offset){
10427                 /* We have some initial padding bytes.
10428                 */
10429                 padcnt = po-offset;
10430                 if (padcnt > bc)
10431                         padcnt = bc;
10432                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10433                 COUNT_BYTES(padcnt);
10434         }
10435         if(pc){
10436                 CHECK_BYTE_COUNT(pc);
10437                 switch(si->cmd) {
10438
10439                 case SMB_COM_TRANSACTION2:
10440                         /* TRANSACTION2 parameters*/
10441                         offset = dissect_transaction2_request_parameters(tvb,
10442                             pinfo, tree, offset, subcmd, pc);
10443                         bc -= pc;
10444                         break;
10445
10446                 case SMB_COM_TRANSACTION:
10447                         /* TRANSACTION parameters processed below */
10448                         COUNT_BYTES(pc);
10449                         break;
10450                 }
10451         }
10452
10453         /* data */
10454         if(od>offset){
10455                 /* We have some initial padding bytes.
10456                 */
10457                 padcnt = od-offset;
10458                 if (padcnt > bc)
10459                         padcnt = bc;
10460                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10461                 COUNT_BYTES(padcnt);
10462         }
10463         if(dc){
10464                 CHECK_BYTE_COUNT(dc);
10465                 switch(si->cmd){
10466
10467                 case SMB_COM_TRANSACTION2:
10468                         /* TRANSACTION2 data*/
10469                         offset = dissect_transaction2_request_data(tvb, pinfo,
10470                             tree, offset, subcmd, dc);
10471                         bc -= dc;
10472                         break;
10473
10474                 case SMB_COM_TRANSACTION:
10475                         /* TRANSACTION data processed below */
10476                         COUNT_BYTES(dc);
10477                         break;
10478                 }
10479         }
10480
10481         /*TRANSACTION request parameters */
10482         if(si->cmd==SMB_COM_TRANSACTION){
10483                 /*XXX replace this block with a function and use that one 
10484                      for both requests/responses*/
10485                 if(dd==0){
10486                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
10487                         tvbuff_t *sp_tvb, *pd_tvb;
10488
10489                         if(pc>0){
10490                                 if(pc>tvb_length_remaining(tvb, po)){
10491                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
10492                                 } else {
10493                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
10494                                 }
10495                         } else {
10496                                 p_tvb = NULL;
10497                         }
10498                         if(dc>0){
10499                                 if(dc>tvb_length_remaining(tvb, od)){
10500                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
10501                                 } else {
10502                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
10503                                 }
10504                         } else {
10505                                 d_tvb = NULL;
10506                         }
10507                         if(sl){
10508                                 if(sl>tvb_length_remaining(tvb, so)){
10509                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
10510                                 } else {
10511                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
10512                                 }
10513                         } else {
10514                                 s_tvb = NULL;
10515                         }
10516
10517                         if (!si->unidir) {
10518                                 if(!pinfo->fd->flags.visited){
10519                                         /* 
10520                                          * Allocate a new smb_transact_info_t
10521                                          * structure.
10522                                          */
10523                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
10524                                         tri->subcmd = -1;
10525                                         tri->trans_subcmd = -1;
10526                                         tri->function = -1;
10527                                         tri->fid = -1;
10528                                         tri->lanman_cmd = 0;
10529                                         tri->param_descrip = NULL;
10530                                         tri->data_descrip = NULL;
10531                                         tri->aux_data_descrip = NULL;
10532                                         tri->info_level = -1;
10533                                         si->sip->extra_info = tri;
10534                                 } else {
10535                                         /*
10536                                          * We already filled the structure
10537                                          * in; don't bother doing so again.
10538                                          */
10539                                         tri = NULL;
10540                                 }
10541                         } else {
10542                                 /*
10543                                  * This is a unidirectional message, for
10544                                  * which there will be no reply; don't
10545                                  * bother allocating an "smb_transact_info_t"
10546                                  * structure for it.
10547                                  */
10548                                 tri = NULL;
10549                         }
10550                         dissected_trans = FALSE;
10551                         if(strncmp("\\PIPE\\", an, 6) == 0){
10552                                 if (tri != NULL)
10553                                         tri->subcmd=TRANSACTION_PIPE;
10554
10555                                 /*
10556                                  * A tvbuff containing the setup words and
10557                                  * the pipe path.
10558                                  */
10559                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10560
10561                                 /*
10562                                  * A tvbuff containing the parameters and the
10563                                  * data.
10564                                  */
10565                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
10566
10567                                 dissected_trans = dissect_pipe_smb(sp_tvb,
10568                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
10569                                     top_tree);
10570                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
10571                                 if (tri != NULL)
10572                                         tri->subcmd=TRANSACTION_MAILSLOT;
10573
10574                                 /*
10575                                  * A tvbuff containing the setup words and
10576                                  * the mailslot path.
10577                                  */
10578                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10579                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
10580                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
10581                         }
10582                         if (!dissected_trans) {
10583                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
10584                                     pinfo, tree);
10585                         }
10586                 } else {
10587                         if(check_col(pinfo->cinfo, COL_INFO)){
10588                                 col_append_str(pinfo->cinfo, COL_INFO,
10589                                         "[transact continuation]");
10590                         }
10591                 }
10592         }
10593
10594         END_OF_SMB
10595
10596         return offset;
10597 }
10598
10599  
10600
10601 static int
10602 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10603     int offset, guint16 *bcp, gboolean *trunc)
10604 {
10605         int fn_len;
10606         const char *fn;
10607         int old_offset = offset;
10608         proto_item *item = NULL;
10609         proto_tree *tree = NULL;
10610         smb_info_t *si;
10611
10612         si = (smb_info_t *)pinfo->private_data;
10613
10614         if(parent_tree){
10615                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10616                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10617                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10618         }
10619
10620         /* create time */
10621         CHECK_BYTE_COUNT_SUBR(4);
10622         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10623                 hf_smb_create_time,
10624                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10625         *bcp -= 4;
10626
10627         /* access time */
10628         CHECK_BYTE_COUNT_SUBR(4);
10629         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10630                 hf_smb_access_time,
10631                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10632         *bcp -= 4;
10633
10634         /* last write time */
10635         CHECK_BYTE_COUNT_SUBR(4);
10636         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10637                 hf_smb_last_write_time,
10638                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10639         *bcp -= 4;
10640
10641         /* data size */
10642         CHECK_BYTE_COUNT_SUBR(4);
10643         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10644         COUNT_BYTES_SUBR(4);
10645
10646         /* allocation size */
10647         CHECK_BYTE_COUNT_SUBR(4);
10648         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10649         COUNT_BYTES_SUBR(4);
10650
10651         /* File Attributes */
10652         CHECK_BYTE_COUNT_SUBR(2);
10653         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10654         *bcp -= 2;
10655
10656         /* file name len */
10657         CHECK_BYTE_COUNT_SUBR(1);
10658         fn_len = tvb_get_guint8(tvb, offset);
10659         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10660         COUNT_BYTES_SUBR(1);
10661
10662         /* file name */
10663         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10664         CHECK_STRING_SUBR(fn);
10665         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10666                 fn);
10667         COUNT_BYTES_SUBR(fn_len);
10668
10669         if (check_col(pinfo->cinfo, COL_INFO)) {
10670                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10671                 fn);
10672         }
10673  
10674         proto_item_append_text(item, " File: %s", fn);
10675         proto_item_set_len(item, offset-old_offset);
10676
10677         *trunc = FALSE;
10678         return offset;
10679 }
10680
10681 static int
10682 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10683     int offset, guint16 *bcp, gboolean *trunc)
10684 {
10685         int fn_len;
10686         const char *fn;
10687         int old_offset = offset;
10688         proto_item *item = NULL;
10689         proto_tree *tree = NULL;
10690         smb_info_t *si;
10691
10692         si = (smb_info_t *)pinfo->private_data;
10693
10694         if(parent_tree){
10695                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10696                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10697                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10698         }
10699  
10700         /* create time */
10701         CHECK_BYTE_COUNT_SUBR(4);
10702         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10703                 hf_smb_create_time,
10704                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10705         *bcp -= 4;
10706
10707         /* access time */
10708         CHECK_BYTE_COUNT_SUBR(4);
10709         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10710                 hf_smb_access_time,
10711                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10712         *bcp -= 4;
10713
10714         /* last write time */
10715         CHECK_BYTE_COUNT_SUBR(4);
10716         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10717                 hf_smb_last_write_time,
10718                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10719         *bcp -= 4;
10720
10721         /* data size */
10722         CHECK_BYTE_COUNT_SUBR(4);
10723         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10724         COUNT_BYTES_SUBR(4);
10725
10726         /* allocation size */
10727         CHECK_BYTE_COUNT_SUBR(4);
10728         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10729         COUNT_BYTES_SUBR(4);
10730
10731         /* File Attributes */
10732         CHECK_BYTE_COUNT_SUBR(2);
10733         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10734         *bcp -= 2;
10735
10736         /* ea size */
10737         CHECK_BYTE_COUNT_SUBR(4);
10738         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10739         COUNT_BYTES_SUBR(4);
10740
10741         /* file name len */
10742         CHECK_BYTE_COUNT_SUBR(1);
10743         fn_len = tvb_get_guint8(tvb, offset);
10744         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10745         COUNT_BYTES_SUBR(1);
10746
10747         /* file name */
10748         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10749         CHECK_STRING_SUBR(fn);
10750         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10751                 fn);
10752         COUNT_BYTES_SUBR(fn_len);
10753
10754         if (check_col(pinfo->cinfo, COL_INFO)) {
10755                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10756                 fn);
10757         }
10758
10759         proto_item_append_text(item, " File: %s", fn);
10760         proto_item_set_len(item, offset-old_offset);
10761
10762         *trunc = FALSE;
10763         return offset;
10764 }
10765
10766 static int
10767 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10768     int offset, guint16 *bcp, gboolean *trunc)
10769 {
10770         int fn_len;
10771         const char *fn;
10772         int old_offset = offset;
10773         proto_item *item = NULL;
10774         proto_tree *tree = NULL;
10775         smb_info_t *si;
10776         guint32 neo;
10777         int padcnt;
10778
10779         si = (smb_info_t *)pinfo->private_data;
10780
10781         if(parent_tree){
10782                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10783                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10784                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10785         }
10786
10787         /* next entry offset */
10788         CHECK_BYTE_COUNT_SUBR(4);
10789         neo = tvb_get_letohl(tvb, offset);
10790         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10791         COUNT_BYTES_SUBR(4);
10792         
10793         /* file index */
10794         CHECK_BYTE_COUNT_SUBR(4);
10795         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10796         COUNT_BYTES_SUBR(4);
10797
10798         /* create time */
10799         CHECK_BYTE_COUNT_SUBR(8);
10800         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10801                 hf_smb_create_time);
10802         *bcp -= 8;
10803         
10804         /* access time */
10805         CHECK_BYTE_COUNT_SUBR(8);
10806         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10807                 hf_smb_access_time);
10808         *bcp -= 8;
10809         
10810         /* last write time */
10811         CHECK_BYTE_COUNT_SUBR(8);
10812         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10813                 hf_smb_last_write_time);
10814         *bcp -= 8;
10815         
10816         /* last change time */
10817         CHECK_BYTE_COUNT_SUBR(8);
10818         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10819                 hf_smb_change_time);
10820         *bcp -= 8;
10821         
10822         /* end of file */
10823         CHECK_BYTE_COUNT_SUBR(8);
10824         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10825         COUNT_BYTES_SUBR(8);
10826
10827         /* allocation size */
10828         CHECK_BYTE_COUNT_SUBR(8);
10829         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10830         COUNT_BYTES_SUBR(8);
10831
10832         /* Extended File Attributes */
10833         CHECK_BYTE_COUNT_SUBR(4);
10834         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10835         *bcp -= 4;
10836
10837         /* file name len */
10838         CHECK_BYTE_COUNT_SUBR(4);
10839         fn_len = tvb_get_letohl(tvb, offset);
10840         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10841         COUNT_BYTES_SUBR(4);
10842
10843         /* file name */
10844         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10845         CHECK_STRING_SUBR(fn);
10846         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10847                 fn);
10848         COUNT_BYTES_SUBR(fn_len);
10849
10850         if (check_col(pinfo->cinfo, COL_INFO)) {
10851                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10852                 fn);
10853         }
10854
10855         /* skip to next structure */
10856         if(neo){
10857                 padcnt = (old_offset + neo) - offset;
10858                 if (padcnt < 0) {
10859                         /*
10860                          * XXX - this is bogus; flag it?
10861                          */
10862                         padcnt = 0;
10863                 }
10864                 if (padcnt != 0) {
10865                         CHECK_BYTE_COUNT_SUBR(padcnt);
10866                         COUNT_BYTES_SUBR(padcnt);
10867                 }
10868         }
10869
10870         proto_item_append_text(item, " File: %s", fn);
10871         proto_item_set_len(item, offset-old_offset);
10872
10873         *trunc = FALSE;
10874         return offset;
10875 }
10876
10877 static int
10878 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10879     int offset, guint16 *bcp, gboolean *trunc)
10880 {
10881         int fn_len;
10882         const char *fn;
10883         int old_offset = offset;
10884         proto_item *item = NULL;
10885         proto_tree *tree = NULL;
10886         smb_info_t *si;
10887         guint32 neo;
10888         int padcnt;
10889
10890         si = (smb_info_t *)pinfo->private_data;
10891
10892         if(parent_tree){
10893                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10894                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10895                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10896         }
10897
10898         /* next entry offset */
10899         CHECK_BYTE_COUNT_SUBR(4);
10900         neo = tvb_get_letohl(tvb, offset);
10901         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10902         COUNT_BYTES_SUBR(4);
10903         
10904         /* file index */
10905         CHECK_BYTE_COUNT_SUBR(4);
10906         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10907         COUNT_BYTES_SUBR(4);
10908
10909         /* create time */
10910         CHECK_BYTE_COUNT_SUBR(8);
10911         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10912                 hf_smb_create_time);
10913         *bcp -= 8;
10914         
10915         /* access time */
10916         CHECK_BYTE_COUNT_SUBR(8);
10917         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10918                 hf_smb_access_time);
10919         *bcp -= 8;
10920         
10921         /* last write time */
10922         CHECK_BYTE_COUNT_SUBR(8);
10923         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10924                 hf_smb_last_write_time);
10925         *bcp -= 8;
10926         
10927         /* last change time */
10928         CHECK_BYTE_COUNT_SUBR(8);
10929         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10930                 hf_smb_change_time);
10931         *bcp -= 8;
10932         
10933         /* end of file */
10934         CHECK_BYTE_COUNT_SUBR(8);
10935         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10936         COUNT_BYTES_SUBR(8);
10937
10938         /* allocation size */
10939         CHECK_BYTE_COUNT_SUBR(8);
10940         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10941         COUNT_BYTES_SUBR(8);
10942
10943         /* Extended File Attributes */
10944         CHECK_BYTE_COUNT_SUBR(4);
10945         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10946         *bcp -= 4;
10947
10948         /* file name len */
10949         CHECK_BYTE_COUNT_SUBR(4);
10950         fn_len = tvb_get_letohl(tvb, offset);
10951         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10952         COUNT_BYTES_SUBR(4);
10953
10954         /* ea size */
10955         CHECK_BYTE_COUNT_SUBR(4);
10956         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10957         COUNT_BYTES_SUBR(4);
10958
10959         /* file name */
10960         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10961         CHECK_STRING_SUBR(fn);
10962         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10963                 fn);
10964         COUNT_BYTES_SUBR(fn_len);
10965
10966         if (check_col(pinfo->cinfo, COL_INFO)) {
10967                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10968                 fn);
10969         }
10970
10971         /* skip to next structure */
10972         if(neo){
10973                 padcnt = (old_offset + neo) - offset;
10974                 if (padcnt < 0) {
10975                         /*
10976                          * XXX - this is bogus; flag it?
10977                          */
10978                         padcnt = 0;
10979                 }
10980                 if (padcnt != 0) {
10981                         CHECK_BYTE_COUNT_SUBR(padcnt);
10982                         COUNT_BYTES_SUBR(padcnt);
10983                 }
10984         }
10985
10986         proto_item_append_text(item, " File: %s", fn);
10987         proto_item_set_len(item, offset-old_offset);
10988
10989         *trunc = FALSE;
10990         return offset;
10991 }
10992
10993 static int
10994 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10995     int offset, guint16 *bcp, gboolean *trunc)
10996 {
10997         int fn_len, sfn_len;
10998         const char *fn, *sfn;
10999         int old_offset = offset;
11000         proto_item *item = NULL;
11001         proto_tree *tree = NULL;
11002         smb_info_t *si;
11003         guint32 neo;
11004         int padcnt;
11005
11006         si = (smb_info_t *)pinfo->private_data;
11007
11008         if(parent_tree){
11009                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11010                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11011                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11012         }
11013
11014         /* next entry offset */
11015         CHECK_BYTE_COUNT_SUBR(4);
11016         neo = tvb_get_letohl(tvb, offset);
11017         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11018         COUNT_BYTES_SUBR(4);
11019         
11020         /* file index */
11021         CHECK_BYTE_COUNT_SUBR(4);
11022         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11023         COUNT_BYTES_SUBR(4);
11024
11025         /* create time */
11026         CHECK_BYTE_COUNT_SUBR(8);
11027         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11028                 hf_smb_create_time);
11029         *bcp -= 8;
11030         
11031         /* access time */
11032         CHECK_BYTE_COUNT_SUBR(8);
11033         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11034                 hf_smb_access_time);
11035         *bcp -= 8;
11036         
11037         /* last write time */
11038         CHECK_BYTE_COUNT_SUBR(8);
11039         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11040                 hf_smb_last_write_time);
11041         *bcp -= 8;
11042         
11043         /* last change time */
11044         CHECK_BYTE_COUNT_SUBR(8);
11045         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11046                 hf_smb_change_time);
11047         *bcp -= 8;
11048         
11049         /* end of file */
11050         CHECK_BYTE_COUNT_SUBR(8);
11051         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11052         COUNT_BYTES_SUBR(8);
11053
11054         /* allocation size */
11055         CHECK_BYTE_COUNT_SUBR(8);
11056         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11057         COUNT_BYTES_SUBR(8);
11058
11059         /* Extended File Attributes */
11060         CHECK_BYTE_COUNT_SUBR(4);
11061         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
11062         *bcp -= 4;
11063
11064         /* file name len */
11065         CHECK_BYTE_COUNT_SUBR(4);
11066         fn_len = tvb_get_letohl(tvb, offset);
11067         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11068         COUNT_BYTES_SUBR(4);
11069
11070         /* ea size */
11071         CHECK_BYTE_COUNT_SUBR(4);
11072         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11073         COUNT_BYTES_SUBR(4);
11074
11075         /* short file name len */
11076         CHECK_BYTE_COUNT_SUBR(1);
11077         sfn_len = tvb_get_guint8(tvb, offset);
11078         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11079         COUNT_BYTES_SUBR(1);
11080
11081         /* reserved byte */
11082         CHECK_BYTE_COUNT_SUBR(1);
11083         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11084         COUNT_BYTES_SUBR(1);
11085  
11086         /* short file name */
11087         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
11088         CHECK_STRING_SUBR(sfn);
11089         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11090                 sfn);
11091         COUNT_BYTES_SUBR(24);
11092
11093         /* file name */
11094         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11095         CHECK_STRING_SUBR(fn);
11096         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11097                 fn);
11098         COUNT_BYTES_SUBR(fn_len);
11099
11100         if (check_col(pinfo->cinfo, COL_INFO)) {
11101                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11102                 fn);
11103         }
11104
11105         /* skip to next structure */
11106         if(neo){
11107                 padcnt = (old_offset + neo) - offset;
11108                 if (padcnt < 0) {
11109                         /*
11110                          * XXX - this is bogus; flag it?
11111                          */
11112                         padcnt = 0;
11113                 }
11114                 if (padcnt != 0) {
11115                         CHECK_BYTE_COUNT_SUBR(padcnt);
11116                         COUNT_BYTES_SUBR(padcnt);
11117                 }
11118         }
11119
11120         proto_item_append_text(item, " File: %s", fn);
11121         proto_item_set_len(item, offset-old_offset);
11122
11123         *trunc = FALSE;
11124         return offset;
11125 }
11126
11127 static int
11128 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11129     int offset, guint16 *bcp, gboolean *trunc)
11130 {
11131         int fn_len;
11132         const char *fn;
11133         int old_offset = offset;
11134         proto_item *item = NULL;
11135         proto_tree *tree = NULL;
11136         smb_info_t *si;
11137         guint32 neo;
11138         int padcnt;
11139
11140         si = (smb_info_t *)pinfo->private_data;
11141
11142         if(parent_tree){
11143                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11144                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11145                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11146         }
11147  
11148         /* next entry offset */
11149         CHECK_BYTE_COUNT_SUBR(4);
11150         neo = tvb_get_letohl(tvb, offset);
11151         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11152         COUNT_BYTES_SUBR(4);
11153         
11154         /* file index */
11155         CHECK_BYTE_COUNT_SUBR(4);
11156         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11157         COUNT_BYTES_SUBR(4);
11158
11159         /* file name len */
11160         CHECK_BYTE_COUNT_SUBR(4);
11161         fn_len = tvb_get_letohl(tvb, offset);
11162         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11163         COUNT_BYTES_SUBR(4);
11164
11165         /* file name */
11166         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11167         CHECK_STRING_SUBR(fn);
11168         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11169                 fn);
11170         COUNT_BYTES_SUBR(fn_len);
11171
11172         if (check_col(pinfo->cinfo, COL_INFO)) {
11173                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11174                 fn);
11175         }
11176
11177         /* skip to next structure */
11178         if(neo){
11179                 padcnt = (old_offset + neo) - offset;
11180                 if (padcnt < 0) {
11181                         /*
11182                          * XXX - this is bogus; flag it?
11183                          */
11184                         padcnt = 0;
11185                 }
11186                 if (padcnt != 0) {
11187                         CHECK_BYTE_COUNT_SUBR(padcnt);
11188                         COUNT_BYTES_SUBR(padcnt);
11189                 }
11190         }
11191
11192         proto_item_append_text(item, " File: %s", fn);
11193         proto_item_set_len(item, offset-old_offset);
11194
11195         *trunc = FALSE;
11196         return offset;
11197 }
11198  
11199 static int
11200 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11201     int offset, guint16 *bcp, gboolean *trunc)
11202 {
11203 /*XXX im lazy. i havnt implemented this */
11204         offset += *bcp;
11205         *bcp = 0;
11206         *trunc = FALSE;
11207         return offset;
11208 }
11209
11210 /*dissect the data block for TRANS2_FIND_FIRST2*/
11211 static int
11212 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
11213     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
11214 {
11215         smb_info_t *si;
11216
11217         if(!*bcp){
11218                 return offset;
11219         }
11220         
11221         si = (smb_info_t *)pinfo->private_data;
11222         switch(si->info_level){
11223         case 1:         /*Info Standard*/
11224                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
11225                     trunc);
11226                 break;
11227         case 2:         /*Info Query EA Size*/
11228                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11229                     trunc);
11230                 break;
11231         case 3:         /*Info Query EAs From List same as 
11232                                 InfoQueryEASize*/
11233                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11234                     trunc);
11235                 break;
11236         case 0x0101:    /*Find File Directory Info*/
11237                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
11238                     trunc);
11239                 break;
11240         case 0x0102:    /*Find File Full Directory Info*/
11241                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
11242                     trunc);
11243                 break;
11244         case 0x0103:    /*Find File Names Info*/
11245                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
11246                     trunc);
11247                 break;
11248         case 0x0104:    /*Find File Both Directory Info*/
11249                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
11250                     trunc);
11251                 break;
11252         case 0x0202:    /*Find File UNIX*/
11253                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
11254                     trunc);
11255                 break;
11256         default:        /* unknown info level */
11257                 *trunc = FALSE;
11258                 break;
11259         }
11260         return offset;
11261 }
11262
11263
11264 static int
11265 dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11266 {
11267         guint32 mask;
11268         proto_item *item = NULL;
11269         proto_tree *tree = NULL;
11270
11271         mask = tvb_get_letohl(tvb, offset);
11272
11273         if(parent_tree){
11274                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11275                         "FS Attributes: 0x%08x", mask);
11276                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
11277         }
11278
11279         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
11280                 tvb, offset, 4, mask);
11281         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
11282                 tvb, offset, 4, mask);
11283         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
11284                 tvb, offset, 4, mask);
11285         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
11286                 tvb, offset, 4, mask);
11287         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
11288                 tvb, offset, 4, mask);
11289         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
11290                 tvb, offset, 4, mask);
11291         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
11292                 tvb, offset, 4, mask);
11293
11294         offset += 4;
11295         return offset;
11296 }
11297  
11298
11299 static int
11300 dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11301 {
11302         guint32 mask;
11303         proto_item *item = NULL;
11304         proto_tree *tree = NULL;
11305
11306         mask = tvb_get_letohl(tvb, offset);
11307
11308         if(parent_tree){
11309                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11310                         "Device Characteristics: 0x%08x", mask);
11311                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
11312         }
11313
11314         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
11315                 tvb, offset, 4, mask);
11316         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
11317                 tvb, offset, 4, mask);
11318         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
11319                 tvb, offset, 4, mask);
11320         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
11321                 tvb, offset, 4, mask);
11322         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
11323                 tvb, offset, 4, mask);
11324         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
11325                 tvb, offset, 4, mask);
11326         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
11327                 tvb, offset, 4, mask);
11328
11329         offset += 4;
11330         return offset;
11331 }
11332
11333 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
11334 static int
11335 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11336     int offset, guint16 *bcp)
11337 {
11338         smb_info_t *si;
11339         int fn_len, vll, fnl;
11340         const char *fn;
11341
11342         if(!*bcp){
11343                 return offset;
11344         }
11345         
11346         si = (smb_info_t *)pinfo->private_data;
11347         switch(si->info_level){
11348         case 1:         /* SMB_INFO_ALLOCATION */
11349                 /* filesystem id */
11350                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11351                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
11352                 COUNT_BYTES_TRANS_SUBR(4);
11353
11354                 /* sectors per unit */
11355                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11356                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11357                 COUNT_BYTES_TRANS_SUBR(4);
11358
11359                 /* units */
11360                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11361                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
11362                 COUNT_BYTES_TRANS_SUBR(4);
11363
11364                 /* avail units */
11365                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11366                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
11367                 COUNT_BYTES_TRANS_SUBR(4);
11368
11369                 /* bytes per sector, only 16bit integer here */
11370                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11371                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11372                 COUNT_BYTES_TRANS_SUBR(2);
11373
11374                 break;
11375         case 2:         /* SMB_INFO_VOLUME */
11376                 /* volume serial number */
11377                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11378                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11379                 COUNT_BYTES_TRANS_SUBR(4);
11380
11381                 /* volume label length, only one byte here */
11382                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
11383                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11384                 COUNT_BYTES_TRANS_SUBR(1);
11385
11386                 /* label */
11387                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
11388                 CHECK_STRING_TRANS_SUBR(fn);
11389                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11390                         fn);
11391                 COUNT_BYTES_TRANS_SUBR(fn_len);
11392
11393                 break;
11394         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
11395                 /* create time */
11396                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11397                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11398                         hf_smb_create_time);
11399                 *bcp -= 8;
11400         
11401                 /* volume serial number */
11402                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11403                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11404                 COUNT_BYTES_TRANS_SUBR(4);
11405
11406                 /* volume label length */
11407                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11408                 vll = tvb_get_letohl(tvb, offset);
11409                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
11410                 COUNT_BYTES_TRANS_SUBR(4);
11411
11412                 /* 2 reserved bytes */
11413                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11414                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11415                 COUNT_BYTES_TRANS_SUBR(2);
11416
11417                 /* label */
11418                 fn_len = vll;
11419                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11420                 CHECK_STRING_TRANS_SUBR(fn);
11421                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11422                         fn);
11423                 COUNT_BYTES_TRANS_SUBR(fn_len);
11424
11425                 break;
11426         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
11427                 /* allocation size */
11428                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11429                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11430                 COUNT_BYTES_TRANS_SUBR(8);
11431
11432                 /* free allocation units */
11433                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11434                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
11435                 COUNT_BYTES_TRANS_SUBR(8);
11436
11437                 /* sectors per unit */
11438                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11439                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11440                 COUNT_BYTES_TRANS_SUBR(4);
11441
11442                 /* bytes per sector */
11443                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11444                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
11445                 COUNT_BYTES_TRANS_SUBR(4);
11446
11447                 break;
11448         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
11449                 /* device type */
11450                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11451                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
11452                 COUNT_BYTES_TRANS_SUBR(4);
11453  
11454                 /* device characteristics */
11455                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11456                 offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
11457                 *bcp -= 4;
11458         
11459                 break;
11460         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
11461                 /* FS attributes */
11462                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11463                 offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
11464                 *bcp -= 4;
11465         
11466                 /* max name len */
11467                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11468                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
11469                 COUNT_BYTES_TRANS_SUBR(4);
11470
11471                 /* fs name length */
11472                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11473                 fnl = tvb_get_letohl(tvb, offset);
11474                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
11475                 COUNT_BYTES_TRANS_SUBR(4);
11476
11477                 /* label */
11478                 fn_len = fnl;
11479                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11480                 CHECK_STRING_TRANS_SUBR(fn);
11481                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
11482                         fn);
11483                 COUNT_BYTES_TRANS_SUBR(fn_len);
11484
11485                 break;
11486         case 1006:      /* QUERY_FS_QUOTA_INFO */
11487                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, bcp);
11488         }
11489  
11490         return offset;
11491 }
11492  
11493 static int
11494 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
11495     proto_tree *parent_tree)
11496 {
11497         proto_item *item = NULL;
11498         proto_tree *tree = NULL;
11499         smb_info_t *si;
11500         smb_transact2_info_t *t2i;
11501         int count;
11502         gboolean trunc;
11503         int offset = 0;
11504         guint16 dc;
11505
11506         dc = tvb_reported_length(tvb);
11507
11508         si = (smb_info_t *)pinfo->private_data;
11509         if (si->sip != NULL)
11510                 t2i = si->sip->extra_info;
11511         else
11512                 t2i = NULL;
11513
11514         if(parent_tree){
11515                 if (t2i != NULL && t2i->subcmd != -1) {
11516                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11517                                 "%s Data",
11518                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11519                                         "Unknown (0x%02x)"));
11520                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11521                 } else {
11522                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11523                                 "Unknown Transaction2 Data");
11524                 }
11525         }
11526
11527         if (t2i == NULL) {
11528                 offset += dc;
11529                 return offset;
11530         }
11531         switch(t2i->subcmd){
11532         case 0x00:      /*TRANS2_OPEN2*/
11533                 /* XXX not implemented yet. See SNIA doc */
11534                 break;
11535         case 0x01:      /*TRANS2_FIND_FIRST2*/
11536                 /* returned data */
11537                 count = si->info_count;
11538
11539                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11540                         col_append_fstr(pinfo->cinfo, COL_INFO,
11541                         ", Files:");
11542                 }
11543
11544                 while(count--){
11545                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11546                                 offset, &dc, &trunc);
11547                         if (trunc)
11548                                 break;
11549                 }
11550                 break;
11551         case 0x02:      /*TRANS2_FIND_NEXT2*/
11552                 /* returned data */
11553                 count = si->info_count;
11554
11555                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11556                         col_append_fstr(pinfo->cinfo, COL_INFO,
11557                         ", Files:");
11558                 }
11559
11560                 while(count--){
11561                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11562                                 offset, &dc, &trunc);
11563                         if (trunc)
11564                                 break;
11565                 }
11566                 break;
11567         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11568                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
11569                 break;
11570         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11571                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11572                 break;
11573         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11574                 /* no data in this response */
11575                 break;
11576         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11577                 /* identical to QUERY_PATH_INFO */
11578                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11579                 break;
11580         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11581                 /* no data in this response */
11582                 break;
11583         case 0x09:      /*TRANS2_FSCTL*/
11584                 /* XXX dont know how to dissect this one (yet)*/
11585                 break;
11586         case 0x0a:      /*TRANS2_IOCTL2*/
11587                 /* XXX dont know how to dissect this one (yet)*/
11588                 break;
11589         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11590                 /* XXX dont know how to dissect this one (yet)*/
11591                 break;
11592         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11593                 /* XXX dont know how to dissect this one (yet)*/
11594                 break;
11595         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11596                 /* no data in this response */
11597                 break;
11598         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11599                 /* XXX dont know how to dissect this one (yet)*/
11600                 break;
11601         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11602                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
11603                 break;
11604         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11605                 /* the SNIA spec appears to say the response has no data */
11606                 break;
11607         case -1:
11608                 /*
11609                  * We don't know what the matching request was; don't
11610                  * bother putting anything else into the tree for the data.
11611                  */
11612                 offset += dc;
11613                 dc = 0;
11614                 break;
11615         }
11616
11617         /* ooops there were data we didnt know how to process */
11618         if(dc != 0){
11619                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11620                 offset += dc;
11621         }
11622
11623         return offset;
11624 }
11625
11626
11627 static void
11628 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
11629 {
11630         proto_item *item = NULL;
11631         proto_tree *tree = NULL;
11632         smb_info_t *si;
11633         smb_transact2_info_t *t2i;
11634         guint16 fid;
11635         int lno;
11636         int offset = 0;
11637         int pc;
11638
11639         pc = tvb_reported_length(tvb);
11640
11641         si = (smb_info_t *)pinfo->private_data;
11642         if (si->sip != NULL)
11643                 t2i = si->sip->extra_info;
11644         else
11645                 t2i = NULL;
11646
11647         if(parent_tree){
11648                 if (t2i != NULL && t2i->subcmd != -1) {
11649                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11650                                 "%s Parameters",
11651                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11652                                                 "Unknown (0x%02x)"));
11653                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
11654                 } else {
11655                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11656                                 "Unknown Transaction2 Parameters");
11657                 }
11658         }
11659
11660         if (t2i == NULL) {
11661                 offset += pc;
11662                 return;
11663         }
11664         switch(t2i->subcmd){
11665         case 0x00:      /*TRANS2_OPEN2*/
11666                 /* fid */
11667                 fid = tvb_get_letohs(tvb, offset);
11668                 add_fid(tvb, pinfo, tree, offset, 2, fid);
11669                 offset += 2;
11670
11671                 /* File Attributes */
11672                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
11673
11674                 /* create time */
11675                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
11676                         hf_smb_create_time, 
11677                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
11678
11679                 /* data size */
11680                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11681                 offset += 4;
11682
11683                 /* granted access */
11684                 offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
11685
11686                 /* File Type */
11687                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
11688                 offset += 2;
11689
11690                 /* IPC State */
11691                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
11692
11693                 /* open_action */
11694                 offset = dissect_open_action(tvb, pinfo, tree, offset);
11695
11696                 /* 4 reserved bytes */
11697                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
11698                 offset += 4;
11699
11700                 /* ea error offset, only a 16 bit integer here */
11701                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11702                 offset += 2;
11703
11704                 /* ea length */
11705                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
11706                 offset += 4;
11707
11708                 break;
11709         case 0x01:      /*TRANS2_FIND_FIRST2*/
11710                 /* Find First2 information level */
11711                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
11712
11713                 /* sid */
11714                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
11715                 offset += 2;
11716
11717                 /* search count */
11718                 si->info_count = tvb_get_letohs(tvb, offset);
11719                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11720                 offset += 2;
11721
11722                 /* end of search */
11723                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11724                 offset += 2;
11725
11726                 /* ea error offset, only a 16 bit integer here */
11727                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11728                 offset += 2;
11729
11730                 /* last name offset */
11731                 lno = tvb_get_letohs(tvb, offset);
11732                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11733                 offset += 2;
11734
11735                 break;
11736         case 0x02:      /*TRANS2_FIND_NEXT2*/
11737                 /* search count */
11738                 si->info_count = tvb_get_letohs(tvb, offset);
11739                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11740                 offset += 2;
11741
11742                 /* end of search */
11743                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11744                 offset += 2;
11745
11746                 /* ea error offset , only a 16 bit integer here*/
11747                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11748                 offset += 2;
11749
11750                 /* last name offset */
11751                 lno = tvb_get_letohs(tvb, offset);
11752                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11753                 offset += 2;
11754
11755                 break;
11756         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11757                 /* no parameter block here */
11758                 break;
11759         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11760                 /* no parameter block here */
11761                 break;
11762         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11763                 /* no parameter block here */
11764                 break;
11765         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11766                 /* no parameter block here */
11767                 break;
11768         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11769                 /* no parameter block here */
11770                 break;
11771         case 0x09:      /*TRANS2_FSCTL*/
11772                 /* XXX dont know how to dissect this one (yet)*/
11773                 break;
11774         case 0x0a:      /*TRANS2_IOCTL2*/
11775                 /* XXX dont know how to dissect this one (yet)*/
11776                 break;
11777         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11778                 /* XXX dont know how to dissect this one (yet)*/
11779                 break;
11780         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11781                 /* XXX dont know how to dissect this one (yet)*/
11782                 break;
11783         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11784                 /* ea error offset, only a 16 bit integer here */
11785                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11786                 offset += 2;
11787
11788                 break;
11789         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11790                 /* XXX dont know how to dissect this one (yet)*/
11791                 break;
11792         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11793                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11794                 break;
11795         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11796                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11797                 break;
11798         case -1:
11799                 /*
11800                  * We don't know what the matching request was; don't
11801                  * bother putting anything else into the tree for the data.
11802                  */
11803                 offset += pc;
11804                 break;
11805         }
11806
11807         /* ooops there were data we didnt know how to process */
11808         if(offset<pc){
11809                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
11810                 offset += pc-offset;
11811         }
11812 }
11813
11814
11815 static int
11816 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
11817 {
11818         guint8 sc, wc;
11819         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
11820         gboolean reassembled = FALSE;
11821         smb_info_t *si;
11822         smb_transact2_info_t *t2i = NULL;
11823         guint16 bc;
11824         int padcnt;
11825         gboolean dissected_trans;
11826         fragment_data *r_fd = NULL;
11827         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
11828         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
11829         gboolean save_fragmented;
11830
11831         si = (smb_info_t *)pinfo->private_data;
11832
11833         switch(si->cmd){
11834         case SMB_COM_TRANSACTION2:
11835                 /* transaction2 */
11836                 if (si->sip != NULL) {
11837                         t2i = si->sip->extra_info;
11838                 } else
11839                         t2i = NULL;
11840                 if (t2i == NULL) {
11841                         /*
11842                          * We didn't see the matching request, so we don't
11843                          * know what type of transaction this is.
11844                          */
11845                         proto_tree_add_text(tree, tvb, 0, 0,
11846                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
11847                         if (check_col(pinfo->cinfo, COL_INFO)) {
11848                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11849                         }
11850                 } else {
11851                         si->info_level = t2i->info_level;
11852                         if (t2i->subcmd == -1) {
11853                                 /*
11854                                  * We didn't manage to extract the subcommand
11855                                  * from the matching request (perhaps because
11856                                  * the frame was short), so we don't know what
11857                                  * type of transaction this is.
11858                                  */
11859                                 proto_tree_add_text(tree, tvb, 0, 0,
11860                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
11861                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11862                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11863                                 }
11864                         } else {
11865                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
11866                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11867                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11868                                                 val_to_str(t2i->subcmd,
11869                                                         trans2_cmd_vals, 
11870                                                         "<unknown (0x%02x)>"));
11871                                 }
11872                         }
11873                 }
11874                 break;
11875         }
11876
11877         WORD_COUNT;
11878
11879         /* total param count, only a 16bit integer here */
11880         tp = tvb_get_letohs(tvb, offset);
11881         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
11882         offset += 2;
11883
11884         /* total data count, only a 16 bit integer here */
11885         td = tvb_get_letohs(tvb, offset);
11886         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
11887         offset += 2;
11888
11889         /* 2 reserved bytes */
11890         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11891         offset += 2;
11892
11893         /* param count */
11894         pc = tvb_get_letohs(tvb, offset);
11895         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11896         offset += 2;
11897
11898         /* param offset */
11899         po = tvb_get_letohs(tvb, offset);
11900         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11901         offset += 2;
11902
11903         /* param disp */
11904         pd = tvb_get_letohs(tvb, offset);
11905         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11906         offset += 2;
11907
11908         /* data count */
11909         dc = tvb_get_letohs(tvb, offset);
11910         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11911         offset += 2;
11912
11913         /* data offset */
11914         od = tvb_get_letohs(tvb, offset);
11915         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11916         offset += 2;
11917
11918         /* data disp */
11919         dd = tvb_get_letohs(tvb, offset);
11920         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11921         offset += 2;
11922
11923         /* setup count */
11924         sc = tvb_get_guint8(tvb, offset);
11925         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11926         offset += 1;
11927
11928         /* reserved byte */
11929         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11930         offset += 1;
11931
11932
11933         /* if there were any setup bytes, put them in a tvb for later */
11934         if(sc){
11935                 if((2*sc)>tvb_length_remaining(tvb, offset)){
11936                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
11937                 } else {
11938                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
11939                 }
11940                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
11941         } else {
11942                 s_tvb = NULL;
11943                 sp_tvb=NULL;
11944         }
11945         offset += 2*sc;
11946
11947
11948         BYTE_COUNT;
11949
11950
11951         /* reassembly of SMB Transaction data payload.
11952            In this section we do reassembly of both the data and parameters
11953            blocks of the SMB transaction command.
11954         */
11955         save_fragmented = pinfo->fragmented;
11956         /* do we need reassembly? */
11957         if( (td!=dc) || (tp!=pc) ){
11958                 /* oh yeah, either data or parameter section needs 
11959                    reassembly
11960                 */
11961                 pinfo->fragmented = TRUE;
11962                 if(smb_trans_reassembly){
11963                         /* ...and we were told to do reassembly */
11964                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
11965                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11966                                                              po, pc, pd, td+tp);
11967                                 
11968                         }
11969                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
11970                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11971                                                              od, dc, dd+tp, td+tp);
11972                         }
11973                 }
11974         }
11975
11976         /* if we got a reassembled fd structure from the reassembly routine we must
11977            create pd_tvb from it 
11978         */
11979         if(r_fd){
11980                 proto_tree *tr;
11981                 proto_item *it;
11982                 fragment_data *fd;
11983
11984                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
11985                                              r_fd->datalen);
11986                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
11987                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
11988                 pinfo->fragmented = FALSE;
11989
11990                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
11991                 tr = proto_item_add_subtree(it, ett_smb_segments);
11992                 for(fd=r_fd->next;fd;fd=fd->next){
11993                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
11994                                             "Frame:%u Data:%u-%u",
11995                                             fd->frame, fd->offset,
11996                                             fd->offset+fd->len-1);
11997                 }
11998         }
11999
12000
12001         if(pd_tvb){
12002                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
12003                 if(tp){
12004                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
12005                 }
12006                 if(td){
12007                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
12008                 }
12009         } else {
12010                 /* It was not reassembled. Do as best as we can.
12011                  * in this case we always try to dissect the stuff if 
12012                  * data and param displacement is 0. i.e. for the first
12013                  * (and maybe only) packet.
12014                  */
12015                 if( (pd==0) && (dd==0) ){
12016                         int min;
12017                         int reported_min;
12018                         min = MIN(pc,tvb_length_remaining(tvb,po));
12019                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
12020                         if(min && reported_min) {
12021                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
12022                         }
12023                         min = MIN(dc,tvb_length_remaining(tvb,od));
12024                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
12025                         if(min && reported_min) {
12026                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
12027                         }
12028                         /*
12029                          * A tvbuff containing the parameters
12030                          * and the data.
12031                          * XXX - check pc and dc as well?
12032                          */
12033                         if (tvb_length_remaining(tvb, po)){
12034                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12035                         }
12036                 }
12037         }
12038
12039
12040
12041         /* parameters */
12042         if(po>offset){
12043                 /* We have some padding bytes.
12044                 */
12045                 padcnt = po-offset;
12046                 if (padcnt > bc)
12047                         padcnt = bc;
12048                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12049                 COUNT_BYTES(padcnt);
12050         }
12051         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
12052                 /* TRANSACTION2 parameters*/
12053                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
12054         }
12055         COUNT_BYTES(pc);
12056
12057
12058         /* data */
12059         if(od>offset){
12060                 /* We have some initial padding bytes.
12061                 */
12062                 padcnt = od-offset;
12063                 if (padcnt > bc)
12064                         padcnt = bc;
12065                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12066                 COUNT_BYTES(padcnt);
12067         }
12068         /*
12069          * If the data count is bigger than the count of bytes
12070          * remaining, clamp it so that the count of bytes remaining
12071          * doesn't go negative.
12072          */
12073         if (dc > bc)
12074                 dc = bc;
12075         COUNT_BYTES(dc);
12076
12077
12078
12079         /* from now on, everything is in separate tvbuffs so we dont count
12080            the bytes with COUNT_BYTES any more.
12081            neither do we reference offset any more (which by now points to the
12082            first byte AFTER this PDU */
12083
12084
12085         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
12086                 /* TRANSACTION2 parameters*/
12087                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
12088         }
12089
12090
12091         if(si->cmd==SMB_COM_TRANSACTION){
12092                 smb_transact_info_t *tri;
12093
12094                 dissected_trans = FALSE;
12095                 if (si->sip != NULL)
12096                         tri = si->sip->extra_info;
12097                 else
12098                         tri = NULL;
12099                 if (tri != NULL) {
12100                         switch(tri->subcmd){
12101
12102                         case TRANSACTION_PIPE:
12103                                 /* This function is safe to call for 
12104                                    s_tvb==sp_tvb==NULL, i.e. if we don't
12105                                    know them at this point.
12106                                    It's also safe to call if "p_tvb"
12107                                    or "d_tvb" are null.
12108                                 */
12109                                 if( pd_tvb) {
12110                                         dissected_trans = dissect_pipe_smb(
12111                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
12112                                                 d_tvb, NULL, pinfo, top_tree);
12113                                 }
12114                                 break;
12115                                 
12116                         case TRANSACTION_MAILSLOT:
12117                                 /* This one should be safe to call
12118                                    even if s_tvb and sp_tvb is NULL
12119                                 */
12120                                 if(d_tvb){
12121                                         dissected_trans = dissect_mailslot_smb(
12122                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
12123                                                 top_tree);
12124                                 }
12125                                 break;
12126                         }
12127                 }
12128                 if (!dissected_trans) {
12129                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
12130                         dissect_trans_data(s_tvb, p_tvb, d_tvb,
12131                                            pinfo, tree);
12132                 }
12133         }
12134
12135
12136         if( (p_tvb==0) && (d_tvb==0) ){
12137                 if(check_col(pinfo->cinfo, COL_INFO)){
12138                         col_append_str(pinfo->cinfo, COL_INFO,
12139                                        "[transact continuation]");
12140                 }
12141         }
12142
12143         pinfo->fragmented = save_fragmented;
12144         END_OF_SMB
12145
12146         return offset;
12147 }
12148
12149
12150 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12151    END Transaction/Transaction2 Primary and secondary requests
12152    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12153
12154
12155 static int
12156 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
12157 {
12158         guint8 wc;
12159         guint16 bc;
12160
12161         WORD_COUNT;
12162  
12163         if (wc != 0)
12164                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
12165
12166         BYTE_COUNT;
12167
12168         if (bc != 0)
12169                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
12170
12171         END_OF_SMB
12172
12173         return offset;
12174 }
12175
12176 typedef struct _smb_function {
12177        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12178        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12179 } smb_function;
12180
12181 static smb_function smb_dissector[256] = {
12182   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
12183   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
12184   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
12185   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
12186   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
12187   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
12188   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
12189   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
12190   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
12191   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
12192   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
12193   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
12194   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
12195   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
12196   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
12197   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
12198
12199   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
12200   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
12201   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
12202   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
12203   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
12204   /* 0x15 */  {dissect_unknown, dissect_unknown},
12205   /* 0x16 */  {dissect_unknown, dissect_unknown},
12206   /* 0x17 */  {dissect_unknown, dissect_unknown},
12207   /* 0x18 */  {dissect_unknown, dissect_unknown},
12208   /* 0x19 */  {dissect_unknown, dissect_unknown},
12209   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
12210   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
12211   /* 0x1c */  {dissect_unknown, dissect_unknown},
12212   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
12213   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
12214   /* 0x1f */  {dissect_unknown, dissect_unknown},
12215
12216   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
12217   /* 0x21 */  {dissect_unknown, dissect_unknown},
12218   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
12219   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
12220   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
12221   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
12222   /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12223   /* 0x27 */  {dissect_unknown, dissect_unknown},
12224   /* 0x28 */  {dissect_unknown, dissect_unknown},
12225   /* 0x29 */  {dissect_unknown, dissect_unknown},
12226   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
12227   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
12228   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
12229   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
12230   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
12231   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
12232
12233   /* 0x30 */  {dissect_unknown, dissect_unknown},
12234   /* 0x31 */  {dissect_unknown, dissect_unknown},
12235   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
12236   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12237   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
12238   /* 0x35 */  {dissect_unknown, dissect_unknown},
12239   /* 0x36 */  {dissect_unknown, dissect_unknown},
12240   /* 0x37 */  {dissect_unknown, dissect_unknown},
12241   /* 0x38 */  {dissect_unknown, dissect_unknown},
12242   /* 0x39 */  {dissect_unknown, dissect_unknown},
12243   /* 0x3a */  {dissect_unknown, dissect_unknown},
12244   /* 0x3b */  {dissect_unknown, dissect_unknown},
12245   /* 0x3c */  {dissect_unknown, dissect_unknown},
12246   /* 0x3d */  {dissect_unknown, dissect_unknown},
12247   /* 0x3e */  {dissect_unknown, dissect_unknown},
12248   /* 0x3f */  {dissect_unknown, dissect_unknown},
12249
12250   /* 0x40 */  {dissect_unknown, dissect_unknown},
12251   /* 0x41 */  {dissect_unknown, dissect_unknown},
12252   /* 0x42 */  {dissect_unknown, dissect_unknown},
12253   /* 0x43 */  {dissect_unknown, dissect_unknown},
12254   /* 0x44 */  {dissect_unknown, dissect_unknown},
12255   /* 0x45 */  {dissect_unknown, dissect_unknown},
12256   /* 0x46 */  {dissect_unknown, dissect_unknown},
12257   /* 0x47 */  {dissect_unknown, dissect_unknown},
12258   /* 0x48 */  {dissect_unknown, dissect_unknown},
12259   /* 0x49 */  {dissect_unknown, dissect_unknown},
12260   /* 0x4a */  {dissect_unknown, dissect_unknown},
12261   /* 0x4b */  {dissect_unknown, dissect_unknown},
12262   /* 0x4c */  {dissect_unknown, dissect_unknown},
12263   /* 0x4d */  {dissect_unknown, dissect_unknown},
12264   /* 0x4e */  {dissect_unknown, dissect_unknown},
12265   /* 0x4f */  {dissect_unknown, dissect_unknown},
12266
12267   /* 0x50 */  {dissect_unknown, dissect_unknown},
12268   /* 0x51 */  {dissect_unknown, dissect_unknown},
12269   /* 0x52 */  {dissect_unknown, dissect_unknown},
12270   /* 0x53 */  {dissect_unknown, dissect_unknown},
12271   /* 0x54 */  {dissect_unknown, dissect_unknown},
12272   /* 0x55 */  {dissect_unknown, dissect_unknown},
12273   /* 0x56 */  {dissect_unknown, dissect_unknown},
12274   /* 0x57 */  {dissect_unknown, dissect_unknown},
12275   /* 0x58 */  {dissect_unknown, dissect_unknown},
12276   /* 0x59 */  {dissect_unknown, dissect_unknown},
12277   /* 0x5a */  {dissect_unknown, dissect_unknown},
12278   /* 0x5b */  {dissect_unknown, dissect_unknown},
12279   /* 0x5c */  {dissect_unknown, dissect_unknown},
12280   /* 0x5d */  {dissect_unknown, dissect_unknown},
12281   /* 0x5e */  {dissect_unknown, dissect_unknown},
12282   /* 0x5f */  {dissect_unknown, dissect_unknown},
12283
12284   /* 0x60 */  {dissect_unknown, dissect_unknown},
12285   /* 0x61 */  {dissect_unknown, dissect_unknown},
12286   /* 0x62 */  {dissect_unknown, dissect_unknown},
12287   /* 0x63 */  {dissect_unknown, dissect_unknown},
12288   /* 0x64 */  {dissect_unknown, dissect_unknown},
12289   /* 0x65 */  {dissect_unknown, dissect_unknown},
12290   /* 0x66 */  {dissect_unknown, dissect_unknown},
12291   /* 0x67 */  {dissect_unknown, dissect_unknown},
12292   /* 0x68 */  {dissect_unknown, dissect_unknown},
12293   /* 0x69 */  {dissect_unknown, dissect_unknown},
12294   /* 0x6a */  {dissect_unknown, dissect_unknown},
12295   /* 0x6b */  {dissect_unknown, dissect_unknown},
12296   /* 0x6c */  {dissect_unknown, dissect_unknown},
12297   /* 0x6d */  {dissect_unknown, dissect_unknown},
12298   /* 0x6e */  {dissect_unknown, dissect_unknown},
12299   /* 0x6f */  {dissect_unknown, dissect_unknown},
12300
12301   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
12302   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
12303   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
12304   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
12305   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
12306   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
12307   /* 0x76 */  {dissect_unknown, dissect_unknown},
12308   /* 0x77 */  {dissect_unknown, dissect_unknown},
12309   /* 0x78 */  {dissect_unknown, dissect_unknown},
12310   /* 0x79 */  {dissect_unknown, dissect_unknown},
12311   /* 0x7a */  {dissect_unknown, dissect_unknown},
12312   /* 0x7b */  {dissect_unknown, dissect_unknown},
12313   /* 0x7c */  {dissect_unknown, dissect_unknown},
12314   /* 0x7d */  {dissect_unknown, dissect_unknown},
12315   /* 0x7e */  {dissect_unknown, dissect_unknown},
12316   /* 0x7f */  {dissect_unknown, dissect_unknown},
12317
12318   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
12319   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
12320   /* 0x82 */  {dissect_unknown, dissect_unknown},
12321   /* 0x83 */  {dissect_unknown, dissect_unknown},
12322   /* 0x84 */  {dissect_unknown, dissect_unknown},
12323   /* 0x85 */  {dissect_unknown, dissect_unknown},
12324   /* 0x86 */  {dissect_unknown, dissect_unknown},
12325   /* 0x87 */  {dissect_unknown, dissect_unknown},
12326   /* 0x88 */  {dissect_unknown, dissect_unknown},
12327   /* 0x89 */  {dissect_unknown, dissect_unknown},
12328   /* 0x8a */  {dissect_unknown, dissect_unknown},
12329   /* 0x8b */  {dissect_unknown, dissect_unknown},
12330   /* 0x8c */  {dissect_unknown, dissect_unknown},
12331   /* 0x8d */  {dissect_unknown, dissect_unknown},
12332   /* 0x8e */  {dissect_unknown, dissect_unknown},
12333   /* 0x8f */  {dissect_unknown, dissect_unknown},
12334
12335   /* 0x90 */  {dissect_unknown, dissect_unknown},
12336   /* 0x91 */  {dissect_unknown, dissect_unknown},
12337   /* 0x92 */  {dissect_unknown, dissect_unknown},
12338   /* 0x93 */  {dissect_unknown, dissect_unknown},
12339   /* 0x94 */  {dissect_unknown, dissect_unknown},
12340   /* 0x95 */  {dissect_unknown, dissect_unknown},
12341   /* 0x96 */  {dissect_unknown, dissect_unknown},
12342   /* 0x97 */  {dissect_unknown, dissect_unknown},
12343   /* 0x98 */  {dissect_unknown, dissect_unknown},
12344   /* 0x99 */  {dissect_unknown, dissect_unknown},
12345   /* 0x9a */  {dissect_unknown, dissect_unknown},
12346   /* 0x9b */  {dissect_unknown, dissect_unknown},
12347   /* 0x9c */  {dissect_unknown, dissect_unknown},
12348   /* 0x9d */  {dissect_unknown, dissect_unknown},
12349   /* 0x9e */  {dissect_unknown, dissect_unknown},
12350   /* 0x9f */  {dissect_unknown, dissect_unknown},
12351   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
12352   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
12353   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
12354   /* 0xa3 */  {dissect_unknown, dissect_unknown},
12355   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
12356   /* 0xa5 */  {dissect_nt_rename_file_request, dissect_empty},
12357   /* 0xa6 */  {dissect_unknown, dissect_unknown},
12358   /* 0xa7 */  {dissect_unknown, dissect_unknown},
12359   /* 0xa8 */  {dissect_unknown, dissect_unknown},
12360   /* 0xa9 */  {dissect_unknown, dissect_unknown},
12361   /* 0xaa */  {dissect_unknown, dissect_unknown},
12362   /* 0xab */  {dissect_unknown, dissect_unknown},
12363   /* 0xac */  {dissect_unknown, dissect_unknown},
12364   /* 0xad */  {dissect_unknown, dissect_unknown},
12365   /* 0xae */  {dissect_unknown, dissect_unknown},
12366   /* 0xaf */  {dissect_unknown, dissect_unknown},
12367
12368   /* 0xb0 */  {dissect_unknown, dissect_unknown},
12369   /* 0xb1 */  {dissect_unknown, dissect_unknown},
12370   /* 0xb2 */  {dissect_unknown, dissect_unknown},
12371   /* 0xb3 */  {dissect_unknown, dissect_unknown},
12372   /* 0xb4 */  {dissect_unknown, dissect_unknown},
12373   /* 0xb5 */  {dissect_unknown, dissect_unknown},
12374   /* 0xb6 */  {dissect_unknown, dissect_unknown},
12375   /* 0xb7 */  {dissect_unknown, dissect_unknown},
12376   /* 0xb8 */  {dissect_unknown, dissect_unknown},
12377   /* 0xb9 */  {dissect_unknown, dissect_unknown},
12378   /* 0xba */  {dissect_unknown, dissect_unknown},
12379   /* 0xbb */  {dissect_unknown, dissect_unknown},
12380   /* 0xbc */  {dissect_unknown, dissect_unknown},
12381   /* 0xbd */  {dissect_unknown, dissect_unknown},
12382   /* 0xbe */  {dissect_unknown, dissect_unknown},
12383   /* 0xbf */  {dissect_unknown, dissect_unknown},
12384   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
12385   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
12386   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
12387   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
12388   /* 0xc4 */  {dissect_unknown, dissect_unknown},
12389   /* 0xc5 */  {dissect_unknown, dissect_unknown},
12390   /* 0xc6 */  {dissect_unknown, dissect_unknown},
12391   /* 0xc7 */  {dissect_unknown, dissect_unknown},
12392   /* 0xc8 */  {dissect_unknown, dissect_unknown},
12393   /* 0xc9 */  {dissect_unknown, dissect_unknown},
12394   /* 0xca */  {dissect_unknown, dissect_unknown},
12395   /* 0xcb */  {dissect_unknown, dissect_unknown},
12396   /* 0xcc */  {dissect_unknown, dissect_unknown},
12397   /* 0xcd */  {dissect_unknown, dissect_unknown},
12398   /* 0xce */  {dissect_unknown, dissect_unknown},
12399   /* 0xcf */  {dissect_unknown, dissect_unknown},
12400
12401   /* 0xd0 */  {dissect_unknown, dissect_unknown},
12402   /* 0xd1 */  {dissect_unknown, dissect_unknown},
12403   /* 0xd2 */  {dissect_unknown, dissect_unknown},
12404   /* 0xd3 */  {dissect_unknown, dissect_unknown},
12405   /* 0xd4 */  {dissect_unknown, dissect_unknown},
12406   /* 0xd5 */  {dissect_unknown, dissect_unknown},
12407   /* 0xd6 */  {dissect_unknown, dissect_unknown},
12408   /* 0xd7 */  {dissect_unknown, dissect_unknown},
12409   /* 0xd8 */  {dissect_unknown, dissect_unknown},
12410   /* 0xd9 */  {dissect_unknown, dissect_unknown},
12411   /* 0xda */  {dissect_unknown, dissect_unknown},
12412   /* 0xdb */  {dissect_unknown, dissect_unknown},
12413   /* 0xdc */  {dissect_unknown, dissect_unknown},
12414   /* 0xdd */  {dissect_unknown, dissect_unknown},
12415   /* 0xde */  {dissect_unknown, dissect_unknown},
12416   /* 0xdf */  {dissect_unknown, dissect_unknown},
12417
12418   /* 0xe0 */  {dissect_unknown, dissect_unknown},
12419   /* 0xe1 */  {dissect_unknown, dissect_unknown},
12420   /* 0xe2 */  {dissect_unknown, dissect_unknown},
12421   /* 0xe3 */  {dissect_unknown, dissect_unknown},
12422   /* 0xe4 */  {dissect_unknown, dissect_unknown},
12423   /* 0xe5 */  {dissect_unknown, dissect_unknown},
12424   /* 0xe6 */  {dissect_unknown, dissect_unknown},
12425   /* 0xe7 */  {dissect_unknown, dissect_unknown},
12426   /* 0xe8 */  {dissect_unknown, dissect_unknown},
12427   /* 0xe9 */  {dissect_unknown, dissect_unknown},
12428   /* 0xea */  {dissect_unknown, dissect_unknown},
12429   /* 0xeb */  {dissect_unknown, dissect_unknown},
12430   /* 0xec */  {dissect_unknown, dissect_unknown},
12431   /* 0xed */  {dissect_unknown, dissect_unknown},
12432   /* 0xee */  {dissect_unknown, dissect_unknown},
12433   /* 0xef */  {dissect_unknown, dissect_unknown},
12434
12435   /* 0xf0 */  {dissect_unknown, dissect_unknown},
12436   /* 0xf1 */  {dissect_unknown, dissect_unknown},
12437   /* 0xf2 */  {dissect_unknown, dissect_unknown},
12438   /* 0xf3 */  {dissect_unknown, dissect_unknown},
12439   /* 0xf4 */  {dissect_unknown, dissect_unknown},
12440   /* 0xf5 */  {dissect_unknown, dissect_unknown},
12441   /* 0xf6 */  {dissect_unknown, dissect_unknown},
12442   /* 0xf7 */  {dissect_unknown, dissect_unknown},
12443   /* 0xf8 */  {dissect_unknown, dissect_unknown},
12444   /* 0xf9 */  {dissect_unknown, dissect_unknown},
12445   /* 0xfa */  {dissect_unknown, dissect_unknown},
12446   /* 0xfb */  {dissect_unknown, dissect_unknown},
12447   /* 0xfc */  {dissect_unknown, dissect_unknown},
12448   /* 0xfd */  {dissect_unknown, dissect_unknown},
12449   /* 0xfe */  {dissect_unknown, dissect_unknown},
12450   /* 0xff */  {dissect_unknown, dissect_unknown},
12451 };
12452
12453 static int
12454 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
12455 {
12456         int old_offset = offset;
12457         smb_info_t *si;
12458  
12459         si = pinfo->private_data;
12460         if(cmd!=0xff){
12461                 proto_item *cmd_item;
12462                 proto_tree *cmd_tree;
12463                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12464
12465                 if (check_col(pinfo->cinfo, COL_INFO)) {
12466                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
12467                                 decode_smb_name(cmd),
12468                                 (si->request)? "Request" : "Response");
12469                 }
12470
12471                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
12472                         "%s %s (0x%02x)",
12473                         decode_smb_name(cmd), 
12474                         (si->request)?"Request":"Response",
12475                         cmd);
12476
12477                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
12478
12479                 dissector = (si->request)?
12480                         smb_dissector[cmd].request:smb_dissector[cmd].response;
12481
12482                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
12483                 proto_item_set_len(cmd_item, offset-old_offset);
12484         }
12485         return offset;
12486 }
12487
12488
12489 /* NOTE: this value_string array will also be used to access data directly by
12490  * index instead of val_to_str() since 
12491  * 1, the array will always span every value from 0x00 to 0xff and
12492  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
12493  * This means that this value_string array MUST always
12494  * 1, contain all entries 0x00 to 0xff
12495  * 2, all entries must be in order.
12496  */
12497 static const value_string smb_cmd_vals[] = {
12498   { 0x00, "Create Directory" },
12499   { 0x01, "Delete Directory" },
12500   { 0x02, "Open" },
12501   { 0x03, "Create" },
12502   { 0x04, "Close" },
12503   { 0x05, "Flush" },
12504   { 0x06, "Delete" },
12505   { 0x07, "Rename" },
12506   { 0x08, "Query Information" },
12507   { 0x09, "Set Information" },
12508   { 0x0A, "Read" },
12509   { 0x0B, "Write" },
12510   { 0x0C, "Lock Byte Range" },
12511   { 0x0D, "Unlock Byte Range" },
12512   { 0x0E, "Create Temp" },
12513   { 0x0F, "Create New" },
12514   { 0x10, "Check Directory" },
12515   { 0x11, "Process Exit" },
12516   { 0x12, "Seek" },
12517   { 0x13, "Lock And Read" },
12518   { 0x14, "Write And Unlock" },
12519   { 0x15, "unknown-0x15" },
12520   { 0x16, "unknown-0x16" },
12521   { 0x17, "unknown-0x17" },
12522   { 0x18, "unknown-0x18" },
12523   { 0x19, "unknown-0x19" },
12524   { 0x1A, "Read Raw" },
12525   { 0x1B, "Read MPX" },
12526   { 0x1C, "Read MPX Secondary" },
12527   { 0x1D, "Write Raw" },
12528   { 0x1E, "Write MPX" },
12529   { 0x1F, "SMBwriteBs" },
12530   { 0x20, "Write Complete" },
12531   { 0x21, "unknown-0x21" },
12532   { 0x22, "Set Information2" },
12533   { 0x23, "Query Information2" },
12534   { 0x24, "Locking AndX" },
12535   { 0x25, "Transaction" },
12536   { 0x26, "Transaction Secondary" },
12537   { 0x27, "IOCTL" },
12538   { 0x28, "IOCTL Secondary" },
12539   { 0x29, "Copy" },
12540   { 0x2A, "Move" },
12541   { 0x2B, "Echo" },
12542   { 0x2C, "Write And Close" },
12543   { 0x2D, "Open AndX" },
12544   { 0x2E, "Read AndX" },
12545   { 0x2F, "Write AndX" },
12546   { 0x30, "unknown-0x30" },
12547   { 0x31, "Close And Tree Discover" },
12548   { 0x32, "Transaction2" },
12549   { 0x33, "Transaction2 Secondary" },
12550   { 0x34, "Find Close2" },
12551   { 0x35, "Find Notify Close" },
12552   { 0x36, "unknown-0x36" },
12553   { 0x37, "unknown-0x37" },
12554   { 0x38, "unknown-0x38" },
12555   { 0x39, "unknown-0x39" },
12556   { 0x3A, "unknown-0x3A" },
12557   { 0x3B, "unknown-0x3B" },
12558   { 0x3C, "unknown-0x3C" },
12559   { 0x3D, "unknown-0x3D" },
12560   { 0x3E, "unknown-0x3E" },
12561   { 0x3F, "unknown-0x3F" },
12562   { 0x40, "unknown-0x40" },
12563   { 0x41, "unknown-0x41" },
12564   { 0x42, "unknown-0x42" },
12565   { 0x43, "unknown-0x43" },
12566   { 0x44, "unknown-0x44" },
12567   { 0x45, "unknown-0x45" },
12568   { 0x46, "unknown-0x46" },
12569   { 0x47, "unknown-0x47" },
12570   { 0x48, "unknown-0x48" },
12571   { 0x49, "unknown-0x49" },
12572   { 0x4A, "unknown-0x4A" },
12573   { 0x4B, "unknown-0x4B" },
12574   { 0x4C, "unknown-0x4C" },
12575   { 0x4D, "unknown-0x4D" },
12576   { 0x4E, "unknown-0x4E" },
12577   { 0x4F, "unknown-0x4F" },
12578   { 0x50, "unknown-0x50" },
12579   { 0x51, "unknown-0x51" },
12580   { 0x52, "unknown-0x52" },
12581   { 0x53, "unknown-0x53" },
12582   { 0x54, "unknown-0x54" },
12583   { 0x55, "unknown-0x55" },
12584   { 0x56, "unknown-0x56" },
12585   { 0x57, "unknown-0x57" },
12586   { 0x58, "unknown-0x58" },
12587   { 0x59, "unknown-0x59" },
12588   { 0x5A, "unknown-0x5A" },
12589   { 0x5B, "unknown-0x5B" },
12590   { 0x5C, "unknown-0x5C" },
12591   { 0x5D, "unknown-0x5D" },
12592   { 0x5E, "unknown-0x5E" },
12593   { 0x5F, "unknown-0x5F" },
12594   { 0x60, "unknown-0x60" },
12595   { 0x61, "unknown-0x61" },
12596   { 0x62, "unknown-0x62" },
12597   { 0x63, "unknown-0x63" },
12598   { 0x64, "unknown-0x64" },
12599   { 0x65, "unknown-0x65" },
12600   { 0x66, "unknown-0x66" },
12601   { 0x67, "unknown-0x67" },
12602   { 0x68, "unknown-0x68" },
12603   { 0x69, "unknown-0x69" },
12604   { 0x6A, "unknown-0x6A" },
12605   { 0x6B, "unknown-0x6B" },
12606   { 0x6C, "unknown-0x6C" },
12607   { 0x6D, "unknown-0x6D" },
12608   { 0x6E, "unknown-0x6E" },
12609   { 0x6F, "unknown-0x6F" },
12610   { 0x70, "Tree Connect" },
12611   { 0x71, "Tree Disconnect" },
12612   { 0x72, "Negotiate Protocol" },
12613   { 0x73, "Session Setup AndX" },
12614   { 0x74, "Logoff AndX" },
12615   { 0x75, "Tree Connect AndX" },
12616   { 0x76, "unknown-0x76" },
12617   { 0x77, "unknown-0x77" },
12618   { 0x78, "unknown-0x78" },
12619   { 0x79, "unknown-0x79" },
12620   { 0x7A, "unknown-0x7A" },
12621   { 0x7B, "unknown-0x7B" },
12622   { 0x7C, "unknown-0x7C" },
12623   { 0x7D, "unknown-0x7D" },
12624   { 0x7E, "unknown-0x7E" },
12625   { 0x7F, "unknown-0x7F" },
12626   { 0x80, "Query Information Disk" },
12627   { 0x81, "Search" },
12628   { 0x82, "Find" },
12629   { 0x83, "Find Unique" },
12630   { 0x84, "SMBfclose" },
12631   { 0x85, "unknown-0x85" },
12632   { 0x86, "unknown-0x86" },
12633   { 0x87, "unknown-0x87" },
12634   { 0x88, "unknown-0x88" },
12635   { 0x89, "unknown-0x89" },
12636   { 0x8A, "unknown-0x8A" },
12637   { 0x8B, "unknown-0x8B" },
12638   { 0x8C, "unknown-0x8C" },
12639   { 0x8D, "unknown-0x8D" },
12640   { 0x8E, "unknown-0x8E" },
12641   { 0x8F, "unknown-0x8F" },
12642   { 0x90, "unknown-0x90" },
12643   { 0x91, "unknown-0x91" },
12644   { 0x92, "unknown-0x92" },
12645   { 0x93, "unknown-0x93" },
12646   { 0x94, "unknown-0x94" },
12647   { 0x95, "unknown-0x95" },
12648   { 0x96, "unknown-0x96" },
12649   { 0x97, "unknown-0x97" },
12650   { 0x98, "unknown-0x98" },
12651   { 0x99, "unknown-0x99" },
12652   { 0x9A, "unknown-0x9A" },
12653   { 0x9B, "unknown-0x9B" },
12654   { 0x9C, "unknown-0x9C" },
12655   { 0x9D, "unknown-0x9D" },
12656   { 0x9E, "unknown-0x9E" },
12657   { 0x9F, "unknown-0x9F" },
12658   { 0xA0, "NT Transact" },
12659   { 0xA1, "NT Transact Secondary" },
12660   { 0xA2, "NT Create AndX" },
12661   { 0xA3, "unknown-0xA3" },
12662   { 0xA4, "NT Cancel" },
12663   { 0xA5, "NT Rename" },
12664   { 0xA6, "unknown-0xA6" },
12665   { 0xA7, "unknown-0xA7" },
12666   { 0xA8, "unknown-0xA8" },
12667   { 0xA9, "unknown-0xA9" },
12668   { 0xAA, "unknown-0xAA" },
12669   { 0xAB, "unknown-0xAB" },
12670   { 0xAC, "unknown-0xAC" },
12671   { 0xAD, "unknown-0xAD" },
12672   { 0xAE, "unknown-0xAE" },
12673   { 0xAF, "unknown-0xAF" },
12674   { 0xB0, "unknown-0xB0" },
12675   { 0xB1, "unknown-0xB1" },
12676   { 0xB2, "unknown-0xB2" },
12677   { 0xB3, "unknown-0xB3" },
12678   { 0xB4, "unknown-0xB4" },
12679   { 0xB5, "unknown-0xB5" },
12680   { 0xB6, "unknown-0xB6" },
12681   { 0xB7, "unknown-0xB7" },
12682   { 0xB8, "unknown-0xB8" },
12683   { 0xB9, "unknown-0xB9" },
12684   { 0xBA, "unknown-0xBA" },
12685   { 0xBB, "unknown-0xBB" },
12686   { 0xBC, "unknown-0xBC" },
12687   { 0xBD, "unknown-0xBD" },
12688   { 0xBE, "unknown-0xBE" },
12689   { 0xBF, "unknown-0xBF" },
12690   { 0xC0, "Open Print File" },
12691   { 0xC1, "Write Print File" },
12692   { 0xC2, "Close Print File" },
12693   { 0xC3, "Get Print Queue" },
12694   { 0xC4, "unknown-0xC4" },
12695   { 0xC5, "unknown-0xC5" },
12696   { 0xC6, "unknown-0xC6" },
12697   { 0xC7, "unknown-0xC7" },
12698   { 0xC8, "unknown-0xC8" },
12699   { 0xC9, "unknown-0xC9" },
12700   { 0xCA, "unknown-0xCA" },
12701   { 0xCB, "unknown-0xCB" },
12702   { 0xCC, "unknown-0xCC" },
12703   { 0xCD, "unknown-0xCD" },
12704   { 0xCE, "unknown-0xCE" },
12705   { 0xCF, "unknown-0xCF" },
12706   { 0xD0, "SMBsends" },
12707   { 0xD1, "SMBsendb" },
12708   { 0xD2, "SMBfwdname" },
12709   { 0xD3, "SMBcancelf" },
12710   { 0xD4, "SMBgetmac" },
12711   { 0xD5, "SMBsendstrt" },
12712   { 0xD6, "SMBsendend" },
12713   { 0xD7, "SMBsendtxt" },
12714   { 0xD8, "SMBreadbulk" },
12715   { 0xD9, "SMBwritebulk" },
12716   { 0xDA, "SMBwritebulkdata" },
12717   { 0xDB, "unknown-0xDB" },
12718   { 0xDC, "unknown-0xDC" },
12719   { 0xDD, "unknown-0xDD" },
12720   { 0xDE, "unknown-0xDE" },
12721   { 0xDF, "unknown-0xDF" },
12722   { 0xE0, "unknown-0xE0" },
12723   { 0xE1, "unknown-0xE1" },
12724   { 0xE2, "unknown-0xE2" },
12725   { 0xE3, "unknown-0xE3" },
12726   { 0xE4, "unknown-0xE4" },
12727   { 0xE5, "unknown-0xE5" },
12728   { 0xE6, "unknown-0xE6" },
12729   { 0xE7, "unknown-0xE7" },
12730   { 0xE8, "unknown-0xE8" },
12731   { 0xE9, "unknown-0xE9" },
12732   { 0xEA, "unknown-0xEA" },
12733   { 0xEB, "unknown-0xEB" },
12734   { 0xEC, "unknown-0xEC" },
12735   { 0xED, "unknown-0xED" },
12736   { 0xEE, "unknown-0xEE" },
12737   { 0xEF, "unknown-0xEF" },
12738   { 0xF0, "unknown-0xF0" },
12739   { 0xF1, "unknown-0xF1" },
12740   { 0xF2, "unknown-0xF2" },
12741   { 0xF3, "unknown-0xF3" },
12742   { 0xF4, "unknown-0xF4" },
12743   { 0xF5, "unknown-0xF5" },
12744   { 0xF6, "unknown-0xF6" },
12745   { 0xF7, "unknown-0xF7" },
12746   { 0xF8, "unknown-0xF8" },
12747   { 0xF9, "unknown-0xF9" },
12748   { 0xFA, "unknown-0xFA" },
12749   { 0xFB, "unknown-0xFB" },
12750   { 0xFC, "unknown-0xFC" },
12751   { 0xFD, "unknown-0xFD" },
12752   { 0xFE, "SMBinvalid" },
12753   { 0xFF, "unknown-0xFF" },
12754   { 0x00, NULL },
12755 };
12756
12757 static char *decode_smb_name(unsigned char cmd)
12758 {
12759   return(smb_cmd_vals[cmd].strptr);
12760 }
12761  
12762
12763
12764 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12765  * Everything TVBUFFIFIED above this line
12766  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12767
12768
12769 static void
12770 free_hash_tables(gpointer ctarg, gpointer user_data)
12771 {
12772         conv_tables_t *ct = ctarg;
12773
12774         if (ct->unmatched)
12775                 g_hash_table_destroy(ct->unmatched);
12776         if (ct->matched)
12777                 g_hash_table_destroy(ct->matched);
12778         if (ct->dcerpc_fid_to_frame)
12779                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
12780         if (ct->tid_service)
12781                 g_hash_table_destroy(ct->tid_service);
12782 }
12783
12784 static void
12785 smb_init_protocol(void)
12786 {
12787         if (smb_saved_info_key_chunk)
12788                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
12789         if (smb_saved_info_chunk)
12790                 g_mem_chunk_destroy(smb_saved_info_chunk);
12791         if (smb_nt_transact_info_chunk)
12792                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
12793         if (smb_transact2_info_chunk)
12794                 g_mem_chunk_destroy(smb_transact2_info_chunk);
12795         if (smb_transact_info_chunk)
12796                 g_mem_chunk_destroy(smb_transact_info_chunk);
12797
12798         /*
12799          * Free the hash tables attached to the conversation table
12800          * structures, and then free the list of conversation table
12801          * data structures (which doesn't free the data structures
12802          * themselves; that's done by destroying the chunk from
12803          * which they were allocated).
12804          */
12805         if (conv_tables) {
12806                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
12807                 g_slist_free(conv_tables);
12808                 conv_tables = NULL;
12809         }
12810
12811         /*
12812          * Now destroy the chunk from which the conversation table
12813          * structures were allocated.
12814          */
12815         if (conv_tables_chunk)
12816                 g_mem_chunk_destroy(conv_tables_chunk);
12817
12818         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
12819             sizeof(smb_saved_info_t),
12820             smb_saved_info_init_count * sizeof(smb_saved_info_t),
12821             G_ALLOC_ONLY);
12822         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
12823             sizeof(smb_saved_info_key_t),
12824             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
12825             G_ALLOC_ONLY);
12826         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
12827             sizeof(smb_nt_transact_info_t),
12828             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
12829             G_ALLOC_ONLY);
12830         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
12831             sizeof(smb_transact2_info_t),
12832             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
12833             G_ALLOC_ONLY);
12834         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
12835             sizeof(smb_transact_info_t),
12836             smb_transact_info_init_count * sizeof(smb_transact_info_t),
12837             G_ALLOC_ONLY);
12838         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
12839             sizeof(conv_tables_t),
12840             conv_tables_count * sizeof(conv_tables_t),
12841             G_ALLOC_ONLY);
12842 }
12843
12844 /* Max string length for displaying Unicode strings.  */
12845 #define MAX_UNICODE_STR_LEN     256
12846
12847
12848 /* Turn a little-endian Unicode '\0'-terminated string into a string we
12849    can display.
12850    XXX - for now, we just handle the ISO 8859-1 characters.
12851    If exactlen==TRUE then us_lenp contains the exact len of the string in
12852    bytes. It might not be null terminated !
12853    bc specifies the number of bytes in the byte parameters; Windows 2000,
12854    at least, appears, in some cases, to put only 1 byte of 0 at the end
12855    of a Unicode string if the byte count
12856 */
12857 static gchar *
12858 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
12859                    guint16 bc)
12860 {
12861   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12862   static gchar *cur;
12863   gchar        *p;
12864   guint16       uchar;
12865   int           len;
12866   int           us_len;
12867   int           overflow = 0;
12868
12869   if (cur == &str[0][0]) {
12870     cur = &str[1][0];
12871   } else if (cur == &str[1][0]) {  
12872     cur = &str[2][0];
12873   } else {  
12874     cur = &str[0][0];
12875   }
12876   p = cur;
12877   len = MAX_UNICODE_STR_LEN;
12878   us_len = 0;
12879   for (;;) {
12880     if (bc == 0)
12881       break;
12882     if (bc == 1) {
12883       /* XXX - explain this */
12884       if (!exactlen)
12885         us_len += 1;    /* this is a one-byte null terminator */
12886       break;
12887     }
12888     uchar = tvb_get_letohs(tvb, offset);
12889     if (uchar == 0) {
12890       us_len += 2;      /* this is a two-byte null terminator */
12891       break;
12892     }
12893     if (len > 0) {
12894       if ((uchar & 0xFF00) == 0)
12895         *p++ = uchar;   /* ISO 8859-1 */
12896       else
12897         *p++ = '?';     /* not 8859-1 */
12898       len--;
12899     } else
12900       overflow = 1;
12901     offset += 2;
12902     bc -= 2;
12903     us_len += 2;
12904     if(exactlen){
12905       if(us_len>= *us_lenp){
12906         break;
12907       }
12908     }
12909   }
12910   if (overflow) {
12911     /* Note that we're not showing the full string.  */
12912     *p++ = '.';
12913     *p++ = '.';
12914     *p++ = '.';
12915   }
12916   *p = '\0';
12917   *us_lenp = us_len;
12918   return cur;
12919 }
12920  
12921
12922 /* nopad == TRUE : Do not add any padding before this string
12923  * exactlen == TRUE : len contains the exact len of the string in bytes.
12924  * bc: pointer to variable with amount of data left in the byte parameters
12925  *   region
12926  */
12927 static const gchar *
12928 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
12929     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
12930     guint16 *bcp)
12931 {
12932   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12933   static gchar *cur;
12934   const gchar *string;
12935   int string_len;
12936   smb_info_t *si;
12937   unsigned int copylen;
12938
12939   if (*bcp == 0) {
12940     /* Not enough data in buffer */
12941     return NULL;
12942   }
12943   si = pinfo->private_data;
12944   if (si->unicode) {
12945     if ((!nopad) && (*offsetp % 2)) {
12946       /*
12947        * XXX - this should be an offset relative to the beginning of the SMB,
12948        * not an offset relative to the beginning of the frame; if the stuff
12949        * before the SMB has an odd number of bytes, an offset relative to
12950        * the beginning of the frame will give the wrong answer.
12951        */
12952       (*offsetp)++;   /* Looks like a pad byte there sometimes */
12953       (*bcp)--;
12954       if (*bcp == 0) {
12955         /* Not enough data in buffer */
12956         return NULL;
12957       }
12958     }
12959     if(exactlen){
12960       string_len = *len;
12961       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12962     } else {
12963       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12964     }
12965   } else {
12966     if(exactlen){
12967       /*
12968        * The string we return must be null-terminated.
12969        */
12970       if (cur == &str[0][0]) {
12971         cur = &str[1][0];
12972       } else if (cur == &str[1][0]) {  
12973         cur = &str[2][0];
12974       } else {  
12975         cur = &str[0][0];
12976       }
12977       copylen = *len;
12978       if (copylen > MAX_UNICODE_STR_LEN)
12979         copylen = MAX_UNICODE_STR_LEN;
12980       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
12981       cur[copylen] = '\0';
12982       if (copylen > MAX_UNICODE_STR_LEN)
12983         strcat(cur, "...");
12984       string_len = *len;
12985       string = cur;
12986     } else {
12987       string_len = tvb_strsize(tvb, *offsetp);
12988       string = tvb_get_ptr(tvb, *offsetp, string_len);
12989     }
12990   }
12991   *len = string_len;
12992   return string;
12993 }
12994
12995
12996
12997 static const value_string errcls_types[] = {
12998   { SMB_SUCCESS, "Success"},
12999   { SMB_ERRDOS, "DOS Error"},
13000   { SMB_ERRSRV, "Server Error"},
13001   { SMB_ERRHRD, "Hardware Error"},
13002   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
13003   { 0, NULL }
13004 };
13005
13006 const value_string DOS_errors[] = {
13007   {0, "Success"},
13008   {SMBE_insufficientbuffer, "Insufficient buffer"},
13009   {SMBE_badfunc, "Invalid function (or system call)"},
13010   {SMBE_badfile, "File not found (pathname error)"},
13011   {SMBE_badpath, "Directory not found"},
13012   {SMBE_nofids, "Too many open files"},
13013   {SMBE_noaccess, "Access denied"},
13014   {SMBE_badfid, "Invalid fid"},
13015   {SMBE_nomem,  "Out of memory"},
13016   {SMBE_badmem, "Invalid memory block address"},
13017   {SMBE_badenv, "Invalid environment"},
13018   {SMBE_badaccess, "Invalid open mode"},
13019   {SMBE_baddata, "Invalid data (only from ioctl call)"},
13020   {SMBE_res, "Reserved error code?"}, 
13021   {SMBE_baddrive, "Invalid drive"},
13022   {SMBE_remcd, "Attempt to delete current directory"},
13023   {SMBE_diffdevice, "Rename/move across different filesystems"},
13024   {SMBE_nofiles, "No more files found in file search"},
13025   {SMBE_badshare, "Share mode on file conflict with open mode"},
13026   {SMBE_lock, "Lock request conflicts with existing lock"},
13027   {SMBE_unsup, "Request unsupported, returned by Win 95"},
13028   {SMBE_nosuchshare, "Requested share does not exist"},
13029   {SMBE_filexists, "File in operation already exists"},
13030   {SMBE_cannotopen, "Cannot open the file specified"},
13031   {SMBE_unknownlevel, "Unknown info level"},
13032   {SMBE_invalidname, "Invalid name"},
13033   {SMBE_badpipe, "Named pipe invalid"},
13034   {SMBE_pipebusy, "All instances of pipe are busy"},
13035   {SMBE_pipeclosing, "Named pipe close in progress"},
13036   {SMBE_notconnected, "No process on other end of named pipe"},
13037   {SMBE_moredata, "More data to be returned"},
13038   {SMBE_baddirectory,  "Invalid directory name in a path."},
13039   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
13040   {SMBE_eas_nsup, "Extended attributes not supported"},
13041   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
13042   {SMBE_unknownipc, "Unknown IPC Operation"},
13043   {SMBE_noipc, "Don't support ipc"},
13044   {SMBE_alreadyexists, "File already exists"},
13045   {SMBE_unknownprinterdriver, "Unknown printer driver"},
13046   {SMBE_invalidprintername, "Invalid printer name"},
13047   {SMBE_printeralreadyexists, "Printer already exists"},
13048   {SMBE_invaliddatatype, "Invalid data type"},
13049   {SMBE_invalidenvironment, "Invalid environment"},
13050   {SMBE_printerdriverinuse, "Printer driver in use"},
13051   {SMBE_invalidparam, "Invalid parameter"},
13052   {SMBE_invalidformsize, "Invalid form size"},
13053   {0, NULL}
13054   };
13055
13056 /* Error codes for the ERRSRV class */
13057
13058 static const value_string SRV_errors[] = {
13059   {SMBE_error, "Non specific error code"},
13060   {SMBE_badpw, "Bad password"},
13061   {SMBE_badtype, "Reserved"},
13062   {SMBE_access, "No permissions to perform the requested operation"},
13063   {SMBE_invnid, "TID invalid"},
13064   {SMBE_invnetname, "Invalid network name. Service not found"},
13065   {SMBE_invdevice, "Invalid device"},
13066   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
13067   {SMBE_qfull, "Print queue full"},
13068   {SMBE_qtoobig, "Queued item too big"},
13069   {SMBE_qeof, "EOF on print queue dump"},
13070   {SMBE_invpfid, "Invalid print file in smb_fid"},
13071   {SMBE_smbcmd, "Unrecognised command"},
13072   {SMBE_srverror, "SMB server internal error"},
13073   {SMBE_filespecs, "Fid and pathname invalid combination"},
13074   {SMBE_badlink, "Bad link in request ???"},
13075   {SMBE_badpermits, "Access specified for a file is not valid"},
13076   {SMBE_badpid, "Bad process id in request"},
13077   {SMBE_setattrmode, "Attribute mode invalid"},
13078   {SMBE_paused, "Message server paused"},
13079   {SMBE_msgoff, "Not receiving messages"},
13080   {SMBE_noroom, "No room for message"},
13081   {SMBE_rmuns, "Too many remote usernames"},
13082   {SMBE_timeout, "Operation timed out"},
13083   {SMBE_noresource, "No resources currently available for request."},
13084   {SMBE_toomanyuids, "Too many userids"},
13085   {SMBE_baduid, "Bad userid"},
13086   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
13087   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
13088   {SMBE_contMPX, "Resume MPX mode"},
13089   {SMBE_badPW, "Bad Password???"},
13090   {SMBE_nosupport, "Operation not supported"},
13091   { 0, NULL}
13092 };
13093
13094 /* Error codes for the ERRHRD class */
13095
13096 static const value_string HRD_errors[] = {
13097   {SMBE_nowrite, "Read only media"},
13098   {SMBE_badunit, "Unknown device"},
13099   {SMBE_notready, "Drive not ready"},
13100   {SMBE_badcmd, "Unknown command"},
13101   {SMBE_data, "Data (CRC) error"},
13102   {SMBE_badreq, "Bad request structure length"},
13103   {SMBE_seek, "Seek error???"},
13104   {SMBE_badmedia, "Bad media???"},
13105   {SMBE_badsector, "Bad sector???"},
13106   {SMBE_nopaper, "No paper in printer???"},
13107   {SMBE_write, "Write error???"},
13108   {SMBE_read, "Read error???"},
13109   {SMBE_general, "General error???"},
13110   {SMBE_badshare, "A open conflicts with an existing open"},
13111   {SMBE_lock, "Lock/unlock error"},
13112   {SMBE_wrongdisk,  "Wrong disk???"},
13113   {SMBE_FCBunavail, "FCB unavailable???"},
13114   {SMBE_sharebufexc, "Share buffer excluded???"},
13115   {SMBE_diskfull, "Disk full???"},
13116   {0, NULL}
13117 };
13118
13119 static char *decode_smb_error(guint8 errcls, guint16 errcode)
13120 {
13121
13122   switch (errcls) {
13123
13124   case SMB_SUCCESS:
13125
13126     return("No Error");   /* No error ??? */
13127     break;
13128
13129   case SMB_ERRDOS:
13130
13131     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
13132     break;
13133
13134   case SMB_ERRSRV:
13135
13136     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
13137     break;
13138
13139   case SMB_ERRHRD:
13140
13141     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
13142     break;
13143
13144   default:
13145
13146     return("Unknown error class!");
13147
13148   }
13149
13150 }
13151
13152
13153 /* These are the MS country codes from
13154
13155         http://www.unicode.org/unicode/onlinedat/countries.html
13156
13157    For countries that share the same number, I choose to use only the
13158    name of the largest country. Apologies for this. If this offends you,
13159    here is the table to change that.
13160
13161    This also includes the code of 0 for "Default", which isn't in
13162    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
13163    header file.  Presumably it means "don't override the setting
13164    on the user's machine".
13165
13166    Future versions of Microsoft's "winnls.h" header file might include
13167    additional codes; the current version matches the Unicode Consortium's
13168    table.
13169 */
13170 const value_string ms_country_codes[] = {
13171         {  0,   "Default"},
13172         {  1,   "USA"},
13173         {  2,   "Canada"},
13174         {  7,   "Russia"},
13175         { 20,   "Egypt"},
13176         { 27,   "South Africa"},
13177         { 30,   "Greece"},
13178         { 31,   "Netherlands"},
13179         { 32,   "Belgium"},
13180         { 33,   "France"},
13181         { 34,   "Spain"},
13182         { 36,   "Hungary"},
13183         { 39,   "Italy"},
13184         { 40,   "Romania"},
13185         { 41,   "Switzerland"},
13186         { 43,   "Austria"},
13187         { 44,   "United Kingdom"},
13188         { 45,   "Denmark"},
13189         { 46,   "Sweden"},
13190         { 47,   "Norway"},
13191         { 48,   "Poland"},
13192         { 49,   "Germany"},
13193         { 51,   "Peru"},
13194         { 52,   "Mexico"},
13195         { 54,   "Argentina"},
13196         { 55,   "Brazil"},
13197         { 56,   "Chile"},
13198         { 57,   "Colombia"},
13199         { 58,   "Venezuela"},
13200         { 60,   "Malaysia"},
13201         { 61,   "Australia"},
13202         { 62,   "Indonesia"},
13203         { 63,   "Philippines"},
13204         { 64,   "New Zealand"},
13205         { 65,   "Singapore"},
13206         { 66,   "Thailand"},
13207         { 81,   "Japan"},
13208         { 82,   "South Korea"},
13209         { 84,   "Viet Nam"},
13210         { 86,   "China"},
13211         { 90,   "Turkey"},
13212         { 91,   "India"},
13213         { 92,   "Pakistan"},
13214         {212,   "Morocco"},
13215         {213,   "Algeria"},
13216         {216,   "Tunisia"},
13217         {218,   "Libya"},
13218         {254,   "Kenya"},
13219         {263,   "Zimbabwe"},
13220         {298,   "Faroe Islands"},
13221         {351,   "Portugal"},
13222         {352,   "Luxembourg"},
13223         {353,   "Ireland"},
13224         {354,   "Iceland"},
13225         {355,   "Albania"},
13226         {358,   "Finland"},
13227         {359,   "Bulgaria"},
13228         {370,   "Lithuania"},
13229         {371,   "Latvia"},
13230         {372,   "Estonia"},
13231         {374,   "Armenia"},
13232         {375,   "Belarus"},
13233         {380,   "Ukraine"},
13234         {381,   "Serbia"},
13235         {385,   "Croatia"},
13236         {386,   "Slovenia"},
13237         {389,   "Macedonia"},
13238         {420,   "Czech Republic"},
13239         {421,   "Slovak Republic"},
13240         {501,   "Belize"},
13241         {502,   "Guatemala"},
13242         {503,   "El Salvador"},
13243         {504,   "Honduras"},
13244         {505,   "Nicaragua"},
13245         {506,   "Costa Rica"},
13246         {507,   "Panama"},
13247         {591,   "Bolivia"},
13248         {593,   "Ecuador"},
13249         {595,   "Paraguay"},
13250         {598,   "Uruguay"},
13251         {673,   "Brunei Darussalam"},
13252         {852,   "Hong Kong"},
13253         {853,   "Macau"},
13254         {886,   "Taiwan"},
13255         {960,   "Maldives"},
13256         {961,   "Lebanon"},
13257         {962,   "Jordan"},
13258         {963,   "Syria"},
13259         {964,   "Iraq"},
13260         {965,   "Kuwait"},
13261         {966,   "Saudi Arabia"},
13262         {967,   "Yemen"},
13263         {968,   "Oman"},
13264         {971,   "United Arab Emirates"},
13265         {972,   "Israel"},
13266         {973,   "Bahrain"},
13267         {974,   "Qatar"},
13268         {976,   "Mongolia"},
13269         {981,   "Iran"},
13270         {994,   "Azerbaijan"},
13271         {995,   "Georgia"},
13272         {996,   "Kyrgyzstan"},
13273
13274         {0,     NULL}
13275 };
13276
13277 /*
13278  * NT error codes.
13279  *
13280  * From
13281  *
13282  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
13283  */
13284 const value_string NT_errors[] = {
13285   { 0x00000000, "STATUS_SUCCESS" },
13286   { 0x00000000, "STATUS_WAIT_0" },
13287   { 0x00000001, "STATUS_WAIT_1" },
13288   { 0x00000002, "STATUS_WAIT_2" },
13289   { 0x00000003, "STATUS_WAIT_3" },
13290   { 0x0000003F, "STATUS_WAIT_63" },
13291   { 0x00000080, "STATUS_ABANDONED" },
13292   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
13293   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
13294   { 0x000000C0, "STATUS_USER_APC" },
13295   { 0x00000100, "STATUS_KERNEL_APC" },
13296   { 0x00000101, "STATUS_ALERTED" },
13297   { 0x00000102, "STATUS_TIMEOUT" },
13298   { 0x00000103, "STATUS_PENDING" },
13299   { 0x00000104, "STATUS_REPARSE" },
13300   { 0x00000105, "STATUS_MORE_ENTRIES" },
13301   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
13302   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
13303   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
13304   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
13305   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
13306   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
13307   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
13308   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
13309   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
13310   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
13311   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
13312   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
13313   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
13314   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
13315   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
13316   { 0x00000116, "STATUS_CRASH_DUMP" },
13317   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
13318   { 0x00000118, "STATUS_REPARSE_OBJECT" },
13319   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
13320   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
13321   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
13322   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
13323   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
13324   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
13325   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
13326   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
13327   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
13328   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
13329   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
13330   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
13331   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
13332   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
13333   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
13334   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
13335   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
13336   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
13337   { 0x40000012, "STATUS_EVENT_DONE" },
13338   { 0x40000013, "STATUS_EVENT_PENDING" },
13339   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
13340   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
13341   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
13342   { 0x40000017, "STATUS_WAS_UNLOCKED" },
13343   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
13344   { 0x40000019, "STATUS_WAS_LOCKED" },
13345   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
13346   { 0x4000001B, "STATUS_ALREADY_WIN32" },
13347   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
13348   { 0x4000001D, "STATUS_WX86_CONTINUE" },
13349   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
13350   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
13351   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
13352   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
13353   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
13354   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
13355   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
13356   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
13357   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
13358   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
13359   { 0x80000003, "STATUS_BREAKPOINT" },
13360   { 0x80000004, "STATUS_SINGLE_STEP" },
13361   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
13362   { 0x80000006, "STATUS_NO_MORE_FILES" },
13363   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
13364   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
13365   { 0x8000000B, "STATUS_NO_INHERITANCE" },
13366   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
13367   { 0x8000000D, "STATUS_PARTIAL_COPY" },
13368   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
13369   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
13370   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
13371   { 0x80000011, "STATUS_DEVICE_BUSY" },
13372   { 0x80000012, "STATUS_NO_MORE_EAS" },
13373   { 0x80000013, "STATUS_INVALID_EA_NAME" },
13374   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
13375   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
13376   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
13377   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
13378   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
13379   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
13380   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
13381   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
13382   { 0x8000001D, "STATUS_BUS_RESET" },
13383   { 0x8000001E, "STATUS_END_OF_MEDIA" },
13384   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
13385   { 0x80000020, "STATUS_MEDIA_CHECK" },
13386   { 0x80000021, "STATUS_SETMARK_DETECTED" },
13387   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
13388   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
13389   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
13390   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
13391   { 0x80000026, "STATUS_LONGJUMP" },
13392   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
13393   { 0x80090301, "SEC_E_INVALID_HANDLE" },
13394   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
13395   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
13396   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
13397   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
13398   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
13399   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
13400   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
13401   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
13402   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
13403   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
13404   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
13405   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
13406   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
13407   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
13408   { 0xC0000008, "STATUS_INVALID_HANDLE" },
13409   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
13410   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
13411   { 0xC000000B, "STATUS_INVALID_CID" },
13412   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
13413   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
13414   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
13415   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
13416   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
13417   { 0xC0000011, "STATUS_END_OF_FILE" },
13418   { 0xC0000012, "STATUS_WRONG_VOLUME" },
13419   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
13420   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
13421   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
13422   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
13423   { 0xC0000017, "STATUS_NO_MEMORY" },
13424   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
13425   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
13426   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
13427   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
13428   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
13429   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
13430   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
13431   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
13432   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
13433   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
13434   { 0xC0000022, "STATUS_ACCESS_DENIED" },
13435   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
13436   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
13437   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
13438   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
13439   { 0xC0000027, "STATUS_UNWIND" },
13440   { 0xC0000028, "STATUS_BAD_STACK" },
13441   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
13442   { 0xC000002A, "STATUS_NOT_LOCKED" },
13443   { 0xC000002B, "STATUS_PARITY_ERROR" },
13444   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
13445   { 0xC000002D, "STATUS_NOT_COMMITTED" },
13446   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
13447   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
13448   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
13449   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
13450   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
13451   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
13452   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
13453   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
13454   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
13455   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
13456   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
13457   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
13458   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
13459   { 0xC000003C, "STATUS_DATA_OVERRUN" },
13460   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
13461   { 0xC000003E, "STATUS_DATA_ERROR" },
13462   { 0xC000003F, "STATUS_CRC_ERROR" },
13463   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
13464   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
13465   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
13466   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
13467   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
13468   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
13469   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
13470   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
13471   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
13472   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
13473   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
13474   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
13475   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
13476   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
13477   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
13478   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
13479   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
13480   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
13481   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
13482   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
13483   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
13484   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
13485   { 0xC0000056, "STATUS_DELETE_PENDING" },
13486   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
13487   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
13488   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
13489   { 0xC000005A, "STATUS_INVALID_OWNER" },
13490   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
13491   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
13492   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
13493   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
13494   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
13495   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
13496   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
13497   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
13498   { 0xC0000063, "STATUS_USER_EXISTS" },
13499   { 0xC0000064, "STATUS_NO_SUCH_USER" },
13500   { 0xC0000065, "STATUS_GROUP_EXISTS" },
13501   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
13502   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
13503   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
13504   { 0xC0000069, "STATUS_LAST_ADMIN" },
13505   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
13506   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
13507   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
13508   { 0xC000006D, "STATUS_LOGON_FAILURE" },
13509   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
13510   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
13511   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
13512   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
13513   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
13514   { 0xC0000073, "STATUS_NONE_MAPPED" },
13515   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
13516   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
13517   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
13518   { 0xC0000077, "STATUS_INVALID_ACL" },
13519   { 0xC0000078, "STATUS_INVALID_SID" },
13520   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
13521   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
13522   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
13523   { 0xC000007C, "STATUS_NO_TOKEN" },
13524   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
13525   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
13526   { 0xC000007F, "STATUS_DISK_FULL" },
13527   { 0xC0000080, "STATUS_SERVER_DISABLED" },
13528   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
13529   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
13530   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
13531   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
13532   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
13533   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
13534   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
13535   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
13536   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
13537   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
13538   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
13539   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
13540   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
13541   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
13542   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
13543   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
13544   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
13545   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
13546   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
13547   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
13548   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
13549   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
13550   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
13551   { 0xC0000098, "STATUS_FILE_INVALID" },
13552   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
13553   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
13554   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
13555   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
13556   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
13557   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
13558   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
13559   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
13560   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
13561   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
13562   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
13563   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
13564   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
13565   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
13566   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
13567   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
13568   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
13569   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
13570   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
13571   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
13572   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
13573   { 0xC00000AE, "STATUS_PIPE_BUSY" },
13574   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
13575   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
13576   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
13577   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
13578   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
13579   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
13580   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
13581   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
13582   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
13583   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
13584   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
13585   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
13586   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
13587   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
13588   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
13589   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
13590   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
13591   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
13592   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
13593   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
13594   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
13595   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
13596   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
13597   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
13598   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
13599   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
13600   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
13601   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
13602   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
13603   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
13604   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
13605   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
13606   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
13607   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
13608   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
13609   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
13610   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
13611   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
13612   { 0xC00000D5, "STATUS_FILE_RENAMED" },
13613   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
13614   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
13615   { 0xC00000D8, "STATUS_CANT_WAIT" },
13616   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
13617   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
13618   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
13619   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
13620   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
13621   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
13622   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
13623   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
13624   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
13625   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
13626   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
13627   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
13628   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
13629   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
13630   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
13631   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
13632   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
13633   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
13634   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
13635   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
13636   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
13637   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
13638   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
13639   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
13640   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
13641   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
13642   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
13643   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
13644   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
13645   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
13646   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
13647   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
13648   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
13649   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
13650   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
13651   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
13652   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
13653   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
13654   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
13655   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
13656   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
13657   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
13658   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
13659   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
13660   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
13661   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
13662   { 0xC0000107, "STATUS_FILES_OPEN" },
13663   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
13664   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
13665   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
13666   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
13667   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
13668   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
13669   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
13670   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
13671   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
13672   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
13673   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
13674   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
13675   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
13676   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
13677   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
13678   { 0xC0000117, "STATUS_NO_LDT" },
13679   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
13680   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
13681   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
13682   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
13683   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
13684   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
13685   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
13686   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
13687   { 0xC0000120, "STATUS_CANCELLED" },
13688   { 0xC0000121, "STATUS_CANNOT_DELETE" },
13689   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
13690   { 0xC0000123, "STATUS_FILE_DELETED" },
13691   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
13692   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
13693   { 0xC0000126, "STATUS_SPECIAL_USER" },
13694   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
13695   { 0xC0000128, "STATUS_FILE_CLOSED" },
13696   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
13697   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
13698   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
13699   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
13700   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
13701   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
13702   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
13703   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
13704   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
13705   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
13706   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
13707   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
13708   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
13709   { 0xC0000136, "STATUS_OPEN_FAILED" },
13710   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
13711   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
13712   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
13713   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
13714   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
13715   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
13716   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
13717   { 0xC000013E, "STATUS_LINK_FAILED" },
13718   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
13719   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
13720   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
13721   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
13722   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
13723   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
13724   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
13725   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
13726   { 0xC0000147, "STATUS_NO_PAGEFILE" },
13727   { 0xC0000148, "STATUS_INVALID_LEVEL" },
13728   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
13729   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
13730   { 0xC000014B, "STATUS_PIPE_BROKEN" },
13731   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
13732   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
13733   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
13734   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
13735   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
13736   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
13737   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
13738   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
13739   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
13740   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
13741   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
13742   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
13743   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
13744   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
13745   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
13746   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
13747   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
13748   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
13749   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
13750   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
13751   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
13752   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
13753   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
13754   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
13755   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
13756   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
13757   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
13758   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
13759   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
13760   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
13761   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
13762   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
13763   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
13764   { 0xC000016D, "STATUS_FT_ORPHANING" },
13765   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
13766   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
13767   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
13768   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
13769   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
13770   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
13771   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
13772   { 0xC0000178, "STATUS_NO_MEDIA" },
13773   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
13774   { 0xC000017B, "STATUS_INVALID_MEMBER" },
13775   { 0xC000017C, "STATUS_KEY_DELETED" },
13776   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
13777   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
13778   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
13779   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
13780   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
13781   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
13782   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
13783   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
13784   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
13785   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
13786   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
13787   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
13788   { 0xC0000189, "STATUS_TOO_LATE" },
13789   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
13790   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
13791   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
13792   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
13793   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
13794   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
13795   { 0xC0000190, "STATUS_TRUST_FAILURE" },
13796   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
13797   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
13798   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
13799   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
13800   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
13801   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
13802   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
13803   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
13804   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
13805   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
13806   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
13807   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
13808   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
13809   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
13810   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
13811   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
13812   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
13813   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
13814   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
13815   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
13816   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
13817   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
13818   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
13819   { 0xC000020D, "STATUS_CONNECTION_RESET" },
13820   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
13821   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
13822   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
13823   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
13824   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
13825   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
13826   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
13827   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
13828   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
13829   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
13830   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
13831   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
13832   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
13833   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
13834   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
13835   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
13836   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
13837   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
13838   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
13839   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
13840   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
13841   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
13842   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
13843   { 0xC0000225, "STATUS_NOT_FOUND" },
13844   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
13845   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
13846   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
13847   { 0xC0000229, "STATUS_FAIL_CHECK" },
13848   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
13849   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
13850   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
13851   { 0xC000022D, "STATUS_RETRY" },
13852   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
13853   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
13854   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
13855   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
13856   { 0xC0000232, "STATUS_INVALID_VARIANT" },
13857   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
13858   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
13859   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
13860   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
13861   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
13862   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
13863   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
13864   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
13865   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
13866   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
13867   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
13868   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
13869   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
13870   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
13871   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
13872   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
13873   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
13874   { 0xC0000244, "STATUS_AUDIT_FAILED" },
13875   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
13876   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
13877   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
13878   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
13879   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
13880   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
13881   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
13882   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
13883   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
13884   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
13885   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
13886   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
13887   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
13888   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
13889   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
13890   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
13891   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
13892   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
13893   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
13894   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
13895   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
13896   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
13897   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
13898   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
13899   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
13900   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
13901   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
13902   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
13903   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
13904   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
13905   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
13906   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
13907   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
13908   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
13909   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
13910   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
13911   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
13912   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
13913   { 0xC0000272, "STATUS_NO_MATCH" },
13914   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
13915   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
13916   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
13917   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
13918   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
13919   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
13920   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
13921   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
13922   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
13923   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
13924   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
13925   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
13926   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
13927   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
13928   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
13929   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
13930   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
13931   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
13932   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
13933   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
13934   { 0xC000028E, "STATUS_NO_EFS" },
13935   { 0xC000028F, "STATUS_WRONG_EFS" },
13936   { 0xC0000290, "STATUS_NO_USER_KEYS" },
13937   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
13938   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
13939   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
13940   { 0x40000294, "STATUS_WAKE_SYSTEM" },
13941   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
13942   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
13943   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
13944   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
13945   { 0xC0000299, "STATUS_SHARED_POLICY" },
13946   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
13947   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
13948   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
13949   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
13950   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
13951   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
13952   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
13953   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
13954   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
13955   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
13956   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
13957   { 0xC00002A5, "STATUS_DS_BUSY" },
13958   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
13959   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
13960   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
13961   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
13962   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
13963   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
13964   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
13965   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
13966   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
13967   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
13968   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
13969   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
13970   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
13971   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
13972   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
13973   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
13974   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
13975   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
13976   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
13977   { 0xC00002B9, "STATUS_NOINTERFACE" },
13978   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
13979   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
13980   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
13981   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
13982   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
13983   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
13984   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
13985   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
13986   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
13987   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
13988   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
13989   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
13990   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
13991   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
13992   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
13993   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
13994   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
13995   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
13996   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
13997   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
13998   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
13999   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
14000   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
14001   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
14002   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
14003   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
14004   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
14005   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
14006   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
14007   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
14008   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
14009   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
14010   { 0xC00002E1, "STATUS_DS_CANT_START" },
14011   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
14012   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
14013   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
14014   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
14015   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
14016   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
14017   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
14018   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
14019   { 0xC0009898, "STATUS_WOW_ASSERTION" },
14020   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
14021   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
14022   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
14023   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
14024   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
14025   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
14026   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
14027   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
14028   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
14029   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
14030   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
14031   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
14032   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
14033   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
14034   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
14035   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
14036   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
14037   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
14038   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
14039   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
14040   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
14041   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
14042   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
14043   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
14044   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
14045   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
14046   { 0xC002001B, "RPC_NT_CALL_FAILED" },
14047   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
14048   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
14049   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
14050   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
14051   { 0xC0020022, "RPC_NT_INVALID_TAG" },
14052   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
14053   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
14054   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
14055   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
14056   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
14057   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
14058   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
14059   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
14060   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
14061   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
14062   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
14063   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
14064   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
14065   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
14066   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
14067   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
14068   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
14069   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
14070   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
14071   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
14072   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
14073   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
14074   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
14075   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
14076   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
14077   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
14078   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
14079   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
14080   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
14081   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
14082   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
14083   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
14084   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
14085   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
14086   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
14087   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
14088   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
14089   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
14090   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
14091   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
14092   { 0xC002100A, "RPC_P_SEND_FAILED" },
14093   { 0xC002100B, "RPC_P_TIMEOUT" },
14094   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
14095   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
14096   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
14097   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
14098   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
14099   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
14100   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
14101   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
14102   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
14103   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
14104   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
14105   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
14106   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
14107   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
14108   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
14109   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
14110   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
14111   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
14112   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
14113   { 0xC002004C, "EPT_NT_CANT_CREATE" },
14114   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
14115   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
14116   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
14117   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
14118   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
14119   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
14120   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
14121   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
14122   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
14123   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
14124   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
14125   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
14126   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
14127   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
14128   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
14129   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
14130   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
14131   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
14132   { 0,          NULL }
14133 };
14134
14135
14136
14137 static const true_false_string tfs_smb_flags_lock = {
14138         "Lock&Read, Write&Unlock are supported",
14139         "Lock&Read, Write&Unlock are not supported"
14140 };
14141 static const true_false_string tfs_smb_flags_receive_buffer = {
14142         "Receive buffer has been posted",
14143         "Receive buffer has not been posted"
14144 };
14145 static const true_false_string tfs_smb_flags_caseless = {
14146         "Path names are caseless",
14147         "Path names are case sensitive"
14148 };
14149 static const true_false_string tfs_smb_flags_canon = {
14150         "Pathnames are canonicalized",
14151         "Pathnames are not canonicalized"
14152 };
14153 static const true_false_string tfs_smb_flags_oplock = {
14154         "OpLock requested/granted",
14155         "OpLock not requested/granted"
14156 };
14157 static const true_false_string tfs_smb_flags_notify = {
14158         "Notify client on all modifications",
14159         "Notify client only on open"
14160 };
14161 static const true_false_string tfs_smb_flags_response = {
14162         "Message is a response to the client/redirector",
14163         "Message is a request to the server"
14164 };
14165
14166 static int
14167 dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14168 {
14169         guint8 mask;
14170         proto_item *item = NULL;
14171         proto_tree *tree = NULL;
14172
14173         mask = tvb_get_guint8(tvb, offset);
14174
14175         if(parent_tree){
14176                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
14177                         "Flags: 0x%02x", mask);
14178                 tree = proto_item_add_subtree(item, ett_smb_flags);
14179         }
14180         proto_tree_add_boolean(tree, hf_smb_flags_response,
14181                 tvb, offset, 1, mask);
14182         proto_tree_add_boolean(tree, hf_smb_flags_notify,
14183                 tvb, offset, 1, mask);
14184         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
14185                 tvb, offset, 1, mask);
14186         proto_tree_add_boolean(tree, hf_smb_flags_canon,
14187                 tvb, offset, 1, mask);
14188         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
14189                 tvb, offset, 1, mask);
14190         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
14191                 tvb, offset, 1, mask);
14192         proto_tree_add_boolean(tree, hf_smb_flags_lock,
14193                 tvb, offset, 1, mask);
14194         offset += 1;
14195         return offset;
14196 }
14197
14198
14199  
14200 static const true_false_string tfs_smb_flags2_long_names_allowed = {
14201         "Long file names are allowed in the response",
14202         "Long file names are not allowed in the response"
14203 };
14204 static const true_false_string tfs_smb_flags2_ea = {
14205         "Extended attributes are supported",
14206         "Extended attributes are not supported"
14207 };
14208 static const true_false_string tfs_smb_flags2_sec_sig = {
14209         "Security signatures are supported",
14210         "Security signatures are not supported"
14211 };
14212 static const true_false_string tfs_smb_flags2_long_names_used = {
14213         "Path names in request are long file names",
14214         "Path names in request are not long file names"
14215 };
14216 static const true_false_string tfs_smb_flags2_esn = {
14217         "Extended security negotiation is supported",
14218         "Extended security negotiation is not supported"
14219 };
14220 static const true_false_string tfs_smb_flags2_dfs = {
14221         "Resolve pathnames with Dfs",
14222         "Don't resolve pathnames with Dfs"
14223 };
14224 static const true_false_string tfs_smb_flags2_roe = {
14225         "Permit reads if execute-only",
14226         "Don't permit reads if execute-only"
14227 };
14228 static const true_false_string tfs_smb_flags2_nt_error = {
14229         "Error codes are NT error codes",
14230         "Error codes are DOS error codes"
14231 };
14232 static const true_false_string tfs_smb_flags2_string = {
14233         "Strings are Unicode",
14234         "Strings are ASCII"
14235 };
14236 static int
14237 dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14238 {
14239         guint16 mask;
14240         proto_item *item = NULL;
14241         proto_tree *tree = NULL;
14242
14243         mask = tvb_get_letohs(tvb, offset);
14244
14245         if(parent_tree){
14246                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
14247                         "Flags2: 0x%04x", mask);
14248                 tree = proto_item_add_subtree(item, ett_smb_flags2);
14249         }
14250
14251         proto_tree_add_boolean(tree, hf_smb_flags2_string,
14252                 tvb, offset, 2, mask);
14253         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
14254                 tvb, offset, 2, mask);
14255         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
14256                 tvb, offset, 2, mask);
14257         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
14258                 tvb, offset, 2, mask);
14259         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
14260                 tvb, offset, 2, mask);
14261         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
14262                 tvb, offset, 2, mask);
14263         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
14264                 tvb, offset, 2, mask);
14265         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
14266                 tvb, offset, 2, mask);
14267         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
14268                 tvb, offset, 2, mask);
14269
14270         offset += 2;
14271         return offset;
14272 }
14273
14274
14275
14276 #define SMB_FLAGS_DIRN 0x80
14277
14278
14279 static gboolean
14280 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14281 {
14282         int offset = 0;
14283         proto_item *item = NULL, *hitem = NULL;
14284         proto_tree *tree = NULL, *htree = NULL;
14285         guint8          flags;
14286         guint16         flags2;
14287         smb_info_t      si;
14288         smb_saved_info_t *sip = NULL;
14289         smb_saved_info_key_t key;
14290         smb_saved_info_key_t *new_key;
14291         guint32 nt_status = 0;
14292         guint8 errclass = 0;
14293         guint16 errcode = 0;
14294         guint32 pid_mid;
14295         conversation_t *conversation;
14296
14297         top_tree=parent_tree;
14298
14299         /* must check that this really is a smb packet */
14300         if (!tvb_bytes_exist(tvb, 0, 4))
14301                 return FALSE;
14302
14303         if( (tvb_get_guint8(tvb, 0) != 0xff)
14304             || (tvb_get_guint8(tvb, 1) != 'S')
14305             || (tvb_get_guint8(tvb, 2) != 'M')
14306             || (tvb_get_guint8(tvb, 3) != 'B') ){
14307                 return FALSE;
14308         }
14309          
14310         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
14311                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
14312         }
14313         if (check_col(pinfo->cinfo, COL_INFO)){
14314                 col_clear(pinfo->cinfo, COL_INFO);
14315         }
14316
14317         /* start off using the local variable, we will allocate a new one if we
14318            need to*/
14319         si.cmd = tvb_get_guint8(tvb, offset+4);
14320         flags = tvb_get_guint8(tvb, offset+9);
14321         si.request = !(flags&SMB_FLAGS_DIRN);
14322         flags2 = tvb_get_letohs(tvb, offset+10);
14323         if(flags2 & 0x8000){
14324                 si.unicode = TRUE; /* Mark them as Unicode */
14325         } else {
14326                 si.unicode = FALSE;
14327         }
14328         si.tid = tvb_get_letohs(tvb, offset+24);
14329         si.pid = tvb_get_letohs(tvb, offset+26);
14330         si.uid = tvb_get_letohs(tvb, offset+28);
14331         si.mid = tvb_get_letohs(tvb, offset+30);
14332         pid_mid = (si.pid << 16) | si.mid;
14333         si.info_level = -1;
14334         si.info_count = -1;
14335
14336         if (parent_tree) {
14337                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
14338                         -1, FALSE);
14339                 tree = proto_item_add_subtree(item, ett_smb);
14340
14341                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
14342                         "SMB Header");
14343
14344                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
14345         }
14346
14347         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
14348         offset += 4;  /* Skip the marker */
14349
14350         /* find which conversation we are part of and get the tables for that 
14351            conversation*/
14352         conversation = find_conversation(&pinfo->src, &pinfo->dst,
14353                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
14354         if(conversation){
14355                 si.ct=conversation_get_proto_data(conversation, proto_smb);
14356         } else {
14357                 /* OK this is a new conversation, we must create it
14358                    and attach appropriate data (matched and unmatched 
14359                    table for this conversation)
14360                 */
14361                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
14362                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
14363                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
14364                 conv_tables = g_slist_prepend(conv_tables, si.ct);
14365                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
14366                         smb_saved_info_equal_matched);
14367                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
14368                         smb_saved_info_equal_unmatched);
14369                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
14370                         smb_saved_info_hash_unmatched, 
14371                         smb_saved_info_equal_unmatched);
14372                 si.ct->tid_service=g_hash_table_new(
14373                         smb_saved_info_hash_unmatched, 
14374                         smb_saved_info_equal_unmatched);
14375                 conversation_add_proto_data(conversation, proto_smb, si.ct);
14376         }
14377
14378         if( (si.request)
14379             &&  (si.mid==0)
14380             &&  (si.uid==0)
14381             &&  (si.pid==0)
14382             &&  (si.tid==0) ){
14383                 /* this is a broadcast SMB packet, there will not be a reply.
14384                    We dont need to do anything 
14385                 */
14386                 si.unidir = TRUE;
14387         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
14388                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
14389                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
14390                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
14391                 /* Ok, we got a special request type. This request is either
14392                    an NT Cancel or a continuation relative to a real request
14393                    in an earlier packet.  In either case, we don't expect any
14394                    responses to this packet.  For continuations, any later
14395                    responses we see really just belong to the original request.
14396                    Anyway, we want to remember this packet somehow and
14397                    remember which original request it is associated with so
14398                    we can say nice things such as "This is a Cancellation to
14399                    the request in frame x", but we don't want the
14400                    request/response matching to get messed up.
14401
14402                    The only thing we do in this case is trying to find which original
14403                    request we match with and insert an entry for this "special" 
14404                    request for later reference. We continue to reference the original
14405                    requests smb_saved_info_t but we dont touch it or change anything
14406                    in it.
14407                 */
14408
14409                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
14410
14411                 if(!pinfo->fd->flags.visited){
14412                         /* try to find which original call we match and if we 
14413                            find it add us to the matched table. Dont touch
14414                            anything else since we dont want this one to mess
14415                            up the request/response matching. We still consider
14416                            the initial call the real request and this is only
14417                            some sort of continuation.
14418                         */
14419                         /* we only check the unmatched table and assume that the
14420                            last seen MID matching ours is the right one.
14421                            This can fail but is better than nothing
14422                         */
14423                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14424                         if(sip!=NULL){
14425                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14426                                 new_key->frame = pinfo->fd->num;
14427                                 new_key->pid_mid = pid_mid;
14428                                 g_hash_table_insert(si.ct->matched, new_key,
14429                                     sip);
14430                         }
14431                 } else {
14432                         /* we have seen this packet before; check the
14433                            matching table
14434                         */
14435                         key.frame = pinfo->fd->num;
14436                         key.pid_mid = pid_mid;
14437                         sip=g_hash_table_lookup(si.ct->matched, &key);
14438                         if(sip==NULL){
14439                         /*
14440                           We didn't find it.
14441                           Too bad, unfortunately there is not really much we can
14442                           do now since this means that we never saw the initial
14443                           request.
14444                          */
14445                         }
14446                 }
14447
14448
14449                 if(sip && sip->frame_req){
14450                         switch(si.cmd){
14451                         case SMB_COM_NT_CANCEL:
14452                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
14453                                                     tvb, 0, 0, sip->frame_req);
14454                                 break;
14455                         case SMB_COM_TRANSACTION_SECONDARY:
14456                         case SMB_COM_TRANSACTION2_SECONDARY:
14457                         case SMB_COM_NT_TRANSACT_SECONDARY:
14458                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
14459                                                     tvb, 0, 0, sip->frame_req);
14460                                 break;
14461                         }
14462                 } else {
14463                         switch(si.cmd){
14464                         case SMB_COM_NT_CANCEL:
14465                                 proto_tree_add_text(htree, tvb, 0, 0,
14466                                                     "Cancellation to: <unknown frame>");
14467                                 break;
14468                         case SMB_COM_TRANSACTION_SECONDARY:
14469                         case SMB_COM_TRANSACTION2_SECONDARY:
14470                         case SMB_COM_NT_TRANSACT_SECONDARY:
14471                                 proto_tree_add_text(htree, tvb, 0, 0,
14472                                                     "Continuation to: <unknown frame>");
14473                                 break;
14474                         }
14475                 }
14476         } else { /* normal bidirectional request or response */
14477                 si.unidir = FALSE;
14478
14479                 if(!pinfo->fd->flags.visited){
14480                         /* first see if we find an unmatched smb "equal" to 
14481                            the current one 
14482                         */
14483                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14484                         if(sip!=NULL){
14485                                 gboolean cmd_match=FALSE;
14486
14487                                 /*
14488                                  * Make sure the SMB we found was the
14489                                  * same command, or a different command
14490                                  * that's another valid type of reply
14491                                  * to that command.
14492                                  */
14493                                 if(si.cmd==sip->cmd){
14494                                         cmd_match=TRUE;
14495                                 }
14496                                 else if(si.cmd==SMB_COM_NT_CANCEL){
14497                                         cmd_match=TRUE;
14498                                 }
14499                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
14500                                      && (sip->cmd==SMB_COM_TRANSACTION)){
14501                                         cmd_match=TRUE;
14502                                 }
14503                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
14504                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
14505                                         cmd_match=TRUE;
14506                                 }
14507                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
14508                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
14509                                         cmd_match=TRUE;
14510                                 }
14511
14512                                 if( (si.request) || (!cmd_match) ) {
14513                                         /* If we are processing an SMB request but there was already
14514                                            another "identical" smb resuest we had not matched yet.
14515                                            This must mean that either we have a retransmission or that the
14516                                            response to the previous one was lost and the client has reused
14517                                            the MID for this conversation. In either case it's not much more
14518                                            we can do than forget the old request and concentrate on the 
14519                                            present one instead.
14520
14521                                            We also do this cleanup if we see that the cmd in the original
14522                                            request in sip->cmd is not compatible with the current cmd.
14523                                            This is to prevent matching errors such as if there were two
14524                                            SMBs of different cmds but with identical MID and PID values and
14525                                            if ethereal lost the first reply and the second request.
14526                                         */
14527                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
14528                                         sip=NULL; /* XXX should free it as well */
14529                                 } else {
14530                                         /* we have found a response to some request we have seen earlier.
14531                                            What we do now depends on whether this is the first response
14532                                            to that request we see (id frame_res==0) or not. 
14533                                         */
14534                                         if(sip->frame_res==0){
14535                                                 /* ok it is the first response we have seen to this packet */
14536                                                 sip->frame_res = pinfo->fd->num;
14537                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14538                                                 new_key->frame = sip->frame_req;
14539                                                 new_key->pid_mid = pid_mid;
14540                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14541                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14542                                                 new_key->frame = sip->frame_res;
14543                                                 new_key->pid_mid = pid_mid;
14544                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14545                                         } else {
14546                                                 /* we have already seen another response to this one, but
14547                                                    register it anyway so we see which request it matches 
14548                                                 */
14549                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14550                                                 new_key->frame = pinfo->fd->num;
14551                                                 new_key->pid_mid = pid_mid;
14552                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14553                                         }
14554                                 }
14555                         }
14556                         if(si.request){
14557                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
14558                                 sip->frame_req = pinfo->fd->num;
14559                                 sip->frame_res = 0;
14560                                 sip->flags = 0;
14561                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
14562                                     == (void *)TID_IPC) {
14563                                         sip->flags |= SMB_SIF_TID_IS_IPC;
14564                                 }
14565                                 sip->cmd = si.cmd;
14566                                 sip->extra_info = NULL;
14567                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
14568                         }
14569                 } else {
14570                         /* we have seen this packet before; check the
14571                            matching table.
14572                            If we haven't yet seen the reply, we won't
14573                            find the info for it; we don't need it, as
14574                            we only use it to save information, and, as
14575                            we've seen this packet before, we've already
14576                            saved the information.
14577                         */
14578                         key.frame = pinfo->fd->num;
14579                         key.pid_mid = pid_mid;
14580                         sip=g_hash_table_lookup(si.ct->matched, &key);
14581                 }
14582         }
14583
14584         /*
14585          * Pass the "sip" on to subdissectors through "si".
14586          */
14587         si.sip = sip;
14588
14589         if (sip != NULL) {
14590                 /*
14591                  * Put in fields for the frame number of the frame to which
14592                  * this is a response or the frame with the response to this
14593                  * frame - if we know the frame number (i.e., it's not 0).
14594                  */
14595                 if(si.request){
14596                         if (sip->frame_res != 0)
14597                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
14598                 } else {
14599                         if (sip->frame_req != 0)
14600                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
14601                 }
14602         }
14603
14604         /* smb command */
14605         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);
14606         offset += 1;
14607
14608         if(flags2 & 0x4000){
14609                 /* handle NT 32 bit error code */
14610
14611                 nt_status = tvb_get_letohl(tvb, offset);
14612
14613                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
14614                         TRUE);
14615                 offset += 4;
14616
14617         } else {
14618                 /* handle DOS error code & class */
14619                 errclass = tvb_get_guint8(tvb, offset);
14620                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
14621                         errclass);
14622                 offset += 1;
14623
14624                 /* reserved byte */
14625                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
14626                 offset += 1;
14627
14628                 /* error code */
14629                 /* XXX - the type of this field depends on the value of
14630                  * "errcls", so there is isn't a single value_string array
14631                  * fo it, so there can't be a single field for it.
14632                  */
14633                 errcode = tvb_get_letohs(tvb, offset);
14634                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
14635                         offset, 2, errcode, "Error Code: %s",
14636                         decode_smb_error(errclass, errcode));
14637                 offset += 2;
14638         }
14639
14640         /* flags */
14641         offset = dissect_smb_flags(tvb, pinfo, htree, offset);
14642
14643         /* flags2 */
14644         offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
14645
14646         /*
14647          * The document at
14648          *
14649          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
14650          *
14651          * (a text version of "Microsoft Networks SMB FILE SHARING
14652          * PROTOCOL, Document Version 6.0p") says that:
14653          *
14654          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
14655          *      the "High Part of PID";
14656          *
14657          *      the next four bytes are reserved;
14658          *
14659          *      the next four bytes are, for SMB-over-IPX (with no
14660          *      NetBIOS involved) two bytes of Session ID and two bytes
14661          *      of SequenceNumber.
14662          *
14663          * If we ever implement SMB-over-IPX (which I suspect goes over
14664          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
14665          * document in question), we'd probably want to have some way
14666          * to determine whether this is SMB-over-IPX or not (which could
14667          * be done by adding a PT_IPXSOCKET port type, having the
14668          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
14669          * and having the SMB dissector check for a port type of
14670          * PT_IPXSOCKET and for "pinfo->match_port" being either
14671          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
14672          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
14673          */
14674
14675         /* 12 reserved bytes */
14676         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
14677         offset += 12;
14678
14679         /* TID */
14680         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
14681         offset += 2;
14682
14683         /* PID */
14684         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
14685         offset += 2;
14686
14687         /* UID */
14688         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
14689         offset += 2;
14690
14691         /* MID */
14692         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
14693         offset += 2;
14694
14695         pinfo->private_data = &si;
14696         dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
14697
14698         /* Append error info from this packet to info string. */
14699         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
14700                 if (flags2 & 0x4000) {
14701                         /*
14702                          * The status is an NT status code; was there
14703                          * an error?
14704                          */
14705                         if (nt_status != 0) {
14706                                 /*
14707                                  * Yes.
14708                                  */
14709                                 col_append_fstr(
14710                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14711                                         val_to_str(nt_status, NT_errors,
14712                                             "Unknown (0x%08X)"));
14713                         }
14714                 } else {
14715                         /*
14716                          * The status is a DOS error class and code; was
14717                          * there an error?
14718                          */
14719                         if (errclass != SMB_SUCCESS) {
14720                                 /*
14721                                  * Yes.
14722                                  */
14723                                 col_append_fstr(
14724                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14725                                         decode_smb_error(errclass, errcode));
14726                         }
14727                 }
14728         }
14729
14730         return TRUE;
14731 }
14732
14733 void
14734 proto_register_smb(void)
14735 {
14736         static hf_register_info hf[] = {
14737         { &hf_smb_cmd,
14738                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
14739                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
14740
14741         { &hf_smb_word_count,
14742                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
14743                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
14744
14745         { &hf_smb_byte_count,
14746                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
14747                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
14748
14749         { &hf_smb_response_to,
14750                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
14751                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
14752
14753         { &hf_smb_response_in,
14754                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
14755                 NULL, 0, "The response to this packet is in this packet", HFILL }},
14756
14757         { &hf_smb_continuation_to,
14758                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
14759                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
14760
14761         { &hf_smb_nt_status,
14762                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
14763                 VALS(NT_errors), 0, "NT Status code", HFILL }},
14764
14765         { &hf_smb_error_class,
14766                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
14767                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
14768
14769         { &hf_smb_error_code,
14770                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
14771                 NULL, 0, "DOS Error Code", HFILL }},
14772
14773         { &hf_smb_reserved,
14774                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
14775                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
14776
14777         { &hf_smb_pid,
14778                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
14779                 NULL, 0, "Process ID", HFILL }},
14780
14781         { &hf_smb_tid,
14782                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
14783                 NULL, 0, "Tree ID", HFILL }},
14784
14785         { &hf_smb_uid,
14786                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
14787                 NULL, 0, "User ID", HFILL }},
14788
14789         { &hf_smb_mid,
14790                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
14791                 NULL, 0, "Multiplex ID", HFILL }},
14792
14793         { &hf_smb_flags_lock,
14794                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
14795                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
14796
14797         { &hf_smb_flags_receive_buffer,
14798                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
14799                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
14800
14801         { &hf_smb_flags_caseless,
14802                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
14803                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
14804
14805         { &hf_smb_flags_canon,
14806                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
14807                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
14808
14809         { &hf_smb_flags_oplock,
14810                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
14811                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
14812
14813         { &hf_smb_flags_notify,
14814                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
14815                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
14816
14817         { &hf_smb_flags_response,
14818                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
14819                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
14820
14821         { &hf_smb_flags2_long_names_allowed,
14822                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
14823                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
14824
14825         { &hf_smb_flags2_ea,
14826                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
14827                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
14828
14829         { &hf_smb_flags2_sec_sig,
14830                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
14831                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
14832
14833         { &hf_smb_flags2_long_names_used,
14834                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
14835                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
14836
14837         { &hf_smb_flags2_esn,
14838                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
14839                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
14840
14841         { &hf_smb_flags2_dfs,
14842                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
14843                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
14844
14845         { &hf_smb_flags2_roe,
14846                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
14847                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
14848
14849         { &hf_smb_flags2_nt_error,
14850                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
14851                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
14852
14853         { &hf_smb_flags2_string,
14854                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
14855                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
14856
14857         { &hf_smb_buffer_format,
14858                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
14859                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
14860
14861         { &hf_smb_dialect_name,
14862                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
14863                 NULL, 0, "Name of dialect", HFILL }},
14864
14865         { &hf_smb_dialect_index,
14866                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
14867                 NULL, 0, "Index of selected dialect", HFILL }},
14868
14869         { &hf_smb_max_trans_buf_size,
14870                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
14871                 NULL, 0, "Maximum transmit buffer size", HFILL }},
14872
14873         { &hf_smb_max_mpx_count,
14874                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
14875                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
14876
14877         { &hf_smb_max_vcs_num,
14878                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
14879                 NULL, 0, "Maximum VCs between client and server", HFILL }},
14880
14881         { &hf_smb_session_key,
14882                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
14883                 NULL, 0, "Unique token identifying this session", HFILL }},
14884
14885         { &hf_smb_server_timezone,
14886                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
14887                 NULL, 0, "Current timezone at server.", HFILL }},
14888
14889         { &hf_smb_encryption_key_length,
14890                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
14891                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
14892
14893         { &hf_smb_encryption_key,
14894                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
14895                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
14896
14897         { &hf_smb_primary_domain,
14898                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
14899                 NULL, 0, "The server's primary domain", HFILL }},
14900
14901         { &hf_smb_max_raw_buf_size,
14902                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
14903                 NULL, 0, "Maximum raw buffer size", HFILL }},
14904
14905         { &hf_smb_server_guid,
14906                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
14907                 NULL, 0, "Globally unique identifier for this server", HFILL }},
14908
14909         { &hf_smb_security_blob_len,
14910                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
14911                 NULL, 0, "Security blob length", HFILL }},
14912
14913         { &hf_smb_security_blob,
14914                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
14915                 NULL, 0, "Security blob", HFILL }},
14916
14917         { &hf_smb_sm_mode16,
14918                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
14919                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14920
14921         { &hf_smb_sm_password16,
14922                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
14923                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14924
14925         { &hf_smb_sm_mode,
14926                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
14927                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14928
14929         { &hf_smb_sm_password,
14930                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
14931                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14932
14933         { &hf_smb_sm_signatures,
14934                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
14935                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
14936
14937         { &hf_smb_sm_sig_required,
14938                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
14939                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
14940
14941         { &hf_smb_rm_read,
14942                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
14943                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
14944
14945         { &hf_smb_rm_write,
14946                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
14947                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
14948
14949         { &hf_smb_server_date_time,
14950                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
14951                 NULL, 0, "Current date and time at server", HFILL }},
14952
14953         { &hf_smb_server_smb_date,
14954                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
14955                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
14956
14957         { &hf_smb_server_smb_time,
14958                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
14959                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
14960
14961         { &hf_smb_server_cap_raw_mode,
14962                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
14963                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
14964
14965         { &hf_smb_server_cap_mpx_mode,
14966                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
14967                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
14968
14969         { &hf_smb_server_cap_unicode,
14970                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
14971                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
14972
14973         { &hf_smb_server_cap_large_files,
14974                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
14975                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
14976
14977         { &hf_smb_server_cap_nt_smbs,
14978                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
14979                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
14980
14981         { &hf_smb_server_cap_rpc_remote_apis,
14982                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
14983                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
14984
14985         { &hf_smb_server_cap_nt_status,
14986                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
14987                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
14988
14989         { &hf_smb_server_cap_level_ii_oplocks,
14990                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
14991                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
14992
14993         { &hf_smb_server_cap_lock_and_read,
14994                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
14995                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
14996
14997         { &hf_smb_server_cap_nt_find,
14998                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
14999                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15000
15001         { &hf_smb_server_cap_dfs,
15002                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15003                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15004
15005         { &hf_smb_server_cap_infolevel_passthru,
15006                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15007                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15008
15009         { &hf_smb_server_cap_large_readx,
15010                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15011                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15012
15013         { &hf_smb_server_cap_large_writex,
15014                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15015                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15016
15017         { &hf_smb_server_cap_unix,
15018                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15019                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15020
15021         { &hf_smb_server_cap_reserved,
15022                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15023                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15024
15025         { &hf_smb_server_cap_bulk_transfer,
15026                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15027                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15028
15029         { &hf_smb_server_cap_compressed_data,
15030                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15031                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15032
15033         { &hf_smb_server_cap_extended_security,
15034                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
15035                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
15036
15037         { &hf_smb_system_time,
15038                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
15039                 NULL, 0, "System Time", HFILL }},
15040
15041         { &hf_smb_unknown,
15042                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
15043                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
15044
15045         { &hf_smb_dir_name,
15046                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
15047                 NULL, 0, "SMB Directory Name", HFILL }},
15048
15049         { &hf_smb_echo_count,
15050                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
15051                 NULL, 0, "Number of times to echo data back", HFILL }},
15052
15053         { &hf_smb_echo_data,
15054                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
15055                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
15056
15057         { &hf_smb_echo_seq_num,
15058                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
15059                 NULL, 0, "Sequence number for this echo response", HFILL }},
15060
15061         { &hf_smb_max_buf_size,
15062                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
15063                 NULL, 0, "Max client buffer size", HFILL }},
15064
15065         { &hf_smb_path,
15066                 { "Path", "smb.path", FT_STRING, BASE_NONE,
15067                 NULL, 0, "Path. Server name and share name", HFILL }},
15068
15069         { &hf_smb_service,
15070                 { "Service", "smb.service", FT_STRING, BASE_NONE,
15071                 NULL, 0, "Service name", HFILL }},
15072
15073         { &hf_smb_password,
15074                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15075                 NULL, 0, "Password", HFILL }},
15076
15077         { &hf_smb_ansi_password,
15078                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15079                 NULL, 0, "ANSI Password", HFILL }},
15080
15081         { &hf_smb_unicode_password,
15082                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15083                 NULL, 0, "Unicode Password", HFILL }},
15084
15085         { &hf_smb_move_flags_file,
15086                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15087                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15088
15089         { &hf_smb_move_flags_dir,
15090                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15091                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15092
15093         { &hf_smb_move_flags_verify,
15094                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15095                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15096
15097         { &hf_smb_move_files_moved,
15098                 { "Files Moved", "smb.move.files_moved", FT_UINT16, BASE_DEC,
15099                 NULL, 0, "Number of files moved", HFILL }},
15100
15101         { &hf_smb_count,
15102                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
15103                 NULL, 0, "Count number of items/bytes", HFILL }},
15104
15105         { &hf_smb_file_name,
15106                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
15107                 NULL, 0, "File Name", HFILL }},
15108
15109         { &hf_smb_open_function_create,
15110                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
15111                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
15112
15113         { &hf_smb_open_function_open,
15114                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
15115                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
15116
15117         { &hf_smb_fid,
15118                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
15119                 NULL, 0, "FID: File ID", HFILL }},
15120
15121         { &hf_smb_file_attr_read_only_16bit,
15122                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
15123                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15124
15125         { &hf_smb_file_attr_read_only_8bit,
15126                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
15127                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15128
15129         { &hf_smb_file_attr_hidden_16bit,
15130                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
15131                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15132
15133         { &hf_smb_file_attr_hidden_8bit,
15134                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
15135                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15136
15137         { &hf_smb_file_attr_system_16bit,
15138                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
15139                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15140
15141         { &hf_smb_file_attr_system_8bit,
15142                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
15143                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15144
15145         { &hf_smb_file_attr_volume_16bit,
15146                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
15147                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15148
15149         { &hf_smb_file_attr_volume_8bit,
15150                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
15151                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
15152
15153         { &hf_smb_file_attr_directory_16bit,
15154                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
15155                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15156
15157         { &hf_smb_file_attr_directory_8bit,
15158                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
15159                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15160
15161         { &hf_smb_file_attr_archive_16bit,
15162                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
15163                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15164
15165         { &hf_smb_file_attr_archive_8bit,
15166                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
15167                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15168
15169         { &hf_smb_file_attr_device,
15170                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
15171                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15172
15173         { &hf_smb_file_attr_normal,
15174                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
15175                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15176
15177         { &hf_smb_file_attr_temporary,
15178                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
15179                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15180
15181         { &hf_smb_file_attr_sparse,
15182                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
15183                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15184
15185         { &hf_smb_file_attr_reparse,
15186                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
15187                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15188
15189         { &hf_smb_file_attr_compressed,
15190                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
15191                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15192
15193         { &hf_smb_file_attr_offline,
15194                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
15195                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15196
15197         { &hf_smb_file_attr_not_content_indexed,
15198                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
15199                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15200
15201         { &hf_smb_file_attr_encrypted,
15202                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
15203                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15204
15205         { &hf_smb_file_size,
15206                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
15207                 NULL, 0, "File Size", HFILL }},
15208
15209         { &hf_smb_search_attribute_read_only,
15210                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
15211                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
15212
15213         { &hf_smb_search_attribute_hidden,
15214                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
15215                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
15216
15217         { &hf_smb_search_attribute_system,
15218                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
15219                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
15220
15221         { &hf_smb_search_attribute_volume,
15222                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
15223                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
15224
15225         { &hf_smb_search_attribute_directory,
15226                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
15227                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
15228
15229         { &hf_smb_search_attribute_archive,
15230                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
15231                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
15232
15233         { &hf_smb_access_mode,
15234                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
15235                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
15236
15237         { &hf_smb_access_sharing,
15238                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
15239                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
15240
15241         { &hf_smb_access_locality,
15242                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
15243                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
15244
15245         { &hf_smb_access_caching,
15246                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
15247                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
15248
15249         { &hf_smb_access_writetru,
15250                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
15251                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
15252
15253         { &hf_smb_create_time,
15254                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
15255                 NULL, 0, "Creation Time", HFILL }},
15256
15257         { &hf_smb_create_dos_date,
15258                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
15259                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
15260
15261         { &hf_smb_create_dos_time,
15262                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
15263                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
15264
15265         { &hf_smb_last_write_time,
15266                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
15267                 NULL, 0, "Time this file was last written to", HFILL }},
15268
15269         { &hf_smb_last_write_dos_date,
15270                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
15271                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
15272
15273         { &hf_smb_last_write_dos_time,
15274                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
15275                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
15276
15277         { &hf_smb_old_file_name,
15278                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
15279                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
15280
15281         { &hf_smb_offset,
15282                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
15283                 NULL, 0, "Offset in file", HFILL }},
15284
15285         { &hf_smb_remaining,
15286                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
15287                 NULL, 0, "Remaining number of bytes", HFILL }},
15288
15289         { &hf_smb_padding,
15290                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
15291                 NULL, 0, "Padding or unknown data", HFILL }},
15292
15293         { &hf_smb_file_data,
15294                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
15295                 NULL, 0, "Data read/written to the file", HFILL }},
15296
15297         { &hf_smb_total_data_len,
15298                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
15299                 NULL, 0, "Total length of data", HFILL }},
15300
15301         { &hf_smb_data_len,
15302                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
15303                 NULL, 0, "Length of data", HFILL }},
15304
15305         { &hf_smb_seek_mode,
15306                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
15307                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
15308
15309         { &hf_smb_access_time,
15310                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
15311                 NULL, 0, "Last Access Time", HFILL }},
15312
15313         { &hf_smb_access_dos_date,
15314                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
15315                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
15316
15317         { &hf_smb_access_dos_time,
15318                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
15319                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
15320
15321         { &hf_smb_data_size,
15322                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
15323                 NULL, 0, "Data Size", HFILL }},
15324
15325         { &hf_smb_alloc_size,
15326                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
15327                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15328
15329         { &hf_smb_max_count,
15330                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
15331                 NULL, 0, "Maximum Count", HFILL }},
15332
15333         { &hf_smb_min_count,
15334                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
15335                 NULL, 0, "Minimum Count", HFILL }},
15336
15337         { &hf_smb_timeout,
15338                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
15339                 NULL, 0, "Timeout in miliseconds", HFILL }},
15340
15341         { &hf_smb_high_offset,
15342                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
15343                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
15344
15345         { &hf_smb_units,
15346                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
15347                 NULL, 0, "Total number of units at server", HFILL }},
15348
15349         { &hf_smb_bpu,
15350                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
15351                 NULL, 0, "Blocks per unit at server", HFILL }},
15352
15353         { &hf_smb_blocksize,
15354                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
15355                 NULL, 0, "Block size (in bytes) at server", HFILL }},
15356
15357         { &hf_smb_freeunits,
15358                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
15359                 NULL, 0, "Number of free units at server", HFILL }},
15360
15361         { &hf_smb_data_offset,
15362                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15363                 NULL, 0, "Data Offset", HFILL }},
15364
15365         { &hf_smb_dcm,
15366                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
15367                 NULL, 0, "Data Compaction Mode", HFILL }},
15368
15369         { &hf_smb_request_mask,
15370                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
15371                 NULL, 0, "Connectionless mode mask", HFILL }},
15372
15373         { &hf_smb_response_mask,
15374                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
15375                 NULL, 0, "Connectionless mode mask", HFILL }},
15376
15377         { &hf_smb_sid,
15378                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
15379                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
15380
15381         { &hf_smb_write_mode_write_through,
15382                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
15383                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
15384
15385         { &hf_smb_write_mode_return_remaining,
15386                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
15387                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
15388
15389         { &hf_smb_write_mode_raw,
15390                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
15391                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
15392
15393         { &hf_smb_write_mode_message_start,
15394                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
15395                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
15396
15397         { &hf_smb_write_mode_connectionless,
15398                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
15399                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
15400
15401         { &hf_smb_resume_key_len,
15402                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
15403                 NULL, 0, "Resume Key length", HFILL }},
15404
15405         { &hf_smb_resume_server_cookie,
15406                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
15407                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
15408
15409         { &hf_smb_resume_client_cookie,
15410                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
15411                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
15412
15413         { &hf_smb_andxoffset,
15414                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
15415                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
15416
15417         { &hf_smb_lock_type_large,
15418                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
15419                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
15420
15421         { &hf_smb_lock_type_cancel,
15422                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
15423                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
15424
15425         { &hf_smb_lock_type_change,
15426                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
15427                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
15428
15429         { &hf_smb_lock_type_oplock,
15430                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
15431                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
15432
15433         { &hf_smb_lock_type_shared,
15434                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
15435                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
15436
15437         { &hf_smb_locking_ol,
15438                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
15439                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
15440
15441         { &hf_smb_number_of_locks,
15442                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
15443                 NULL, 0, "Number of lock requests in this request", HFILL }},
15444
15445         { &hf_smb_number_of_unlocks,
15446                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
15447                 NULL, 0, "Number of unlock requests in this request", HFILL }},
15448
15449         { &hf_smb_lock_long_length,
15450                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
15451                 NULL, 0, "Length of lock/unlock region", HFILL }},
15452
15453         { &hf_smb_lock_long_offset,
15454                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
15455                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
15456
15457         { &hf_smb_file_type,
15458                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
15459                 VALS(filetype_vals), 0, "Type of file", HFILL }},
15460
15461         { &hf_smb_ipc_state_nonblocking,
15462                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
15463                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
15464
15465         { &hf_smb_ipc_state_endpoint,
15466                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
15467                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
15468
15469         { &hf_smb_ipc_state_pipe_type,
15470                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
15471                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
15472
15473         { &hf_smb_ipc_state_read_mode,
15474                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
15475                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
15476
15477         { &hf_smb_ipc_state_icount,
15478                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
15479                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
15480
15481         { &hf_smb_server_fid,
15482                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
15483                 NULL, 0, "Server unique File ID", HFILL }},
15484
15485         { &hf_smb_open_flags_add_info,
15486                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
15487                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
15488
15489         { &hf_smb_open_flags_ex_oplock,
15490                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
15491                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
15492
15493         { &hf_smb_open_flags_batch_oplock,
15494                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
15495                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
15496
15497         { &hf_smb_open_flags_ealen,
15498                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
15499                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
15500
15501         { &hf_smb_open_action_open,
15502                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
15503                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
15504
15505         { &hf_smb_open_action_lock,
15506                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
15507                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
15508
15509         { &hf_smb_vc_num,
15510                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
15511                 NULL, 0, "VC Number", HFILL }},
15512
15513         { &hf_smb_password_len,
15514                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
15515                 NULL, 0, "Length of password", HFILL }},
15516
15517         { &hf_smb_ansi_password_len,
15518                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
15519                 NULL, 0, "Length of ANSI password", HFILL }},
15520
15521         { &hf_smb_unicode_password_len,
15522                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
15523                 NULL, 0, "Length of Unicode password", HFILL }},
15524
15525         { &hf_smb_account,
15526                 { "Account", "smb.account", FT_STRING, BASE_NONE,
15527                 NULL, 0, "Account, username", HFILL }},
15528
15529         { &hf_smb_os,
15530                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
15531                 NULL, 0, "Which OS we are running", HFILL }},
15532
15533         { &hf_smb_lanman,
15534                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
15535                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
15536
15537         { &hf_smb_setup_action_guest,
15538                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
15539                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
15540
15541         { &hf_smb_fs,
15542                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
15543                 NULL, 0, "Native File System", HFILL }},
15544
15545         { &hf_smb_connect_flags_dtid,
15546                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
15547                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
15548
15549         { &hf_smb_connect_support_search,
15550                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
15551                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
15552
15553         { &hf_smb_connect_support_in_dfs,
15554                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
15555                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
15556
15557         { &hf_smb_max_setup_count,
15558                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
15559                 NULL, 0, "Maximum number of setup words to return", HFILL }},
15560
15561         { &hf_smb_total_param_count,
15562                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
15563                 NULL, 0, "Total number of parameter bytes", HFILL }},
15564
15565         { &hf_smb_total_data_count,
15566                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
15567                 NULL, 0, "Total number of data bytes", HFILL }},
15568
15569         { &hf_smb_max_param_count,
15570                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
15571                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
15572
15573         { &hf_smb_max_data_count,
15574                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
15575                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
15576
15577         { &hf_smb_param_disp16,
15578                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
15579                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15580
15581         { &hf_smb_param_count16,
15582                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
15583                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15584
15585         { &hf_smb_param_offset16,
15586                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
15587                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15588
15589         { &hf_smb_param_disp32,
15590                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
15591                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15592
15593         { &hf_smb_param_count32,
15594                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
15595                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15596
15597         { &hf_smb_param_offset32,
15598                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
15599                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15600
15601         { &hf_smb_data_count16,
15602                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
15603                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15604
15605         { &hf_smb_data_disp16,
15606                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
15607                 NULL, 0, "Data Displacement", HFILL }},
15608
15609         { &hf_smb_data_offset16,
15610                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15611                 NULL, 0, "Data Offset", HFILL }},
15612
15613         { &hf_smb_data_count32,
15614                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
15615                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15616
15617         { &hf_smb_data_disp32,
15618                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
15619                 NULL, 0, "Data Displacement", HFILL }},
15620
15621         { &hf_smb_data_offset32,
15622                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
15623                 NULL, 0, "Data Offset", HFILL }},
15624
15625         { &hf_smb_setup_count,
15626                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
15627                 NULL, 0, "Number of setup words in this buffer", HFILL }},
15628
15629         { &hf_smb_nt_trans_subcmd,
15630                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
15631                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
15632
15633         { &hf_smb_nt_ioctl_function_code,
15634                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
15635                 NULL, 0, "NT IOCTL function code", HFILL }},
15636
15637         { &hf_smb_nt_ioctl_isfsctl,
15638                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
15639                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
15640
15641         { &hf_smb_nt_ioctl_flags_root_handle,
15642                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
15643                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
15644
15645         { &hf_smb_nt_ioctl_data,
15646                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
15647                 NULL, 0, "Data for the IOCTL call", HFILL }},
15648
15649         { &hf_smb_nt_notify_action,
15650                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
15651                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
15652
15653         { &hf_smb_nt_notify_watch_tree,
15654                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
15655                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
15656
15657         { &hf_smb_nt_notify_stream_write,
15658                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
15659                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
15660
15661         { &hf_smb_nt_notify_stream_size,
15662                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
15663                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
15664
15665         { &hf_smb_nt_notify_stream_name,
15666                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
15667                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
15668
15669         { &hf_smb_nt_notify_security,
15670                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
15671                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
15672
15673         { &hf_smb_nt_notify_ea,
15674                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
15675                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
15676
15677         { &hf_smb_nt_notify_creation,
15678                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
15679                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
15680
15681         { &hf_smb_nt_notify_last_access,
15682                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
15683                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
15684
15685         { &hf_smb_nt_notify_last_write,
15686                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
15687                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
15688
15689         { &hf_smb_nt_notify_size,
15690                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
15691                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
15692
15693         { &hf_smb_nt_notify_attributes,
15694                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
15695                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
15696
15697         { &hf_smb_nt_notify_dir_name,
15698                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
15699                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
15700
15701         { &hf_smb_nt_notify_file_name,
15702                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
15703                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
15704
15705         { &hf_smb_root_dir_fid,
15706                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
15707                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
15708
15709         { &hf_smb_alloc_size64,
15710                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
15711                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15712
15713         { &hf_smb_nt_create_disposition,
15714                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
15715                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
15716
15717         { &hf_smb_sd_length,
15718                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
15719                 NULL, 0, "Total length of security descriptor", HFILL }},
15720
15721         { &hf_smb_ea_length,
15722                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
15723                 NULL, 0, "Total EA length for opened file", HFILL }},
15724
15725         { &hf_smb_file_name_len,
15726                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
15727                 NULL, 0, "Length of File Name", HFILL }},
15728
15729         { &hf_smb_nt_impersonation_level,
15730                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
15731                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
15732
15733         { &hf_smb_nt_security_flags_context_tracking,
15734                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
15735                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
15736
15737         { &hf_smb_nt_security_flags_effective_only,
15738                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
15739                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
15740
15741         { &hf_smb_nt_access_mask_generic_read,
15742                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
15743                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
15744
15745         { &hf_smb_nt_access_mask_generic_write,
15746                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
15747                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
15748
15749         { &hf_smb_nt_access_mask_generic_execute,
15750                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
15751                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
15752
15753         { &hf_smb_nt_access_mask_generic_all,
15754                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
15755                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
15756
15757         { &hf_smb_nt_access_mask_maximum_allowed,
15758                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
15759                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
15760
15761         { &hf_smb_nt_access_mask_system_security,
15762                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
15763                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
15764
15765         { &hf_smb_nt_access_mask_synchronize,
15766                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
15767                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
15768
15769         { &hf_smb_nt_access_mask_write_owner,
15770                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
15771                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
15772
15773         { &hf_smb_nt_access_mask_write_dac,
15774                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
15775                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
15776
15777         { &hf_smb_nt_access_mask_read_control,
15778                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
15779                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
15780
15781         { &hf_smb_nt_access_mask_delete,
15782                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
15783                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
15784
15785         { &hf_smb_nt_access_mask_write_attributes,
15786                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
15787                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
15788
15789         { &hf_smb_nt_access_mask_read_attributes,
15790                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
15791                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
15792
15793         { &hf_smb_nt_access_mask_delete_child,
15794                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
15795                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
15796
15797         /*
15798          * "Execute" for files, "traverse" for directories.
15799          */
15800         { &hf_smb_nt_access_mask_execute,
15801                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
15802                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
15803
15804         { &hf_smb_nt_access_mask_write_ea,
15805                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
15806                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
15807
15808         { &hf_smb_nt_access_mask_read_ea,
15809                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
15810                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
15811
15812         /*
15813          * "Append data" for files, "add subdirectory" for directories,
15814          * "create pipe instance" for named pipes.
15815          */
15816         { &hf_smb_nt_access_mask_append,
15817                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
15818                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
15819
15820         /*
15821          * "Write data" for files and pipes, "add file" for directory.
15822          */
15823         { &hf_smb_nt_access_mask_write,
15824                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
15825                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
15826
15827         /*
15828          * "Read data" for files and pipes, "list directory" for directory.
15829          */
15830         { &hf_smb_nt_access_mask_read,
15831                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
15832                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
15833
15834         { &hf_smb_nt_create_bits_oplock,
15835                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
15836                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
15837
15838         { &hf_smb_nt_create_bits_boplock,
15839                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
15840                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
15841
15842         { &hf_smb_nt_create_bits_dir,
15843                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
15844                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
15845
15846         { &hf_smb_nt_create_options_directory_file,
15847                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
15848                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
15849
15850         { &hf_smb_nt_create_options_write_through,
15851                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
15852                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
15853
15854         { &hf_smb_nt_create_options_sequential_only,
15855                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
15856                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
15857
15858         { &hf_smb_nt_create_options_sync_io_alert,
15859                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
15860                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
15861
15862         { &hf_smb_nt_create_options_sync_io_nonalert,
15863                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
15864                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
15865
15866         { &hf_smb_nt_create_options_non_directory_file,
15867                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
15868                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
15869
15870         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
15871            and "NtOpenFile()"; is that sent over the wire?  Network
15872            Monitor thinks so, but its author may just have grabbed
15873            the flag bits from a system header file. */
15874
15875         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
15876            and "NtOpenFile()"; is that sent over the wire?  NetMon
15877            thinks so, but see previous comment. */
15878
15879         { &hf_smb_nt_create_options_no_ea_knowledge,
15880                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
15881                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
15882
15883         { &hf_smb_nt_create_options_eight_dot_three_only,
15884                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
15885                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
15886
15887         { &hf_smb_nt_create_options_random_access,
15888                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
15889                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
15890
15891         { &hf_smb_nt_create_options_delete_on_close,
15892                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
15893                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
15894
15895         /* 0x00002000 is "open by FID", or something such as that (which
15896            I suspect is like "open by inumber" on UNIX), at least in
15897            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
15898            wire?  NetMon thinks so, but see previous comment. */
15899
15900         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
15901            and "NtOpenFile()"; is that sent over the wire?  NetMon
15902            thinks so, but see previous comment. */
15903
15904         { &hf_smb_nt_share_access_read,
15905                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
15906                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
15907
15908         { &hf_smb_nt_share_access_write,
15909                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
15910                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
15911
15912         { &hf_smb_nt_share_access_delete,
15913                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
15914                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
15915
15916         { &hf_smb_file_eattr_read_only,
15917                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
15918                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15919
15920         { &hf_smb_file_eattr_hidden,
15921                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
15922                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15923
15924         { &hf_smb_file_eattr_system,
15925                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
15926                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15927
15928         { &hf_smb_file_eattr_volume,
15929                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
15930                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15931
15932         { &hf_smb_file_eattr_directory,
15933                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
15934                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15935
15936         { &hf_smb_file_eattr_archive,
15937                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
15938                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15939
15940         { &hf_smb_file_eattr_device,
15941                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
15942                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15943
15944         { &hf_smb_file_eattr_normal,
15945                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
15946                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15947
15948         { &hf_smb_file_eattr_temporary,
15949                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
15950                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15951
15952         { &hf_smb_file_eattr_sparse,
15953                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
15954                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15955
15956         { &hf_smb_file_eattr_reparse,
15957                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
15958                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15959
15960         { &hf_smb_file_eattr_compressed,
15961                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
15962                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15963
15964         { &hf_smb_file_eattr_offline,
15965                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
15966                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15967
15968         { &hf_smb_file_eattr_not_content_indexed,
15969                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
15970                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15971
15972         { &hf_smb_file_eattr_encrypted,
15973                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
15974                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15975
15976         { &hf_smb_file_eattr_write_through,
15977                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
15978                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
15979
15980         { &hf_smb_file_eattr_no_buffering,
15981                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
15982                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
15983
15984         { &hf_smb_file_eattr_random_access,
15985                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
15986                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
15987
15988         { &hf_smb_file_eattr_sequential_scan,
15989                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
15990                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
15991
15992         { &hf_smb_file_eattr_delete_on_close,
15993                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
15994                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
15995
15996         { &hf_smb_file_eattr_backup_semantics,
15997                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
15998                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
15999
16000         { &hf_smb_file_eattr_posix_semantics,
16001                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
16002                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
16003
16004         { &hf_smb_sec_desc_len,
16005                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
16006                 NULL, 0, "Security Descriptor Length", HFILL }},
16007
16008         { &hf_smb_nt_qsd_owner,
16009                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
16010                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
16011
16012         { &hf_smb_nt_qsd_group,
16013                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
16014                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
16015
16016         { &hf_smb_nt_qsd_dacl,
16017                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
16018                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
16019
16020         { &hf_smb_nt_qsd_sacl,
16021                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
16022                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
16023
16024         { &hf_smb_extended_attributes,
16025                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
16026                 NULL, 0, "Extended Attributes", HFILL }},
16027
16028         { &hf_smb_oplock_level,
16029                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
16030                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
16031
16032         { &hf_smb_create_action,
16033                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
16034                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
16035
16036         { &hf_smb_ea_error_offset,
16037                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
16038                 NULL, 0, "Offset into EA list if EA error", HFILL }},
16039
16040         { &hf_smb_end_of_file,
16041                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
16042                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
16043
16044         { &hf_smb_device_type,
16045                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
16046                 VALS(device_type_vals), 0, "Type of device", HFILL }},
16047
16048         { &hf_smb_is_directory,
16049                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
16050                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
16051
16052         { &hf_smb_next_entry_offset,
16053                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
16054                 NULL, 0, "Offset to next entry", HFILL }},
16055
16056         { &hf_smb_change_time,
16057                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
16058                 NULL, 0, "Last Change Time", HFILL }},
16059
16060         { &hf_smb_setup_len,
16061                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
16062                 NULL, 0, "Length of prionter setup data", HFILL }},
16063
16064         { &hf_smb_print_mode,
16065                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
16066                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
16067
16068         { &hf_smb_print_identifier,
16069                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
16070                 NULL, 0, "Identifier string for this print job", HFILL }},
16071
16072         { &hf_smb_restart_index,
16073                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16074                 NULL, 0, "Index of entry after last returned", HFILL }},
16075
16076         { &hf_smb_print_queue_date,
16077                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16078                 NULL, 0, "Date when this entry was queued", HFILL }},
16079
16080         { &hf_smb_print_queue_dos_date,
16081                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16082                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16083
16084         { &hf_smb_print_queue_dos_time,
16085                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
16086                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
16087
16088         { &hf_smb_print_status,
16089                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
16090                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
16091
16092         { &hf_smb_print_spool_file_number,
16093                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
16094                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
16095
16096         { &hf_smb_print_spool_file_size,
16097                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
16098                 NULL, 0, "Number of bytes in spool file", HFILL }},
16099
16100         { &hf_smb_print_spool_file_name,
16101                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
16102                 NULL, 0, "Name of client that submitted this job", HFILL }},
16103
16104         { &hf_smb_start_index,
16105                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
16106                 NULL, 0, "First queue entry to return", HFILL }},
16107
16108         { &hf_smb_cancel_to,
16109                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
16110                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
16111
16112         { &hf_smb_trans2_subcmd,
16113                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16114                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16115
16116         { &hf_smb_trans_name,
16117                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
16118                 NULL, 0, "Name of transaction", HFILL }},
16119
16120         { &hf_smb_transaction_flags_dtid,
16121                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
16122                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
16123
16124         { &hf_smb_transaction_flags_owt,
16125                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
16126                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
16127
16128         { &hf_smb_search_count,
16129                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
16130                 NULL, 0, "Maximum number of search entries to return", HFILL }},
16131
16132         { &hf_smb_search_pattern,
16133                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
16134                 NULL, 0, "Search Pattern", HFILL }},
16135
16136         { &hf_smb_ff2_backup,
16137                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
16138                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
16139
16140         { &hf_smb_ff2_continue,
16141                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
16142                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
16143
16144         { &hf_smb_ff2_resume,
16145                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
16146                 TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
16147
16148         { &hf_smb_ff2_close_eos,
16149                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
16150                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
16151
16152         { &hf_smb_ff2_close,
16153                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
16154                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
16155
16156         { &hf_smb_ff2_information_level,
16157                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
16158                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
16159
16160         { &hf_smb_qpi_loi,
16161                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
16162                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
16163
16164         { &hf_smb_storage_type,
16165                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
16166                 NULL, 0, "Type of storage", HFILL }},
16167
16168         { &hf_smb_resume,
16169                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
16170                 NULL, 0, "Resume Key", HFILL }},
16171
16172         { &hf_smb_max_referral_level,
16173                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
16174                 NULL, 0, "Latest referral version number understood", HFILL }},
16175
16176         { &hf_smb_qfsi_information_level,
16177                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
16178                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
16179
16180         { &hf_smb_nt_rename_level,
16181                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
16182                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
16183
16184         { &hf_smb_cluster_count,
16185                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
16186                 NULL, 0, "Number of clusters", HFILL }},
16187
16188         { &hf_smb_ea_size,
16189                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
16190                 NULL, 0, "Size of file's EA information", HFILL }},
16191
16192         { &hf_smb_list_length,
16193                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
16194                 NULL, 0, "Length of the remaining data", HFILL }},
16195
16196         { &hf_smb_number_of_links,
16197                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
16198                 NULL, 0, "Number of hard links to the file", HFILL }},
16199
16200         { &hf_smb_delete_pending,
16201                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
16202                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
16203
16204         { &hf_smb_index_number,
16205                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
16206                 NULL, 0, "File system unique identifier", HFILL }},
16207
16208         { &hf_smb_current_offset,
16209                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
16210                 NULL, 0, "Current offset in the file", HFILL }},
16211
16212         { &hf_smb_t2_alignment,
16213                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
16214                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
16215
16216         { &hf_smb_t2_stream_name_length,
16217                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
16218                 NULL, 0, "Length of stream name", HFILL }},
16219
16220         { &hf_smb_t2_stream_size,
16221                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
16222                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16223
16224         { &hf_smb_t2_stream_name,
16225                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
16226                 NULL, 0, "Name of the stream", HFILL }},
16227
16228         { &hf_smb_t2_compressed_file_size,
16229                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
16230                 NULL, 0, "Size of the compressed file", HFILL }},
16231
16232         { &hf_smb_t2_compressed_format,
16233                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
16234                 NULL, 0, "Compression algorithm used", HFILL }},
16235
16236         { &hf_smb_t2_compressed_unit_shift,
16237                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
16238                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16239
16240         { &hf_smb_t2_compressed_chunk_shift,
16241                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
16242                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16243
16244         { &hf_smb_t2_compressed_cluster_shift,
16245                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
16246                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16247
16248         { &hf_smb_dfs_path_consumed,
16249                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
16250                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
16251
16252         { &hf_smb_dfs_num_referrals,
16253                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
16254                 NULL, 0, "Number of referrals in this pdu", HFILL }},
16255
16256         { &hf_smb_get_dfs_server_hold_storage,
16257                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
16258                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
16259
16260         { &hf_smb_get_dfs_fielding,
16261                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
16262                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
16263
16264         { &hf_smb_dfs_referral_version,
16265                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
16266                 NULL, 0, "Version of referral element", HFILL }},
16267
16268         { &hf_smb_dfs_referral_size,
16269                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
16270                 NULL, 0, "Size of referral element", HFILL }},
16271
16272         { &hf_smb_dfs_referral_server_type,
16273                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
16274                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
16275
16276         { &hf_smb_dfs_referral_flags_strip,
16277                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
16278                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
16279
16280         { &hf_smb_dfs_referral_node_offset,
16281                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
16282                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
16283
16284         { &hf_smb_dfs_referral_node,
16285                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
16286                 NULL, 0, "Name of entity to visit next", HFILL }},
16287
16288         { &hf_smb_dfs_referral_proximity,
16289                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
16290                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
16291
16292         { &hf_smb_dfs_referral_ttl,
16293                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
16294                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
16295
16296         { &hf_smb_dfs_referral_path_offset,
16297                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
16298                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
16299
16300         { &hf_smb_dfs_referral_path,
16301                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
16302                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
16303
16304         { &hf_smb_dfs_referral_alt_path_offset,
16305                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
16306                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
16307
16308         { &hf_smb_dfs_referral_alt_path,
16309                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
16310                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
16311
16312         { &hf_smb_end_of_search,
16313                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
16314                 NULL, 0, "Was last entry returned?", HFILL }},
16315
16316         { &hf_smb_last_name_offset,
16317                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
16318                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
16319
16320         { &hf_smb_file_index,
16321                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
16322                 NULL, 0, "File index", HFILL }},
16323
16324         { &hf_smb_short_file_name,
16325                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
16326                 NULL, 0, "Short (8.3) File Name", HFILL }},
16327
16328         { &hf_smb_short_file_name_len,
16329                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
16330                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
16331
16332         { &hf_smb_fs_id,
16333                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
16334                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
16335
16336         { &hf_smb_sector_unit,
16337                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
16338                 NULL, 0, "Sectors per allocation unit", HFILL }},
16339
16340         { &hf_smb_fs_units,
16341                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
16342                 NULL, 0, "Total number of units on this filesystem", HFILL }},
16343
16344         { &hf_smb_fs_sector,
16345                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
16346                 NULL, 0, "Bytes per sector", HFILL }},
16347
16348         { &hf_smb_avail_units,
16349                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
16350                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
16351
16352         { &hf_smb_volume_serial_num,
16353                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
16354                 NULL, 0, "Volume serial number", HFILL }},
16355
16356         { &hf_smb_volume_label_len,
16357                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
16358                 NULL, 0, "Length of volume label", HFILL }},
16359
16360         { &hf_smb_volume_label,
16361                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
16362                 NULL, 0, "Volume label", HFILL }},
16363
16364         { &hf_smb_free_alloc_units64,
16365                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
16366                 NULL, 0, "Number of free allocation units", HFILL }},
16367
16368         { &hf_smb_soft_quota_limit,
16369                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
16370                 NULL, 0, "Soft Quota treshold", HFILL }},
16371
16372         { &hf_smb_hard_quota_limit,
16373                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
16374                 NULL, 0, "Hard Quota limit", HFILL }},
16375
16376         { &hf_smb_user_quota_used,
16377                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
16378                 NULL, 0, "How much Quota is used by this user", HFILL }},
16379
16380         { &hf_smb_max_name_len,
16381                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
16382                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
16383
16384         { &hf_smb_fs_name_len,
16385                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
16386                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
16387
16388         { &hf_smb_fs_name,
16389                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
16390                 NULL, 0, "Name of filesystem", HFILL }},
16391
16392         { &hf_smb_device_char_removable,
16393                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
16394                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
16395
16396         { &hf_smb_device_char_read_only,
16397                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
16398                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
16399
16400         { &hf_smb_device_char_floppy,
16401                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
16402                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
16403
16404         { &hf_smb_device_char_write_once,
16405                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
16406                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
16407
16408         { &hf_smb_device_char_remote,
16409                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
16410                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
16411
16412         { &hf_smb_device_char_mounted,
16413                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
16414                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
16415
16416         { &hf_smb_device_char_virtual,
16417                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
16418                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
16419
16420         { &hf_smb_fs_attr_css,
16421                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
16422                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
16423
16424         { &hf_smb_fs_attr_cpn,
16425                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
16426                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
16427
16428         { &hf_smb_fs_attr_pacls,
16429                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
16430                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
16431
16432         { &hf_smb_fs_attr_fc,
16433                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
16434                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
16435
16436         { &hf_smb_fs_attr_vq,
16437                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
16438                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
16439
16440         { &hf_smb_fs_attr_dim,
16441                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
16442                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
16443
16444         { &hf_smb_fs_attr_vic,
16445                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
16446                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
16447
16448         { &hf_smb_sec_desc_revision,
16449                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
16450                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
16451
16452         { &hf_smb_sid_revision,
16453                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
16454                 NULL, 0, "Version of SID structure", HFILL }},
16455
16456         { &hf_smb_sid_num_auth,
16457                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
16458                 NULL, 0, "Number of authorities for this SID", HFILL }},
16459
16460         { &hf_smb_acl_revision,
16461                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
16462                 NULL, 0, "Version of NT ACL structure", HFILL }},
16463
16464         { &hf_smb_acl_size,
16465                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
16466                 NULL, 0, "Size of NT ACL structure", HFILL }},
16467
16468         { &hf_smb_acl_num_aces,
16469                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
16470                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
16471
16472         { &hf_smb_user_quota_offset,
16473                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
16474                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
16475
16476         { &hf_smb_ace_type,
16477                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
16478                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
16479
16480         { &hf_smb_ace_size,
16481                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
16482                 NULL, 0, "Size of this ACE", HFILL }},
16483
16484         { &hf_smb_ace_flags_object_inherit,
16485                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
16486                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
16487
16488         { &hf_smb_ace_flags_container_inherit,
16489                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
16490                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
16491
16492         { &hf_smb_ace_flags_non_propagate_inherit,
16493                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
16494                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
16495
16496         { &hf_smb_ace_flags_inherit_only,
16497                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
16498                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
16499
16500         { &hf_smb_ace_flags_inherited_ace,
16501                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
16502                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
16503
16504         { &hf_smb_ace_flags_successful_access,
16505                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
16506                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
16507
16508         { &hf_smb_ace_flags_failed_access,
16509                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
16510                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
16511
16512         { &hf_smb_sec_desc_type_owner_defaulted,
16513                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
16514                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
16515
16516         { &hf_smb_sec_desc_type_group_defaulted,
16517                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
16518                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
16519
16520         { &hf_smb_sec_desc_type_dacl_present,
16521                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
16522                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
16523
16524         { &hf_smb_sec_desc_type_dacl_defaulted,
16525                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
16526                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
16527
16528         { &hf_smb_sec_desc_type_sacl_present,
16529                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
16530                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
16531
16532         { &hf_smb_sec_desc_type_sacl_defaulted,
16533                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
16534                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
16535
16536         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
16537                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
16538                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
16539
16540         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
16541                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
16542                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
16543
16544         { &hf_smb_sec_desc_type_dacl_auto_inherited,
16545                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
16546                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
16547
16548         { &hf_smb_sec_desc_type_sacl_auto_inherited,
16549                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
16550                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
16551
16552         { &hf_smb_sec_desc_type_dacl_protected,
16553                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
16554                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
16555
16556         { &hf_smb_sec_desc_type_sacl_protected,
16557                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
16558                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
16559
16560         { &hf_smb_sec_desc_type_self_relative,
16561                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
16562                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
16563
16564         { &hf_smb_quota_flags_deny_disk,
16565                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
16566                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
16567
16568         { &hf_smb_quota_flags_log_limit,
16569                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
16570                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
16571
16572         { &hf_smb_quota_flags_log_warning,
16573                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
16574                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
16575
16576         { &hf_smb_quota_flags_enabled,
16577                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
16578                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
16579
16580         };
16581         static gint *ett[] = {
16582                 &ett_smb,
16583                 &ett_smb_hdr,
16584                 &ett_smb_command,
16585                 &ett_smb_fileattributes,
16586                 &ett_smb_capabilities,
16587                 &ett_smb_aflags,
16588                 &ett_smb_dialect,
16589                 &ett_smb_dialects,
16590                 &ett_smb_mode,
16591                 &ett_smb_rawmode,
16592                 &ett_smb_flags,
16593                 &ett_smb_flags2,
16594                 &ett_smb_desiredaccess,
16595                 &ett_smb_search,
16596                 &ett_smb_file,
16597                 &ett_smb_openfunction,
16598                 &ett_smb_filetype,
16599                 &ett_smb_openaction,
16600                 &ett_smb_writemode,
16601                 &ett_smb_lock_type,
16602                 &ett_smb_ssetupandxaction,
16603                 &ett_smb_optionsup,
16604                 &ett_smb_time_date,
16605                 &ett_smb_move_flags,
16606                 &ett_smb_file_attributes,
16607                 &ett_smb_search_resume_key,
16608                 &ett_smb_search_dir_info,
16609                 &ett_smb_unlocks,
16610                 &ett_smb_unlock,
16611                 &ett_smb_locks,
16612                 &ett_smb_lock,
16613                 &ett_smb_open_flags,
16614                 &ett_smb_ipc_state,
16615                 &ett_smb_open_action,
16616                 &ett_smb_setup_action,
16617                 &ett_smb_connect_flags,
16618                 &ett_smb_connect_support_bits,
16619                 &ett_smb_nt_access_mask,
16620                 &ett_smb_nt_create_bits,
16621                 &ett_smb_nt_create_options,
16622                 &ett_smb_nt_share_access,
16623                 &ett_smb_nt_security_flags,
16624                 &ett_smb_nt_trans_setup,
16625                 &ett_smb_nt_trans_data,
16626                 &ett_smb_nt_trans_param,
16627                 &ett_smb_nt_notify_completion_filter,
16628                 &ett_smb_nt_ioctl_flags,
16629                 &ett_smb_security_information_mask,
16630                 &ett_smb_print_queue_entry,
16631                 &ett_smb_transaction_flags,
16632                 &ett_smb_transaction_params,
16633                 &ett_smb_find_first2_flags,
16634                 &ett_smb_transaction_data,
16635                 &ett_smb_stream_info,
16636                 &ett_smb_dfs_referrals,
16637                 &ett_smb_dfs_referral,
16638                 &ett_smb_dfs_referral_flags,
16639                 &ett_smb_get_dfs_flags,
16640                 &ett_smb_ff2_data,
16641                 &ett_smb_device_characteristics,
16642                 &ett_smb_fs_attributes,
16643                 &ett_smb_segments,
16644                 &ett_smb_sec_desc,
16645                 &ett_smb_sid,
16646                 &ett_smb_acl,
16647                 &ett_smb_ace,
16648                 &ett_smb_ace_flags,
16649                 &ett_smb_sec_desc_type,
16650                 &ett_smb_quotaflags,
16651         };
16652         module_t *smb_module;
16653
16654         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
16655             "SMB", "smb");
16656         proto_register_subtree_array(ett, array_length(ett));
16657         proto_register_field_array(proto_smb, hf, array_length(hf));
16658         register_init_routine(&smb_init_protocol);
16659         smb_module = prefs_register_protocol(proto_smb, NULL);
16660         prefs_register_bool_preference(smb_module, "trans_reassembly",
16661                 "Reassemble SMB Transaction payload",
16662                 "Whether the dissector should do reassembly the payload of SMB Transaction commands spanning multiple SMB PDUs",
16663                 &smb_trans_reassembly);
16664         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
16665                 "Reassemble DCERPC over SMB",
16666                 "Whether the dissector should do reassembly of DCERPC over SMB commands",
16667                 &smb_dcerpc_reassembly);
16668         register_init_routine(smb_trans_reassembly_init);
16669         register_init_routine(smb_dcerpc_reassembly_init);
16670 }
16671
16672 void
16673 proto_reg_handoff_smb(void)
16674 {
16675         heur_dissector_add("netbios", dissect_smb, proto_smb);
16676 }