Correctly dissect LSA security descriptors, at least as they appear
[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.244 2002/04/22 01:07:19 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
550 static gint ett_smb = -1;
551 static gint ett_smb_hdr = -1;
552 static gint ett_smb_command = -1;
553 static gint ett_smb_fileattributes = -1;
554 static gint ett_smb_capabilities = -1;
555 static gint ett_smb_aflags = -1;
556 static gint ett_smb_dialect = -1;
557 static gint ett_smb_dialects = -1;
558 static gint ett_smb_mode = -1;
559 static gint ett_smb_rawmode = -1;
560 static gint ett_smb_flags = -1;
561 static gint ett_smb_flags2 = -1;
562 static gint ett_smb_desiredaccess = -1;
563 static gint ett_smb_search = -1;
564 static gint ett_smb_file = -1;
565 static gint ett_smb_openfunction = -1;
566 static gint ett_smb_filetype = -1;
567 static gint ett_smb_openaction = -1;
568 static gint ett_smb_writemode = -1;
569 static gint ett_smb_lock_type = -1;
570 static gint ett_smb_ssetupandxaction = -1;
571 static gint ett_smb_optionsup = -1;
572 static gint ett_smb_time_date = -1;
573 static gint ett_smb_move_flags = -1;
574 static gint ett_smb_file_attributes = -1;
575 static gint ett_smb_search_resume_key = -1;
576 static gint ett_smb_search_dir_info = -1;
577 static gint ett_smb_unlocks = -1;
578 static gint ett_smb_unlock = -1;
579 static gint ett_smb_locks = -1;
580 static gint ett_smb_lock = -1;
581 static gint ett_smb_open_flags = -1;
582 static gint ett_smb_ipc_state = -1;
583 static gint ett_smb_open_action = -1;
584 static gint ett_smb_setup_action = -1;
585 static gint ett_smb_connect_flags = -1;
586 static gint ett_smb_connect_support_bits = -1;
587 static gint ett_smb_nt_access_mask = -1;
588 static gint ett_smb_nt_create_bits = -1;
589 static gint ett_smb_nt_create_options = -1;
590 static gint ett_smb_nt_share_access = -1;
591 static gint ett_smb_nt_security_flags = -1;
592 static gint ett_smb_nt_trans_setup = -1;
593 static gint ett_smb_nt_trans_data = -1;
594 static gint ett_smb_nt_trans_param = -1;
595 static gint ett_smb_nt_notify_completion_filter = -1;
596 static gint ett_smb_nt_ioctl_flags = -1;
597 static gint ett_smb_security_information_mask = -1;
598 static gint ett_smb_print_queue_entry = -1;
599 static gint ett_smb_transaction_flags = -1;
600 static gint ett_smb_transaction_params = -1;
601 static gint ett_smb_find_first2_flags = -1;
602 static gint ett_smb_transaction_data = -1;
603 static gint ett_smb_stream_info = -1;
604 static gint ett_smb_dfs_referrals = -1;
605 static gint ett_smb_dfs_referral = -1;
606 static gint ett_smb_dfs_referral_flags = -1;
607 static gint ett_smb_get_dfs_flags = -1;
608 static gint ett_smb_ff2_data = -1;
609 static gint ett_smb_device_characteristics = -1;
610 static gint ett_smb_fs_attributes = -1;
611 static gint ett_smb_segments = -1;
612 static gint ett_smb_sec_desc = -1;
613 static gint ett_smb_sid = -1;
614 static gint ett_smb_acl = -1;
615 static gint ett_smb_ace = -1;
616 static gint ett_smb_ace_flags = -1;
617 static gint ett_smb_sec_desc_type = -1;
618 static gint ett_smb_quotaflags = -1;
619
620 proto_tree *top_tree=NULL;     /* ugly */
621
622 static char *decode_smb_name(unsigned char);
623 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
624 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
625     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
626     gboolean exactlen, guint16 *bcp);
627
628 /*
629  * Macros for use in the main dissector routines for an SMB.
630  */
631
632 #define WORD_COUNT      \
633         /* Word Count */                                \
634         wc = tvb_get_guint8(tvb, offset);               \
635         proto_tree_add_uint(tree, hf_smb_word_count,    \
636                 tvb, offset, 1, wc);                    \
637         offset += 1;                                    \
638         if(wc==0) goto bytecount;
639
640 #define BYTE_COUNT      \
641         bytecount:                                      \
642         bc = tvb_get_letohs(tvb, offset);               \
643         proto_tree_add_uint(tree, hf_smb_byte_count,    \
644                         tvb, offset, 2, bc);            \
645         offset += 2;                                    \
646         if(bc==0) goto endofcommand;
647
648 #define CHECK_BYTE_COUNT(len)   \
649         if (bc < len) goto endofcommand;
650
651 #define COUNT_BYTES(len)   {\
652         int tmp;            \
653         tmp=len;            \
654         offset += tmp;      \
655         bc -= tmp;          \
656         }
657
658 #define END_OF_SMB      \
659         if (bc != 0) { \
660                 proto_tree_add_text(tree, tvb, offset, bc, \
661                     "Extra byte parameters");           \
662                 offset += bc;                           \
663         }                                               \
664         endofcommand:
665
666 /*
667  * Macros for use in routines called by them.
668  */
669 #define CHECK_BYTE_COUNT_SUBR(len)      \
670         if (*bcp < len) {               \
671                 *trunc = TRUE;          \
672                 return offset;          \
673         }
674
675 #define CHECK_STRING_SUBR(fn)   \
676         if (fn == NULL) {       \
677                 *trunc = TRUE;  \
678                 return offset;  \
679         }
680
681 #define COUNT_BYTES_SUBR(len)   \
682         offset += len;          \
683         *bcp -= len;
684
685 /*
686  * Macros for use when dissecting transaction parameters and data
687  */
688 #define CHECK_BYTE_COUNT_TRANS(len)     \
689         if (bc < len) return offset;
690
691 #define CHECK_STRING_TRANS(fn)  \
692         if (fn == NULL) return offset;
693
694 #define COUNT_BYTES_TRANS(len)  \
695         offset += len;          \
696         bc -= len;
697
698 /*
699  * Macros for use in subrroutines dissecting transaction parameters or data
700  */
701 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
702         if (*bcp < len) return offset;
703
704 #define CHECK_STRING_TRANS_SUBR(fn)     \
705         if (fn == NULL) return offset;
706
707 #define COUNT_BYTES_TRANS_SUBR(len)     \
708         offset += len;                  \
709         *bcp -= len;
710
711
712 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
713    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
714    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
715 static gboolean smb_trans_reassembly = FALSE;
716 gboolean smb_dcerpc_reassembly = FALSE;
717
718 static GHashTable *smb_trans_fragment_table = NULL;
719 GHashTable *dcerpc_fragment_table = NULL;
720
721 static void
722 smb_trans_reassembly_init(void)
723 {
724         fragment_table_init(&smb_trans_fragment_table);
725 }
726 static void
727 smb_dcerpc_reassembly_init(void)
728 {
729         fragment_table_init(&dcerpc_fragment_table);
730 }
731
732
733 static fragment_data *
734 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
735                      int offset, int count, int pos, int totlen)
736 {
737         fragment_data *fd_head=NULL;
738         smb_info_t *si;
739         int more_frags;
740
741         more_frags=totlen>(pos+count);
742
743         si = (smb_info_t *)pinfo->private_data;
744         if (si->sip == NULL) {
745                 /*
746                  * We don't have the frame number of the request.
747                  *
748                  * XXX - is there truly nothing we can do here?
749                  * Can we not separately keep track of the original
750                  * transaction and its continuations, as we did
751                  * at one time?
752                  *
753                  * It is probably not much point in even trying to do something here
754                  * if we have never seen the initial request. Without the initial 
755                  * request we probably miss all parameters and the begining of data
756                  * so we cant even call a subdissector since we can not determine
757                  * which type of transaction call this is.
758                  */
759                 return NULL;
760         }
761
762         if(!pinfo->fd->flags.visited){
763                 fd_head = fragment_add(tvb, offset, pinfo,
764                                        si->sip->frame_req, smb_trans_fragment_table,
765                                        pos, count, more_frags);
766         } else {
767                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
768         }
769
770         /* we only show the defragmented packet for the first fragment,
771            or else we might end up with dissecting one HUGE transaction PDU
772            a LOT of times. (first fragment is the only one containing the setup
773            bytes)
774            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
775            SMBs. Takes a LOT of time dissecting and is not fun.
776         */
777         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
778                 return fd_head;
779         } else {
780                 return NULL;
781         }
782 }
783                 
784
785
786
787
788 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
789    These variables and functions are used to match
790    responses with calls
791    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
792 /*
793  * The information we need to save about a request in order to show the
794  * frame number of the request in the dissection of the reply.
795  */
796 typedef struct  {
797         guint32 frame;
798         guint32 pid_mid;
799 } smb_saved_info_key_t;
800
801 static GMemChunk *smb_saved_info_key_chunk = NULL;
802 static GMemChunk *smb_saved_info_chunk = NULL;
803 static int smb_saved_info_init_count = 200;
804
805 /* unmatched smb_saved_info structures.
806    For unmatched smb_saved_info structures we store the smb_saved_info
807    structure using the MID and the PID as the key.
808
809    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
810    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
811    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
812 */
813 static gint
814 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
815 {
816         register guint32 key1 = (guint32)k1;
817         register guint32 key2 = (guint32)k2;
818         return key1==key2;
819 }
820 static guint
821 smb_saved_info_hash_unmatched(gconstpointer k)
822 {
823         register guint32 key = (guint32)k;
824         return key;
825 }
826
827 /* matched smb_saved_info structures.
828    For matched smb_saved_info structures we store the smb_saved_info
829    structure twice in the table using the frame number, and a combination
830    of the MID and the PID, as the key.
831    The frame number is guaranteed to be unique but if ever someone makes
832    some change that will renumber the frames in a capture we are in BIG trouble.
833    This is not likely though since that would break (among other things) all the
834    reassembly routines as well.
835
836    We also need the MID as there may be more than one SMB request or reply
837    in a single frame, and we also need the PID as there may be more than
838    one outstanding request with the same MID and different PIDs.
839 */
840 static gint
841 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
842 {
843         const smb_saved_info_key_t *key1 = k1;
844         const smb_saved_info_key_t *key2 = k2;
845         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
846 }
847 static guint
848 smb_saved_info_hash_matched(gconstpointer k)
849 {
850         const smb_saved_info_key_t *key = k;
851         return key->frame + key->pid_mid;
852 }
853
854 /*
855  * The information we need to save about an NT Transaction request in order
856  * to dissect the reply.
857  */
858 typedef struct {
859         int subcmd;
860 } smb_nt_transact_info_t;
861
862 static GMemChunk *smb_nt_transact_info_chunk = NULL;
863 static int smb_nt_transact_info_init_count = 200;
864
865 /*
866  * The information we need to save about a Transaction2 request in order
867  * to dissect the reply.
868  */
869 typedef struct {
870         int subcmd;
871         int info_level;
872 } smb_transact2_info_t;
873
874 static GMemChunk *smb_transact2_info_chunk = NULL;
875 static int smb_transact2_info_init_count = 200;
876
877 /*
878  * The information we need to save about a Transaction request in order
879  * to dissect the reply; this includes information for use by the
880  * Remote API dissector.
881  */
882 static GMemChunk *smb_transact_info_chunk = NULL;
883 static int smb_transact_info_init_count = 200;
884
885 static GMemChunk *conv_tables_chunk = NULL;
886 static GSList *conv_tables = NULL;
887 static int conv_tables_count = 10;
888
889
890 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
891    End of request/response matching functions
892    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
893
894 static const value_string buffer_format_vals[] = {
895         {1,     "Data Block"},
896         {2,     "Dialect"},
897         {3,     "Pathname"},
898         {4,     "ASCII"},
899         {5,     "Variable Block"},
900         {0,     NULL}
901 };
902
903 /*
904  * UTIME - this is *almost* like a UNIX time stamp, except that it's
905  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
906  * January 1, 1970, 00:00:00 GMT.
907  *
908  * This means we have to do some extra work to convert it.  This code is
909  * based on the Samba code:
910  *
911  *      Unix SMB/Netbios implementation.
912  *      Version 1.9.
913  *      time handling functions
914  *      Copyright (C) Andrew Tridgell 1992-1998
915  */
916
917 /*
918  * Yield the difference between *A and *B, in seconds, ignoring leap
919  * seconds.
920  */
921 #define TM_YEAR_BASE 1900
922
923 static int
924 tm_diff(struct tm *a, struct tm *b)
925 {
926         int ay = a->tm_year + (TM_YEAR_BASE - 1);
927         int by = b->tm_year + (TM_YEAR_BASE - 1);
928         int intervening_leap_days =
929             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
930         int years = ay - by;
931         int days =
932             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
933         int hours = 24*days + (a->tm_hour - b->tm_hour);
934         int minutes = 60*hours + (a->tm_min - b->tm_min);
935         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
936
937         return seconds;
938 }
939
940 /*
941  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
942  * determined.
943  */
944 static int
945 TimeZone(time_t t)
946 {
947         struct tm *tm = gmtime(&t);
948         struct tm tm_utc;
949
950         if (tm == NULL)
951                 return 0;
952         tm_utc = *tm;
953         tm = localtime(&t);
954         if (tm == NULL)
955                 return 0;
956         return tm_diff(&tm_utc,tm);
957 }
958
959 /*
960  * Return the same value as TimeZone, but it should be more efficient.
961  *
962  * We keep a table of DST offsets to prevent calling localtime() on each 
963  * call of this function. This saves a LOT of time on many unixes.
964  *
965  * Updated by Paul Eggert <eggert@twinsun.com>
966  */
967 #ifndef CHAR_BIT
968 #define CHAR_BIT 8
969 #endif
970
971 #ifndef TIME_T_MIN
972 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
973                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
974 #endif
975 #ifndef TIME_T_MAX
976 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
977 #endif
978
979 static int
980 TimeZoneFaster(time_t t)
981 {
982         static struct dst_table {time_t start,end; int zone;} *tdt;
983         static struct dst_table *dst_table = NULL;
984         static int table_size = 0;
985         int i;
986         int zone = 0;
987
988         if (t == 0)
989                 t = time(NULL);
990
991         /* Tunis has a 8 day DST region, we need to be careful ... */
992 #define MAX_DST_WIDTH (365*24*60*60)
993 #define MAX_DST_SKIP (7*24*60*60)
994
995         for (i = 0; i < table_size; i++) {
996                 if (t >= dst_table[i].start && t <= dst_table[i].end)
997                         break;
998         }
999
1000         if (i < table_size) {
1001                 zone = dst_table[i].zone;
1002         } else {
1003                 time_t low,high;
1004
1005                 zone = TimeZone(t);
1006                 if (dst_table == NULL)
1007                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1008                 else
1009                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1010                 if (tdt == NULL) {
1011                         if (dst_table)
1012                                 free(dst_table);
1013                         table_size = 0;
1014                 } else {
1015                         dst_table = tdt;
1016                         table_size++;
1017     
1018                         dst_table[i].zone = zone; 
1019                         dst_table[i].start = dst_table[i].end = t;
1020     
1021                         /* no entry will cover more than 6 months */
1022                         low = t - MAX_DST_WIDTH/2;
1023                         if (t < low)
1024                                 low = TIME_T_MIN;
1025       
1026                         high = t + MAX_DST_WIDTH/2;
1027                         if (high < t)
1028                                 high = TIME_T_MAX;
1029       
1030                         /*
1031                          * Widen the new entry using two bisection searches.
1032                          */
1033                         while (low+60*60 < dst_table[i].start) {
1034                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1035                                         t = dst_table[i].start - MAX_DST_SKIP;
1036                                 else
1037                                         t = low + (dst_table[i].start-low)/2;
1038                                 if (TimeZone(t) == zone)
1039                                         dst_table[i].start = t;
1040                                 else
1041                                         low = t;
1042                         }
1043
1044                         while (high-60*60 > dst_table[i].end) {
1045                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1046                                         t = dst_table[i].end + MAX_DST_SKIP;
1047                                 else
1048                                         t = high - (high-dst_table[i].end)/2;
1049                                 if (TimeZone(t) == zone)
1050                                         dst_table[i].end = t;
1051                                 else
1052                                         high = t;
1053                         }
1054                 }
1055         }
1056         return zone;
1057 }
1058
1059 /*
1060  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1061  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1062  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1063  * daylight savings transitions because some local times are ambiguous.
1064  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1065  */
1066 static int
1067 LocTimeDiff(time_t lt)
1068 {
1069         int d = TimeZoneFaster(lt);
1070         time_t t = lt + d;
1071
1072         /* if overflow occurred, ignore all the adjustments so far */
1073         if (((t < lt) ^ (d < 0)))
1074                 t = lt;
1075
1076         /*
1077          * Now t should be close enough to the true UTC to yield the
1078          * right answer.
1079          */
1080         return TimeZoneFaster(t);
1081 }
1082
1083 static int
1084 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1085 {
1086         guint32 timeval;
1087         nstime_t ts;
1088  
1089         timeval = tvb_get_letohl(tvb, offset);
1090         if (timeval == 0xffffffff) {
1091                 proto_tree_add_text(tree, tvb, offset, 4,
1092                     "%s: No time specified (0xffffffff)",
1093                     proto_registrar_get_name(hf_date));
1094                 offset += 4;
1095                 return offset;
1096         }
1097
1098         /*
1099          * We add the local time offset.
1100          */
1101         ts.secs = timeval + LocTimeDiff(timeval);
1102         ts.nsecs = 0;
1103
1104         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1105         offset += 4;
1106  
1107         return offset;
1108 }
1109
1110 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1111
1112 /*
1113  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1114  * to an "nstime_t".
1115  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1116  * midnight "UTC", in 100ns units.
1117  * Return TRUE if the conversion succeeds, FALSE otherwise.
1118  *
1119  * According to the Samba code, it appears to be kludge-GMT (at least for
1120  * file listings). This means it's the GMT you get by taking a local time
1121  * and adding the server time zone offset.  This is NOT the same as GMT in
1122  * some cases.   However, we don't know the server time zone, so we don't
1123  * do that adjustment.
1124  *
1125  * This code is based on the Samba code:
1126  *
1127  *      Unix SMB/Netbios implementation.
1128  *      Version 1.9.
1129  *      time handling functions
1130  *      Copyright (C) Andrew Tridgell 1992-1998
1131  */
1132 static gboolean
1133 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1134 {
1135         double d;
1136         /* The next two lines are a fix needed for the 
1137             broken SCO compiler. JRA. */
1138         time_t l_time_min = TIME_T_MIN;
1139         time_t l_time_max = TIME_T_MAX;
1140
1141         if (filetime_high == 0)
1142                 return FALSE;
1143
1144         /*
1145          * Get the time as a double, in seconds and fractional seconds.
1146          */
1147         d = ((double)filetime_high)*4.0*(double)(1<<30);
1148         d += filetime_low;
1149         d *= 1.0e-7;
1150  
1151         /* Now adjust by 369 years, to make the seconds since 1970. */
1152         d -= TIME_FIXUP_CONSTANT;
1153
1154         if (!(l_time_min <= d && d <= l_time_max))
1155                 return FALSE;
1156
1157         /*
1158          * Get the time as seconds and nanoseconds.
1159          */
1160         tv->secs = d;
1161         tv->nsecs = (d - tv->secs)*1000000000;
1162
1163         return TRUE;
1164 }
1165
1166 int
1167 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1168 {
1169         guint32 filetime_high, filetime_low;
1170         nstime_t ts;
1171
1172         /* XXX there seems also to be another special time value which is fairly common :
1173            0x40000000 00000000  
1174            the meaning of this one is yet unknown 
1175         */
1176         if (tree) {
1177                 filetime_low = tvb_get_letohl(tvb, offset);
1178                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1179                 if (filetime_low == 0 && filetime_high == 0) {
1180                         proto_tree_add_text(tree, tvb, offset, 8,
1181                             "%s: No time specified (0)",
1182                             proto_registrar_get_name(hf_date));
1183                 } else if(filetime_low==0 && filetime_high==0x80000000){
1184                         proto_tree_add_text(tree, tvb, offset, 8,
1185                             "%s: Infinity (relative time)",
1186                             proto_registrar_get_name(hf_date));
1187                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1188                         proto_tree_add_text(tree, tvb, offset, 8,
1189                             "%s: Infinity (absolute time)",
1190                             proto_registrar_get_name(hf_date));
1191                 } else {                        
1192                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1193                                 proto_tree_add_time(tree, hf_date, tvb,
1194                                     offset, 8, &ts);
1195                         } else {
1196                                 proto_tree_add_text(tree, tvb, offset, 8,
1197                                     "%s: Time can't be converted",
1198                                     proto_registrar_get_name(hf_date));
1199                         }
1200                 }
1201         }
1202
1203         offset += 8;
1204         return offset;
1205 }
1206
1207 static int
1208 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
1209     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
1210     int hf_dos_time, gboolean time_first)
1211 {
1212         guint16 dos_time, dos_date;
1213         proto_item *item = NULL;
1214         proto_tree *tree = NULL;
1215         struct tm tm;
1216         time_t t;
1217         static const int mday_noleap[12] = {
1218                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1219         };
1220         static const int mday_leap[12] = {
1221                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1222         };
1223 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1224         nstime_t tv;
1225
1226         if (time_first) {
1227                 dos_time = tvb_get_letohs(tvb, offset);
1228                 dos_date = tvb_get_letohs(tvb, offset+2);
1229         } else {
1230                 dos_date = tvb_get_letohs(tvb, offset);
1231                 dos_time = tvb_get_letohs(tvb, offset+2);
1232         }
1233
1234         if ((dos_time == 0xffff && dos_time == 0xffff) ||
1235             (dos_time == 0 && dos_time == 0)) {
1236                 /*
1237                  * No date/time specified.
1238                  */
1239                 if(parent_tree){
1240                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1241                             "%s: No time specified (0x%08x)",
1242                             proto_registrar_get_name(hf_date),
1243                             (dos_date << 16) | dos_time);
1244                 }
1245                 offset += 4;
1246                 return offset;
1247         }
1248
1249         tm.tm_sec = (dos_time&0x1f)*2;
1250         tm.tm_min = (dos_time>>5)&0x3f;
1251         tm.tm_hour = (dos_time>>11)&0x1f;
1252         tm.tm_mday = dos_date&0x1f;
1253         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1254         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1255         tm.tm_isdst = -1;
1256
1257         /*
1258          * Do some sanity checks before calling "mktime()";
1259          * "mktime()" doesn't do them, it "normalizes" out-of-range
1260          * values.
1261          */
1262         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1263            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1264            (ISLEAP(tm.tm_year + 1900) ?
1265              tm.tm_mday > mday_leap[tm.tm_mon] :
1266              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1267              (t = mktime(&tm)) == -1) {
1268                 /*
1269                  * Invalid date/time.
1270                  */
1271                 if (parent_tree) {
1272                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1273                             "%s: Invalid time",
1274                             proto_registrar_get_name(hf_date));
1275                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1276                         if (time_first) {
1277                                 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);
1278                                 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);
1279                         } else {
1280                                 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);
1281                                 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);
1282                         }
1283                 }
1284                 offset += 4;
1285                 return offset;
1286         }
1287
1288         tv.secs = t;
1289         tv.nsecs = 0;
1290
1291         if(parent_tree){
1292                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1293                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1294                 if (time_first) {
1295                         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);
1296                         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);
1297                 } else {
1298                         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);
1299                         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);
1300                 }
1301         }
1302
1303         offset += 4;
1304
1305         return offset;
1306 }
1307
1308
1309 static const value_string da_access_vals[] = {
1310         { 0,            "Open for reading"},
1311         { 1,            "Open for writing"},
1312         { 2,            "Open for reading and writing"},
1313         { 3,            "Open for execute"},
1314         {0, NULL}
1315 };
1316 static const value_string da_sharing_vals[] = {
1317         { 0,            "Compatibility mode"},
1318         { 1,            "Deny read/write/execute (exclusive)"},
1319         { 2,            "Deny write"},
1320         { 3,            "Deny read/execute"},
1321         { 4,            "Deny none"},
1322         {0, NULL}
1323 };
1324 static const value_string da_locality_vals[] = {
1325         { 0,            "Locality of reference unknown"},
1326         { 1,            "Mainly sequential access"},
1327         { 2,            "Mainly random access"},
1328         { 3,            "Random access with some locality"},
1329         {0, NULL}
1330 };
1331 static const true_false_string tfs_da_caching = {
1332         "Do not cache this file",
1333         "Caching permitted on this file"
1334 };
1335 static const true_false_string tfs_da_writetru = {
1336         "Write through enabled",
1337         "Write through disabled"
1338 };
1339 static int
1340 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1341 {
1342         guint16 mask;
1343         proto_item *item = NULL;
1344         proto_tree *tree = NULL;
1345
1346         mask = tvb_get_letohs(tvb, offset);
1347
1348         if(parent_tree){
1349                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1350                         "%s Access: 0x%04x", type, mask);
1351                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1352         }
1353
1354         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1355                 tvb, offset, 2, mask);
1356         proto_tree_add_boolean(tree, hf_smb_access_caching,
1357                 tvb, offset, 2, mask);
1358         proto_tree_add_uint(tree, hf_smb_access_locality,
1359                 tvb, offset, 2, mask);
1360         proto_tree_add_uint(tree, hf_smb_access_sharing,
1361                 tvb, offset, 2, mask);
1362         proto_tree_add_uint(tree, hf_smb_access_mode,
1363                 tvb, offset, 2, mask);
1364
1365         offset += 2;
1366
1367         return offset;
1368 }
1369
1370 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1371 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1372 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1373 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1374 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1375 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1376 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1377 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1378 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1379 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1380 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1381 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1382 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1383 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1384 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1385
1386 /*
1387  * These are flags to be used in NT Create operations.
1388  */
1389 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1390 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1391 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1392 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1393 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1394 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1395 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1396
1397 static const true_false_string tfs_file_attribute_write_through = {
1398         "This object requires WRITE THROUGH",
1399         "This object does NOT require write through",
1400 };
1401 static const true_false_string tfs_file_attribute_no_buffering = {
1402         "This object requires NO BUFFERING",
1403         "This object can be buffered",
1404 };
1405 static const true_false_string tfs_file_attribute_random_access = {
1406         "This object will be RANDOM ACCESSed",
1407         "Random access is NOT requested",
1408 };
1409 static const true_false_string tfs_file_attribute_sequential_scan = {
1410         "This object is optimized for SEQUENTIAL SCAN",
1411         "This object is NOT optimized for sequential scan",
1412 };
1413 static const true_false_string tfs_file_attribute_delete_on_close = {
1414         "This object will be DELETED ON CLOSE",
1415         "This object will not be deleted on close",
1416 };
1417 static const true_false_string tfs_file_attribute_backup_semantics = {
1418         "This object supports BACKUP SEMANTICS",
1419         "This object does NOT support backup semantics",
1420 };
1421 static const true_false_string tfs_file_attribute_posix_semantics = {
1422         "This object supports POSIX SEMANTICS",
1423         "This object does NOT support POSIX semantics",
1424 };
1425 static const true_false_string tfs_file_attribute_read_only = {
1426         "This file is READ ONLY",
1427         "This file is NOT read only",
1428 };
1429 static const true_false_string tfs_file_attribute_hidden = {
1430         "This is a HIDDEN file",
1431         "This is NOT a hidden file"
1432 };
1433 static const true_false_string tfs_file_attribute_system = {
1434         "This is a SYSTEM file",
1435         "This is NOT a system file"
1436 };
1437 static const true_false_string tfs_file_attribute_volume = {
1438         "This is a VOLUME ID",
1439         "This is NOT a volume ID"
1440 };
1441 static const true_false_string tfs_file_attribute_directory = {
1442         "This is a DIRECTORY",
1443         "This is NOT a directory"
1444 };
1445 static const true_false_string tfs_file_attribute_archive = {
1446         "This is an ARCHIVE file",
1447         "This is NOT an archive file"
1448 };
1449 static const true_false_string tfs_file_attribute_device = {
1450         "This is a DEVICE",
1451         "This is NOT a device"
1452 };
1453 static const true_false_string tfs_file_attribute_normal = {
1454         "This file is an ordinary file",
1455         "This file has some attribute set"
1456 };
1457 static const true_false_string tfs_file_attribute_temporary = {
1458         "This is a TEMPORARY file",
1459         "This is NOT a temporary file"
1460 };
1461 static const true_false_string tfs_file_attribute_sparse = {
1462         "This is a SPARSE file",
1463         "This is NOT a sparse file"
1464 };
1465 static const true_false_string tfs_file_attribute_reparse = {
1466         "This file has an associated REPARSE POINT",
1467         "This file does NOT have an associated reparse point"
1468 };
1469 static const true_false_string tfs_file_attribute_compressed = {
1470         "This is a COMPRESSED file",
1471         "This is NOT a compressed file"
1472 };
1473 static const true_false_string tfs_file_attribute_offline = {
1474         "This file is OFFLINE",
1475         "This file is NOT offline"
1476 };
1477 static const true_false_string tfs_file_attribute_not_content_indexed = {
1478         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1479         "This file MAY be indexed by the content indexing service"
1480 };
1481 static const true_false_string tfs_file_attribute_encrypted = {
1482         "This is an ENCRYPTED file",
1483         "This is NOT an encrypted file"
1484 };
1485
1486 static int
1487 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1488 {
1489         guint16 mask;
1490         proto_item *item = NULL;
1491         proto_tree *tree = NULL;
1492
1493         mask = tvb_get_letohs(tvb, offset);
1494
1495         if(parent_tree){
1496                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1497                         "File Attributes: 0x%04x", mask);
1498                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1499         }
1500         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1501                 tvb, offset, 2, mask);
1502         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1503                 tvb, offset, 2, mask);
1504         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1505                 tvb, offset, 2, mask);
1506         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1507                 tvb, offset, 2, mask);
1508         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1509                 tvb, offset, 2, mask);
1510         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1511                 tvb, offset, 2, mask);
1512
1513         offset += 2;
1514
1515         return offset;
1516 }
1517
1518 /* 3.11 */
1519 static int
1520 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1521 {
1522         guint32 mask;
1523         proto_item *item = NULL;
1524         proto_tree *tree = NULL;
1525
1526         mask = tvb_get_letohl(tvb, offset);
1527
1528         if(parent_tree){
1529                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1530                         "File Attributes: 0x%08x", mask);
1531                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1532         }
1533
1534         /*
1535          * XXX - Network Monitor disagrees on some of the
1536          * bits, e.g. the bits above temporary are "atomic write"
1537          * and "transaction write", and it says nothing about the
1538          * bits above that.
1539          *
1540          * Does the Win32 API documentation, or the NT Native API book,
1541          * suggest anything?
1542          */
1543         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1544                 tvb, offset, 4, mask);
1545         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1546                 tvb, offset, 4, mask);
1547         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1548                 tvb, offset, 4, mask);
1549         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1550                 tvb, offset, 4, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1552                 tvb, offset, 4, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1554                 tvb, offset, 4, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1556                 tvb, offset, 4, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1558                 tvb, offset, 4, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1560                 tvb, offset, 4, mask);
1561         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1562                 tvb, offset, 4, mask);
1563         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1564                 tvb, offset, 4, mask);
1565         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1566                 tvb, offset, 4, mask);
1567         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1568                 tvb, offset, 4, mask);
1569         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1570                 tvb, offset, 4, mask);
1571         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1572                 tvb, offset, 4, mask);
1573         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1574                 tvb, offset, 4, mask);
1575         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1576                 tvb, offset, 4, mask);
1577         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1578                 tvb, offset, 4, mask);
1579         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1580                 tvb, offset, 4, mask);
1581         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1582                 tvb, offset, 4, mask);
1583         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1584                 tvb, offset, 4, mask);
1585         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1586                 tvb, offset, 4, mask);
1587
1588         offset += 4;
1589
1590         return offset;
1591 }
1592
1593 static int
1594 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1595 {
1596         guint8 mask;
1597         proto_item *item = NULL;
1598         proto_tree *tree = NULL;
1599
1600         mask = tvb_get_guint8(tvb, offset);
1601
1602         if(parent_tree){
1603                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1604                         "File Attributes: 0x%02x", mask);
1605                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1606         }
1607         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1608                 tvb, offset, 1, mask);
1609         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1610                 tvb, offset, 1, mask);
1611         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1612                 tvb, offset, 1, mask);
1613         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1614                 tvb, offset, 1, mask);
1615         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1616                 tvb, offset, 1, mask);
1617         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1618                 tvb, offset, 1, mask);
1619
1620         offset += 1;
1621
1622         return offset;
1623 }
1624
1625 static const true_false_string tfs_search_attribute_read_only = {
1626         "Include READ ONLY files in search results",
1627         "Do NOT include read only files in search results",
1628 };
1629 static const true_false_string tfs_search_attribute_hidden = {
1630         "Include HIDDEN files in search results",
1631         "Do NOT include hidden files in search results"
1632 };
1633 static const true_false_string tfs_search_attribute_system = {
1634         "Include SYSTEM files in search results",
1635         "Do NOT include system files in search results"
1636 };
1637 static const true_false_string tfs_search_attribute_volume = {
1638         "Include VOLUME IDs in search results",
1639         "Do NOT include volume IDs in search results"
1640 };
1641 static const true_false_string tfs_search_attribute_directory = {
1642         "Include DIRECTORIES in search results",
1643         "Do NOT include directories in search results"
1644 };
1645 static const true_false_string tfs_search_attribute_archive = {
1646         "Include ARCHIVE files in search results",
1647         "Do NOT include archive files in search results"
1648 };
1649
1650 static int
1651 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1652 {
1653         guint16 mask;
1654         proto_item *item = NULL;
1655         proto_tree *tree = NULL;
1656
1657         mask = tvb_get_letohs(tvb, offset);
1658
1659         if(parent_tree){
1660                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1661                         "Search Attributes: 0x%04x", mask);
1662                 tree = proto_item_add_subtree(item, ett_smb_search);
1663         }
1664
1665         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1666                 tvb, offset, 2, mask);
1667         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1668                 tvb, offset, 2, mask);
1669         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1670                 tvb, offset, 2, mask);  
1671         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1672                 tvb, offset, 2, mask);
1673         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1674                 tvb, offset, 2, mask);
1675         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1676                 tvb, offset, 2, mask);
1677
1678         offset += 2;
1679         return offset;
1680 }
1681
1682 #if 0
1683 /*
1684  * XXX - this isn't used.
1685  * Is this used for anything?  NT Create AndX doesn't use it.
1686  * Is there some 16-bit attribute field with more bits than Read Only,
1687  * Hidden, System, Volume ID, Directory, and Archive?
1688  */
1689 static int
1690 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1691 {
1692         guint32 mask;
1693         proto_item *item = NULL;
1694         proto_tree *tree = NULL;
1695
1696         mask = tvb_get_letohl(tvb, offset);
1697
1698         if(parent_tree){
1699                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1700                         "File Attributes: 0x%08x", mask);
1701                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1702         }
1703         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1704                 tvb, offset, 2, mask);
1705         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1706                 tvb, offset, 2, mask);
1707         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1708                 tvb, offset, 2, mask);
1709         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1710                 tvb, offset, 2, mask);
1711         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1712                 tvb, offset, 2, mask);
1713         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1714                 tvb, offset, 2, mask);
1715         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1716                 tvb, offset, 2, mask);
1717         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1718                 tvb, offset, 2, mask);
1719         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1720                 tvb, offset, 2, mask);
1721         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1722                 tvb, offset, 2, mask);
1723         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1724                 tvb, offset, 2, mask);
1725         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1726                 tvb, offset, 2, mask);
1727         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1728                 tvb, offset, 2, mask);
1729         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1730                 tvb, offset, 2, mask);
1731         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1732                 tvb, offset, 2, mask);
1733
1734         offset += 2;
1735
1736         return offset;
1737 }
1738 #endif
1739
1740
1741 #define SERVER_CAP_RAW_MODE            0x00000001
1742 #define SERVER_CAP_MPX_MODE            0x00000002
1743 #define SERVER_CAP_UNICODE             0x00000004
1744 #define SERVER_CAP_LARGE_FILES         0x00000008
1745 #define SERVER_CAP_NT_SMBS             0x00000010
1746 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1747 #define SERVER_CAP_STATUS32            0x00000040
1748 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1749 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1750 #define SERVER_CAP_NT_FIND             0x00000200
1751 #define SERVER_CAP_DFS                 0x00001000
1752 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1753 #define SERVER_CAP_LARGE_READX         0x00004000
1754 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1755 #define SERVER_CAP_UNIX                0x00800000
1756 #define SERVER_CAP_RESERVED            0x02000000
1757 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1758 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1759 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1760 static const true_false_string tfs_server_cap_raw_mode = {
1761         "Read Raw and Write Raw are supported",
1762         "Read Raw and Write Raw are not supported"
1763 };
1764 static const true_false_string tfs_server_cap_mpx_mode = {
1765         "Read Mpx and Write Mpx are supported",
1766         "Read Mpx and Write Mpx are not supported"
1767 };
1768 static const true_false_string tfs_server_cap_unicode = {
1769         "Unicode strings are supported",
1770         "Unicode strings are not supported"
1771 };
1772 static const true_false_string tfs_server_cap_large_files = {
1773         "Large files are supported",
1774         "Large files are not supported",
1775 };
1776 static const true_false_string tfs_server_cap_nt_smbs = {
1777         "NT SMBs are supported",
1778         "NT SMBs are not supported"
1779 };
1780 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1781         "RPC remote APIs are supported",
1782         "RPC remote APIs are not supported"
1783 };
1784 static const true_false_string tfs_server_cap_nt_status = {
1785         "NT status codes are supported",
1786         "NT status codes are not supported"
1787 };
1788 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1789         "Level 2 oplocks are supported",
1790         "Level 2 oplocks are not supported"
1791 };
1792 static const true_false_string tfs_server_cap_lock_and_read = {
1793         "Lock and Read is supported",
1794         "Lock and Read is not supported"
1795 };
1796 static const true_false_string tfs_server_cap_nt_find = {
1797         "NT Find is supported",
1798         "NT Find is not supported"
1799 };
1800 static const true_false_string tfs_server_cap_dfs = {
1801         "Dfs is supported",
1802         "Dfs is not supported"
1803 };
1804 static const true_false_string tfs_server_cap_infolevel_passthru = {
1805         "NT information level request passthrough is supported",
1806         "NT information level request passthrough is not supported"
1807 };
1808 static const true_false_string tfs_server_cap_large_readx = {
1809         "Large Read andX is supported",
1810         "Large Read andX is not supported"
1811 };
1812 static const true_false_string tfs_server_cap_large_writex = {
1813         "Large Write andX is supported",
1814         "Large Write andX is not supported"
1815 };
1816 static const true_false_string tfs_server_cap_unix = {
1817         "UNIX extensions are supported",
1818         "UNIX extensions are not supported"
1819 };
1820 static const true_false_string tfs_server_cap_reserved = {
1821         "Reserved",
1822         "Reserved"
1823 };
1824 static const true_false_string tfs_server_cap_bulk_transfer = {
1825         "Bulk Read and Bulk Write are supported",
1826         "Bulk Read and Bulk Write are not supported"
1827 };
1828 static const true_false_string tfs_server_cap_compressed_data = {
1829         "Compressed data transfer is supported",
1830         "Compressed data transfer is not supported"
1831 };
1832 static const true_false_string tfs_server_cap_extended_security = {
1833         "Extended security exchanges are supported",
1834         "Extended security exchanges are not supported"
1835 };
1836 static int
1837 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1838 {
1839         guint32 mask;
1840         proto_item *item = NULL;
1841         proto_tree *tree = NULL;
1842
1843         mask = tvb_get_letohl(tvb, offset);
1844
1845         if(parent_tree){
1846                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1847                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1848         }
1849
1850         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1851                 tvb, offset, 4, mask);
1852         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1853                 tvb, offset, 4, mask);
1854         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1855                 tvb, offset, 4, mask);
1856         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1857                 tvb, offset, 4, mask);
1858         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1859                 tvb, offset, 4, mask);
1860         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1861                 tvb, offset, 4, mask);
1862         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1863                 tvb, offset, 4, mask);
1864         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1865                 tvb, offset, 4, mask);
1866         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1867                 tvb, offset, 4, mask);
1868         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1869                 tvb, offset, 4, mask);
1870         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1871                 tvb, offset, 4, mask);
1872         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1873                 tvb, offset, 4, mask);
1874         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1875                 tvb, offset, 4, mask);
1876         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1877                 tvb, offset, 4, mask);
1878         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1879                 tvb, offset, 4, mask);
1880         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1881                 tvb, offset, 4, mask);
1882         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1883                 tvb, offset, 4, mask);
1884         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1885                 tvb, offset, 4, mask);
1886         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1887                 tvb, offset, 4, mask);
1888
1889         return mask;
1890 }
1891
1892 #define RAWMODE_READ   0x01
1893 #define RAWMODE_WRITE  0x02
1894 static const true_false_string tfs_rm_read = {
1895         "Read Raw is supported",
1896         "Read Raw is not supported"
1897 };
1898 static const true_false_string tfs_rm_write = {
1899         "Write Raw is supported",
1900         "Write Raw is not supported"
1901 };
1902
1903 static int
1904 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1905 {
1906         guint16 mask;
1907         proto_item *item = NULL;
1908         proto_tree *tree = NULL;
1909
1910         mask = tvb_get_letohs(tvb, offset);
1911
1912         if(parent_tree){
1913                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1914                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1915         }
1916
1917         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1918         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1919
1920         offset += 2;
1921
1922         return offset;
1923 }
1924
1925 #define SECURITY_MODE_MODE             0x01
1926 #define SECURITY_MODE_PASSWORD         0x02
1927 #define SECURITY_MODE_SIGNATURES       0x04
1928 #define SECURITY_MODE_SIG_REQUIRED     0x08
1929 static const true_false_string tfs_sm_mode = {
1930         "USER security mode",
1931         "SHARE security mode"
1932 };
1933 static const true_false_string tfs_sm_password = {
1934         "ENCRYPTED password. Use challenge/response",
1935         "PLAINTEXT password"
1936 };
1937 static const true_false_string tfs_sm_signatures = {
1938         "Security signatures ENABLED",
1939         "Security signatures NOT enabled"
1940 };
1941 static const true_false_string tfs_sm_sig_required = {
1942         "Security signatures REQUIRED",
1943         "Security signatures NOT required"
1944 };
1945
1946 static int
1947 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1948 {
1949         guint16 mask = 0;
1950         proto_item *item = NULL;
1951         proto_tree *tree = NULL;
1952
1953         switch(wc){
1954         case 13:
1955                 mask = tvb_get_letohs(tvb, offset);
1956                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1957                                 "Security Mode: 0x%04x", mask);
1958                 tree = proto_item_add_subtree(item, ett_smb_mode);
1959                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1960                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1961                 offset += 2;
1962                 break;
1963
1964         case 17:
1965                 mask = tvb_get_guint8(tvb, offset);
1966                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1967                                 "Security Mode: 0x%02x", mask);
1968                 tree = proto_item_add_subtree(item, ett_smb_mode);
1969                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1970                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1971                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1972                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1973                 offset += 1;
1974                 break;
1975         }
1976
1977         return offset;
1978 }
1979
1980 static int
1981 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1982 {
1983         proto_item *it = NULL;
1984         proto_tree *tr = NULL;
1985         guint16 bc;
1986         guint8 wc;
1987
1988         WORD_COUNT;
1989
1990         BYTE_COUNT;
1991
1992         if(tree){
1993                 it = proto_tree_add_text(tree, tvb, offset, bc,
1994                                 "Requested Dialects");
1995                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1996         }
1997
1998         while(bc){
1999                 int len;
2000                 const guint8 *str;
2001                 proto_item *dit = NULL;
2002                 proto_tree *dtr = NULL;
2003
2004                 /* XXX - what if this runs past bc? */
2005                 len = tvb_strsize(tvb, offset+1);
2006                 str = tvb_get_ptr(tvb, offset+1, len);
2007
2008                 if(tr){
2009                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2010                                         "Dialect: %s", str);
2011                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2012                 }
2013
2014                 /* Buffer Format */
2015                 CHECK_BYTE_COUNT(1);
2016                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2017                         TRUE);
2018                 COUNT_BYTES(1);
2019
2020                 /*Dialect Name */
2021                 CHECK_BYTE_COUNT(len);
2022                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2023                         len, str);
2024                 COUNT_BYTES(len);
2025         }
2026
2027         END_OF_SMB
2028
2029         return offset;
2030 }
2031
2032 static int
2033 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2034 {
2035         guint8 wc;
2036         guint16 dialect;
2037         const char *dn;
2038         int dn_len;
2039         guint16 bc;
2040         guint16 ekl=0;
2041         guint32 caps=0;
2042         gint16 tz;
2043
2044         WORD_COUNT;
2045
2046         /* Dialect Index */
2047         dialect = tvb_get_letohs(tvb, offset);
2048         switch(wc){
2049         case 1:
2050                 if(dialect==0xffff){
2051                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2052                                 tvb, offset, 2, dialect,
2053                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2054                 } else {
2055                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2056                                 tvb, offset, 2, dialect);
2057                 }
2058                 break;
2059         case 13:
2060                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2061                         tvb, offset, 2, dialect,
2062                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2063                 break;
2064         case 17:
2065                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2066                         tvb, offset, 2, dialect,
2067                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2068                 break;
2069         default:
2070                 proto_tree_add_text(tree, tvb, offset, wc*2,
2071                         "Words for unknown response format");
2072                 offset += wc*2;
2073                 goto bytecount;
2074         }
2075         offset += 2;
2076
2077         switch(wc){
2078         case 13:
2079                 /* Security Mode */
2080                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
2081                                 wc);
2082
2083                 /* Maximum Transmit Buffer Size */
2084                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2085                         tvb, offset, 2, TRUE);
2086                 offset += 2;
2087
2088                 /* Maximum Multiplex Count */
2089                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2090                         tvb, offset, 2, TRUE);
2091                 offset += 2;
2092
2093                 /* Maximum Vcs Number */
2094                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2095                         tvb, offset, 2, TRUE);
2096                 offset += 2;
2097
2098                 /* raw mode */
2099                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
2100
2101                 /* session key */
2102                 proto_tree_add_item(tree, hf_smb_session_key,
2103                         tvb, offset, 4, TRUE);
2104                 offset += 4;
2105
2106                 /* current time and date at server */
2107                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2108                     TRUE);
2109
2110                 /* time zone */
2111                 tz = tvb_get_letohs(tvb, offset);
2112                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2113                 offset += 2;
2114
2115                 /* encryption key length */
2116                 ekl = tvb_get_letohs(tvb, offset);
2117                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2118                 offset += 2;
2119
2120                 /* 2 reserved bytes */
2121                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2122                 offset += 2;
2123
2124                 break;
2125
2126         case 17:
2127                 /* Security Mode */
2128                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
2129
2130                 /* Maximum Multiplex Count */
2131                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2132                         tvb, offset, 2, TRUE);
2133                 offset += 2;
2134
2135                 /* Maximum Vcs Number */
2136                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2137                         tvb, offset, 2, TRUE);
2138                 offset += 2;
2139
2140                 /* Maximum Transmit Buffer Size */
2141                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2142                         tvb, offset, 4, TRUE);
2143                 offset += 4;
2144
2145                 /* maximum raw buffer size */
2146                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2147                         tvb, offset, 4, TRUE);
2148                 offset += 4;
2149
2150                 /* session key */
2151                 proto_tree_add_item(tree, hf_smb_session_key,
2152                         tvb, offset, 4, TRUE);
2153                 offset += 4;
2154
2155                 /* server capabilities */
2156                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
2157                 offset += 4;
2158
2159                 /* system time */
2160                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
2161                                 hf_smb_system_time);
2162
2163                 /* time zone */
2164                 tz = tvb_get_letohs(tvb, offset);
2165                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2166                         tvb, offset, 2, tz,
2167                         "Server Time Zone: %d min from UTC", tz);
2168                 offset += 2;
2169
2170                 /* encryption key length */
2171                 ekl = tvb_get_guint8(tvb, offset);
2172                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2173                         tvb, offset, 1, ekl);
2174                 offset += 1;
2175
2176                 break;
2177         }
2178
2179         BYTE_COUNT;
2180
2181         switch(wc){
2182         case 13:
2183                 /* challenge/response encryption key */
2184                 if(ekl){
2185                         CHECK_BYTE_COUNT(ekl);
2186                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2187                         COUNT_BYTES(ekl);
2188                 }
2189
2190                 /* domain */
2191                 dn = get_unicode_or_ascii_string(tvb, &offset,
2192                         pinfo, &dn_len, FALSE, FALSE, &bc);
2193                 if (dn == NULL)
2194                         goto endofcommand;
2195                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2196                         offset, dn_len,dn);
2197                 COUNT_BYTES(dn_len);
2198                 break;
2199
2200         case 17:
2201                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2202                         smb_info_t *si;
2203
2204                         /* challenge/response encryption key */
2205                         /* XXX - is this aligned on an even boundary? */
2206                         if(ekl){
2207                                 CHECK_BYTE_COUNT(ekl);
2208                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2209                                         tvb, offset, ekl, TRUE);
2210                                 COUNT_BYTES(ekl);
2211                         }
2212
2213                         /* domain */
2214                         /* this string is special, unicode is flagged in caps */
2215                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2216                         si = pinfo->private_data;
2217                         si->unicode = (caps&SERVER_CAP_UNICODE);
2218                         dn = get_unicode_or_ascii_string(tvb,
2219                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2220                                 &bc);
2221                         if (dn == NULL)
2222                                 goto endofcommand;
2223                         proto_tree_add_string(tree, hf_smb_primary_domain,
2224                                 tvb, offset, dn_len, dn);
2225                         COUNT_BYTES(dn_len);
2226                 } else {
2227                         /* guid */
2228                         /* XXX - show it in the standard Microsoft format
2229                            for GUIDs? */
2230                         CHECK_BYTE_COUNT(16);
2231                         proto_tree_add_item(tree, hf_smb_server_guid,
2232                                 tvb, offset, 16, TRUE);
2233                         COUNT_BYTES(16);
2234
2235                         /* security blob */
2236                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2237                            data structure, at least in NT 5.0-and-later
2238                            server replies? */
2239                         if(bc){
2240                                 proto_tree_add_item(tree, hf_smb_security_blob,
2241                                         tvb, offset, bc, TRUE);
2242                                 COUNT_BYTES(bc);
2243                         }
2244                 }
2245                 break;
2246         }
2247
2248         END_OF_SMB
2249
2250         return offset;
2251 }
2252
2253
2254 static int
2255 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2256 {
2257         int dn_len;
2258         const char *dn;
2259         guint8 wc;
2260         guint16 bc;
2261
2262         WORD_COUNT;
2263  
2264         BYTE_COUNT;
2265
2266         /* buffer format */
2267         CHECK_BYTE_COUNT(1);
2268         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2269         COUNT_BYTES(1);
2270
2271         /* dir name */
2272         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2273                 FALSE, FALSE, &bc);
2274         if (dn == NULL)
2275                 goto endofcommand;
2276         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2277                 dn);
2278         COUNT_BYTES(dn_len);
2279
2280         if (check_col(pinfo->cinfo, COL_INFO)) {
2281                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2282         }
2283
2284         END_OF_SMB
2285
2286         return offset;
2287 }
2288
2289 static int
2290 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2291 {
2292         guint8 wc;
2293         guint16 bc;
2294  
2295         WORD_COUNT;
2296  
2297         BYTE_COUNT;
2298
2299         END_OF_SMB
2300
2301         return offset;
2302 }
2303
2304 static int
2305 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2306 {
2307         guint16 ec, bc;
2308         guint8 wc;
2309
2310         WORD_COUNT;
2311
2312         /* echo count */
2313         ec = tvb_get_letohs(tvb, offset);
2314         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2315         offset += 2;
2316
2317         BYTE_COUNT;
2318
2319         if (bc != 0) {
2320                 /* echo data */
2321                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2322                 COUNT_BYTES(bc);
2323         }
2324
2325         END_OF_SMB
2326
2327         return offset;
2328 }
2329
2330 static int
2331 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2332 {
2333         guint16 bc;
2334         guint8 wc;
2335
2336         WORD_COUNT;
2337
2338         /* echo sequence number */
2339         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2340         offset += 2;
2341
2342         BYTE_COUNT;
2343
2344         if (bc != 0) {
2345                 /* echo data */
2346                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2347                 COUNT_BYTES(bc);
2348         }
2349
2350         END_OF_SMB
2351
2352         return offset;
2353 }
2354
2355 static int
2356 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2357 {
2358         int an_len, pwlen;
2359         const char *an;
2360         guint8 wc;
2361         guint16 bc;
2362
2363         WORD_COUNT;
2364  
2365         BYTE_COUNT;
2366
2367         /* buffer format */
2368         CHECK_BYTE_COUNT(1);
2369         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2370         COUNT_BYTES(1);
2371
2372         /* Path */
2373         an = get_unicode_or_ascii_string(tvb, &offset,
2374                 pinfo, &an_len, FALSE, FALSE, &bc);
2375         if (an == NULL)
2376                 goto endofcommand;
2377         proto_tree_add_string(tree, hf_smb_path, tvb,
2378                 offset, an_len, an);
2379         COUNT_BYTES(an_len);
2380
2381         if (check_col(pinfo->cinfo, COL_INFO)) {
2382                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2383         }
2384
2385         /* buffer format */
2386         CHECK_BYTE_COUNT(1);
2387         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2388         COUNT_BYTES(1);
2389
2390         /* password, ANSI */
2391         /* XXX - what if this runs past bc? */
2392         pwlen = tvb_strsize(tvb, offset);
2393         CHECK_BYTE_COUNT(pwlen);
2394         proto_tree_add_item(tree, hf_smb_password,
2395                 tvb, offset, pwlen, TRUE);
2396         COUNT_BYTES(pwlen);
2397
2398         /* buffer format */
2399         CHECK_BYTE_COUNT(1);
2400         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2401         COUNT_BYTES(1);
2402
2403         /* Service */
2404         an = get_unicode_or_ascii_string(tvb, &offset,
2405                 pinfo, &an_len, FALSE, FALSE, &bc);
2406         if (an == NULL)
2407                 goto endofcommand;
2408         proto_tree_add_string(tree, hf_smb_service, tvb,
2409                 offset, an_len, an);
2410         COUNT_BYTES(an_len);
2411
2412         END_OF_SMB
2413
2414         return offset;
2415 }
2416
2417 static int
2418 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2419 {
2420         guint8 wc;
2421         guint16 bc;
2422
2423         WORD_COUNT;
2424  
2425         /* Maximum Buffer Size */
2426         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2427         offset += 2;
2428
2429         /* tid */
2430         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2431         offset += 2;
2432
2433         BYTE_COUNT;
2434
2435         END_OF_SMB
2436
2437         return offset;
2438 }
2439  
2440
2441 static const true_false_string tfs_of_create = {
2442         "Create file if it does not exist",
2443         "Fail if file does not exist"
2444 };
2445 static const value_string of_open[] = {
2446         { 0,            "Fail if file exists"},
2447         { 1,            "Open file if it exists"},
2448         { 2,            "Truncate file if it exists"},
2449         {0, NULL}
2450 };
2451 static int
2452 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2453 {
2454         guint16 mask;
2455         proto_item *item = NULL;
2456         proto_tree *tree = NULL;
2457
2458         mask = tvb_get_letohs(tvb, offset);
2459
2460         if(parent_tree){
2461                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2462                         "Open Function: 0x%04x", mask);
2463                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2464         }
2465
2466         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2467                 tvb, offset, 2, mask);
2468         proto_tree_add_uint(tree, hf_smb_open_function_open,
2469                 tvb, offset, 2, mask);
2470
2471         offset += 2;
2472
2473         return offset;
2474 }
2475
2476
2477 static const true_false_string tfs_mf_file = {
2478         "Target must be a file",
2479         "Target needn't be a file"
2480  };
2481 static const true_false_string tfs_mf_dir = {
2482         "Target must be a directory",
2483         "Target needn't be a directory"
2484 };
2485 static const true_false_string tfs_mf_verify = {
2486         "MUST verify all writes",
2487         "Don't have to verify writes"
2488 };
2489 static int
2490 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2491 {
2492         guint16 mask;
2493         proto_item *item = NULL;
2494         proto_tree *tree = NULL;
2495
2496         mask = tvb_get_letohs(tvb, offset);
2497
2498         if(parent_tree){
2499                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2500                         "Flags: 0x%04x", mask);
2501                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2502         }
2503  
2504         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2505                 tvb, offset, 2, mask);
2506         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2507                 tvb, offset, 2, mask);
2508         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2509                 tvb, offset, 2, mask);
2510
2511         offset += 2;
2512
2513         return offset;
2514 }
2515
2516 static int
2517 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2518 {
2519         int fn_len;
2520         guint16 tid;
2521         guint16 bc;
2522         guint8 wc;
2523         const char *fn;
2524
2525         WORD_COUNT;
2526
2527         /* tid */
2528         tid = tvb_get_letohs(tvb, offset);
2529         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2530                 "TID (target): 0x%04x", tid);
2531         offset += 2;
2532
2533         /* open function */
2534         offset = dissect_open_function(tvb, pinfo, tree, offset);
2535
2536         /* move flags */
2537         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2538
2539         BYTE_COUNT;
2540
2541         /* buffer format */
2542         CHECK_BYTE_COUNT(1);
2543         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2544         COUNT_BYTES(1);
2545
2546         /* file name */
2547         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2548                 FALSE, FALSE, &bc);
2549         if (fn == NULL)
2550                 goto endofcommand;
2551         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2552                 fn_len, fn, "Old File Name: %s", fn);
2553         COUNT_BYTES(fn_len);
2554
2555         if (check_col(pinfo->cinfo, COL_INFO)) {
2556                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2557         }
2558
2559         /* buffer format */
2560         CHECK_BYTE_COUNT(1);
2561         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2562         COUNT_BYTES(1);
2563
2564         /* file name */
2565         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2566                 FALSE, FALSE, &bc);
2567         if (fn == NULL)
2568                 goto endofcommand;
2569         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2570                 fn_len, fn, "New File Name: %s", fn);
2571         COUNT_BYTES(fn_len);
2572
2573         if (check_col(pinfo->cinfo, COL_INFO)) {
2574                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2575         }
2576
2577         END_OF_SMB
2578
2579         return offset;
2580 }
2581
2582 static int
2583 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2584 {
2585         int fn_len;
2586         const char *fn;
2587         guint8 wc;
2588         guint16 bc;
2589
2590         WORD_COUNT;
2591
2592         /* # of files moved */
2593         proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
2594         offset += 2;
2595
2596         BYTE_COUNT;
2597
2598         /* buffer format */
2599         CHECK_BYTE_COUNT(1);
2600         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2601         COUNT_BYTES(1);
2602
2603         /* file name */
2604         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2605                 FALSE, FALSE, &bc);
2606         if (fn == NULL)
2607                 goto endofcommand;
2608         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2609                 fn);
2610         COUNT_BYTES(fn_len);
2611
2612         END_OF_SMB
2613
2614         return offset;
2615 }
2616
2617 static int
2618 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2619 {
2620         int fn_len;
2621         const char *fn;
2622         guint8 wc;
2623         guint16 bc;
2624
2625         WORD_COUNT;
2626
2627         /* desired access */
2628         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2629
2630         /* Search Attributes */
2631         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2632
2633         BYTE_COUNT;
2634
2635         /* buffer format */
2636         CHECK_BYTE_COUNT(1);
2637         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2638         COUNT_BYTES(1);
2639
2640         /* file name */
2641         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2642                 FALSE, FALSE, &bc);
2643         if (fn == NULL)
2644                 goto endofcommand;
2645         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2646                 fn);
2647         COUNT_BYTES(fn_len);
2648
2649         if (check_col(pinfo->cinfo, COL_INFO)) {
2650                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2651         }
2652
2653         END_OF_SMB
2654
2655         return offset;
2656 }
2657
2658 void
2659 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2660     int len, guint16 fid)
2661 {
2662         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2663         if (check_col(pinfo->cinfo, COL_INFO))
2664                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2665 }
2666
2667 static int
2668 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2669 {
2670         guint8 wc;
2671         guint16 bc;
2672         guint16 fid;
2673
2674         WORD_COUNT;
2675
2676         /* fid */
2677         fid = tvb_get_letohs(tvb, offset);
2678         add_fid(tvb, pinfo, tree, offset, 2, fid);
2679         offset += 2;
2680
2681         /* File Attributes */
2682         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2683
2684         /* last write time */
2685         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2686         
2687         /* File Size */
2688         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2689         offset += 4;
2690
2691         /* granted access */
2692         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2693
2694         BYTE_COUNT;
2695
2696         END_OF_SMB
2697
2698         return offset;
2699 }
2700
2701 static int
2702 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2703 {
2704         guint8 wc;
2705         guint16 bc;
2706         guint16 fid;
2707
2708         WORD_COUNT;
2709
2710         /* fid */
2711         fid = tvb_get_letohs(tvb, offset);
2712         add_fid(tvb, pinfo, tree, offset, 2, fid);
2713         offset += 2;
2714
2715         BYTE_COUNT;
2716
2717         END_OF_SMB
2718
2719         return offset;
2720 }
2721
2722 static int
2723 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2724 {
2725         int fn_len;
2726         const char *fn;
2727         guint8 wc;
2728         guint16 bc;
2729
2730         WORD_COUNT;
2731
2732         /* file attributes */
2733         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2734
2735         /* creation time */
2736         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2737
2738         BYTE_COUNT;
2739
2740         /* buffer format */
2741         CHECK_BYTE_COUNT(1);
2742         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2743         COUNT_BYTES(1);
2744
2745         /* File Name */
2746         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2747                 FALSE, FALSE, &bc);
2748         if (fn == NULL)
2749                 goto endofcommand;
2750         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2751                 fn);
2752         COUNT_BYTES(fn_len);
2753
2754         if (check_col(pinfo->cinfo, COL_INFO)) {
2755                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2756         }
2757
2758         END_OF_SMB
2759
2760         return offset;
2761 }
2762
2763 static int
2764 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2765 {
2766         guint8 wc;
2767         guint16 bc, fid;
2768
2769         WORD_COUNT;
2770
2771         /* fid */
2772         fid = tvb_get_letohs(tvb, offset);
2773         add_fid(tvb, pinfo, tree, offset, 2, fid);
2774         offset += 2;
2775
2776         /* last write time */
2777         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2778
2779         BYTE_COUNT;
2780
2781         END_OF_SMB
2782
2783         return offset;
2784 }
2785
2786 static int
2787 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2788 {
2789         int fn_len;
2790         const char *fn;
2791         guint8 wc;
2792         guint16 bc;
2793
2794         WORD_COUNT;
2795
2796         /* search attributes */
2797         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2798
2799         BYTE_COUNT;
2800
2801         /* buffer format */
2802         CHECK_BYTE_COUNT(1);
2803         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2804         COUNT_BYTES(1);
2805
2806         /* file name */
2807         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2808                 FALSE, FALSE, &bc);
2809         if (fn == NULL)
2810                 goto endofcommand;
2811         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2812                 fn);
2813         COUNT_BYTES(fn_len);
2814
2815         if (check_col(pinfo->cinfo, COL_INFO)) {
2816                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2817         }
2818
2819         END_OF_SMB
2820
2821         return offset;
2822 }
2823
2824 static int
2825 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2826 {
2827         int fn_len;
2828         const char *fn;
2829         guint8 wc;
2830         guint16 bc;
2831
2832         WORD_COUNT;
2833
2834         /* search attributes */
2835         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2836
2837         BYTE_COUNT;
2838
2839         /* buffer format */
2840         CHECK_BYTE_COUNT(1);
2841         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2842         COUNT_BYTES(1);
2843
2844         /* old file name */
2845         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2846                 FALSE, FALSE, &bc);
2847         if (fn == NULL)
2848                 goto endofcommand;
2849         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2850                 fn);
2851         COUNT_BYTES(fn_len);
2852
2853         if (check_col(pinfo->cinfo, COL_INFO)) {
2854                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2855         }
2856
2857         /* buffer format */
2858         CHECK_BYTE_COUNT(1);
2859         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2860         COUNT_BYTES(1);
2861
2862         /* file name */
2863         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2864                 FALSE, FALSE, &bc);
2865         if (fn == NULL)
2866                 goto endofcommand;
2867         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2868                 fn);
2869         COUNT_BYTES(fn_len);
2870
2871         if (check_col(pinfo->cinfo, COL_INFO)) {
2872                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2873         }
2874
2875         END_OF_SMB
2876
2877         return offset;
2878 }
2879
2880 static int
2881 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2882 {
2883         guint16 bc;
2884         guint8 wc;
2885         const char *fn;
2886         int fn_len;
2887
2888         WORD_COUNT;
2889
2890         BYTE_COUNT;
2891
2892         /* Buffer Format */
2893         CHECK_BYTE_COUNT(1);
2894         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2895         COUNT_BYTES(1);
2896
2897         /* File Name */
2898         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2899                 FALSE, FALSE, &bc);
2900         if (fn == NULL)
2901                 goto endofcommand;
2902         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2903                 fn);
2904         COUNT_BYTES(fn_len);
2905
2906         if (check_col(pinfo->cinfo, COL_INFO)) {
2907                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2908         }
2909
2910         END_OF_SMB
2911
2912         return offset;
2913 }
2914  
2915 static int
2916 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2917 {
2918         guint16 bc;
2919         guint8 wc;
2920
2921         WORD_COUNT;
2922
2923         /* File Attributes */
2924         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2925
2926         /* Last Write Time */
2927         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2928
2929         /* File Size */
2930         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2931         offset += 4;
2932
2933         /* 10 reserved bytes */
2934         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2935         offset += 10;
2936
2937         BYTE_COUNT;
2938
2939         END_OF_SMB
2940
2941         return offset;
2942 }
2943
2944 static int
2945 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2946 {
2947         int fn_len;
2948         const char *fn;
2949         guint8 wc;
2950         guint16 bc;
2951
2952         WORD_COUNT;
2953
2954         /* file attributes */
2955         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2956
2957         /* last write time */
2958         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2959
2960         /* 10 reserved bytes */
2961         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2962         offset += 10;
2963
2964         BYTE_COUNT;
2965
2966         /* buffer format */
2967         CHECK_BYTE_COUNT(1);
2968         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2969         COUNT_BYTES(1);
2970
2971         /* file name */
2972         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2973                 FALSE, FALSE, &bc);
2974         if (fn == NULL)
2975                 goto endofcommand;
2976         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2977                 fn);
2978         COUNT_BYTES(fn_len);
2979
2980         if (check_col(pinfo->cinfo, COL_INFO)) {
2981                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2982         }
2983
2984         END_OF_SMB
2985
2986         return offset;
2987 }
2988
2989 static int
2990 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2991 {
2992         guint8 wc;
2993         guint16 bc;
2994         smb_info_t *si;
2995         unsigned int fid;
2996
2997         WORD_COUNT;
2998
2999         /* fid */
3000         fid = tvb_get_letohs(tvb, offset);
3001         add_fid(tvb, pinfo, tree, offset, 2, fid);
3002         offset += 2;
3003         if (!pinfo->fd->flags.visited) {
3004                 /* remember the FID for the processing of the response */
3005                 si = (smb_info_t *)pinfo->private_data;
3006                 si->sip->extra_info=(void *)fid;
3007         }
3008
3009         /* read count */
3010         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3011         offset += 2;
3012
3013         /* offset */
3014         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3015         offset += 4;
3016
3017         /* remaining */
3018         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3019         offset += 2;
3020
3021         BYTE_COUNT;
3022
3023         END_OF_SMB
3024
3025         return offset;
3026 }
3027
3028 int
3029 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3030 {
3031         int tvblen;
3032
3033         if(bc>datalen){
3034                 /* We have some initial padding bytes. */
3035                 /* XXX - use the data offset here instead? */
3036                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3037                         TRUE);
3038                 offset += bc-datalen;
3039                 bc = datalen;
3040         }
3041         tvblen = tvb_length_remaining(tvb, offset);
3042         if(bc>tvblen){
3043                 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);
3044                 offset += tvblen;
3045         } else {
3046                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3047                 offset += bc;
3048         }
3049         return offset;
3050 }
3051
3052 static int
3053 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3054     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3055 {
3056         int tvblen;
3057         tvbuff_t *dcerpc_tvb;
3058
3059         if(bc>datalen){
3060                 /* We have some initial padding bytes. */
3061                 /* XXX - use the data offset here instead? */
3062                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3063                         TRUE);
3064                 offset += bc-datalen;
3065                 bc = datalen;
3066         }
3067         tvblen = tvb_length_remaining(tvb, offset);
3068         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3069         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3070         if(bc>tvblen)
3071                 offset += tvblen;
3072         else
3073                 offset += bc;
3074         return offset;
3075 }
3076
3077 static int
3078 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3079 {
3080         guint16 cnt=0, bc;
3081         guint8 wc;
3082         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3083         int fid=0;
3084
3085         WORD_COUNT;
3086
3087         /* read count */
3088         cnt = tvb_get_letohs(tvb, offset);
3089         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3090         offset += 2;
3091
3092         /* 8 reserved bytes */
3093         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3094         offset += 8;
3095
3096         /* If we have seen the request, then print which FID this refers to */
3097         /* first check if we have seen the request */
3098         if(si->sip != NULL && si->sip->frame_req>0){
3099                 fid=(int)si->sip->extra_info;
3100                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3101         }
3102
3103         BYTE_COUNT;
3104
3105         /* buffer format */
3106         CHECK_BYTE_COUNT(1);
3107         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3108         COUNT_BYTES(1);
3109
3110         /* data len */
3111         CHECK_BYTE_COUNT(2);
3112         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3113         COUNT_BYTES(2);
3114
3115         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3116            read write */
3117         if(bc){
3118                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3119                         /* dcerpc call */
3120                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3121                             top_tree, offset, bc, bc, fid);
3122                 } else {
3123                         /* ordinary file data, or we didn't see the request,
3124                            so we don't know whether this is a DCERPC call
3125                            or not */
3126                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3127                 }
3128                 bc = 0;
3129         }
3130
3131         END_OF_SMB
3132
3133         return offset;
3134 }
3135
3136 static int
3137 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3138 {
3139         guint16 cnt, bc;
3140         guint8 wc;
3141
3142         WORD_COUNT;
3143
3144         /* read count */
3145         cnt = tvb_get_letohs(tvb, offset);
3146         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3147         offset += 2;
3148
3149         /* 8 reserved bytes */
3150         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3151         offset += 8;
3152
3153         BYTE_COUNT;
3154
3155         /* buffer format */
3156         CHECK_BYTE_COUNT(1);
3157         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3158         COUNT_BYTES(1);
3159
3160         /* data len */
3161         CHECK_BYTE_COUNT(2);
3162         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3163         COUNT_BYTES(2);
3164
3165         END_OF_SMB
3166
3167         return offset;
3168 }
3169
3170
3171 static int
3172 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3173 {
3174         guint32 ofs=0;
3175         guint16 cnt=0, bc, fid=0;
3176         guint8 wc;
3177         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3178
3179         WORD_COUNT;
3180
3181         /* fid */
3182         fid = tvb_get_letohs(tvb, offset);
3183         add_fid(tvb, pinfo, tree, offset, 2, fid);
3184         offset += 2;
3185
3186         /* write count */
3187         cnt = tvb_get_letohs(tvb, offset);
3188         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3189         offset += 2;
3190
3191         /* offset */
3192         ofs = tvb_get_letohl(tvb, offset);
3193         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3194         offset += 4;
3195
3196         if (check_col(pinfo->cinfo, COL_INFO))
3197                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3198                                 ", %d byte%s at offset %d", cnt, 
3199                                 (cnt == 1) ? "" : "s", ofs);
3200
3201         /* remaining */
3202         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3203         offset += 2;
3204
3205         BYTE_COUNT;
3206
3207         /* buffer format */
3208         CHECK_BYTE_COUNT(1);
3209         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3210         COUNT_BYTES(1);
3211
3212         /* data len */
3213         CHECK_BYTE_COUNT(2);
3214         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3215         COUNT_BYTES(2);
3216
3217         if (bc != 0) {
3218                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3219                         /* dcerpc call */
3220                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3221                             top_tree, offset, bc, bc, fid);
3222                 } else {
3223                         /* ordinary file data */
3224                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3225                 }
3226                 bc = 0;
3227         }
3228
3229         END_OF_SMB
3230
3231         return offset;
3232 }
3233  
3234 static int
3235 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3236 {
3237         guint8 wc;
3238         guint16 bc, cnt;
3239
3240         WORD_COUNT;
3241
3242         /* write count */
3243         cnt = tvb_get_letohs(tvb, offset);
3244         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3245         offset += 2;
3246
3247         if (check_col(pinfo->cinfo, COL_INFO))
3248                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3249                                 ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
3250
3251         BYTE_COUNT;
3252
3253         END_OF_SMB
3254
3255         return offset;
3256 }
3257
3258 static int
3259 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3260 {
3261         guint8 wc;
3262         guint16 bc, fid;
3263
3264         WORD_COUNT;
3265
3266         /* fid */
3267         fid = tvb_get_letohs(tvb, offset);
3268         add_fid(tvb, pinfo, tree, offset, 2, fid);
3269         offset += 2;
3270
3271         /* lock count */
3272         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3273         offset += 4;
3274
3275         /* offset */
3276         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3277         offset += 4;
3278
3279         BYTE_COUNT;
3280
3281         END_OF_SMB
3282
3283         return offset;
3284 }
3285
3286 static int
3287 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3288 {
3289         int fn_len;
3290         const char *fn;
3291         guint8 wc;
3292         guint16 bc;
3293
3294         WORD_COUNT;
3295
3296         /* 2 reserved bytes */
3297         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3298         offset += 2;
3299
3300         /* Creation time */
3301         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3302
3303         BYTE_COUNT;
3304
3305         /* buffer format */
3306         CHECK_BYTE_COUNT(1);
3307         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3308         COUNT_BYTES(1);
3309
3310         /* directory name */
3311         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3312                 FALSE, FALSE, &bc);
3313         if (fn == NULL)
3314                 goto endofcommand;
3315         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3316                 fn);
3317         COUNT_BYTES(fn_len);
3318
3319         if (check_col(pinfo->cinfo, COL_INFO)) {
3320                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3321         }
3322
3323         END_OF_SMB
3324
3325         return offset;
3326 }
3327
3328 static int
3329 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3330 {
3331         int fn_len;
3332         const char *fn;
3333         guint8 wc;
3334         guint16 bc, fid;
3335
3336         WORD_COUNT;
3337
3338         /* fid */
3339         fid = tvb_get_letohs(tvb, offset);
3340         add_fid(tvb, pinfo, tree, offset, 2, fid);
3341         offset += 2;
3342
3343         BYTE_COUNT;
3344
3345         /* buffer format */
3346         CHECK_BYTE_COUNT(1);
3347         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3348         COUNT_BYTES(1);
3349
3350         /* file name */
3351         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3352                 FALSE, FALSE, &bc);
3353         if (fn == NULL)
3354                 goto endofcommand;
3355         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3356                 fn);
3357         COUNT_BYTES(fn_len);
3358
3359         END_OF_SMB
3360
3361         return offset;
3362 }
3363
3364 static const value_string seek_mode_vals[] = {
3365         {0,     "From Start Of File"},
3366         {1,     "From Current Position"},
3367         {2,     "From End Of File"},
3368         {0,     NULL}
3369 };
3370
3371 static int
3372 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3373 {
3374         guint8 wc;
3375         guint16 bc, fid;
3376
3377         WORD_COUNT;
3378
3379         /* fid */
3380         fid = tvb_get_letohs(tvb, offset);
3381         add_fid(tvb, pinfo, tree, offset, 2, fid);
3382         offset += 2;
3383
3384         /* Seek Mode */
3385         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3386         offset += 2;
3387
3388         /* offset */
3389         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3390         offset += 4;
3391
3392         BYTE_COUNT;
3393
3394         END_OF_SMB
3395
3396         return offset;
3397 }
3398
3399 static int
3400 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3401 {
3402         guint8 wc;
3403         guint16 bc;
3404
3405         WORD_COUNT;
3406
3407         /* offset */
3408         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3409         offset += 4;
3410
3411         BYTE_COUNT;
3412
3413         END_OF_SMB
3414
3415         return offset;
3416 }
3417  
3418 static int
3419 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3420 {
3421         guint8 wc;
3422         guint16 bc, fid;
3423
3424         WORD_COUNT;
3425
3426         /* fid */
3427         fid = tvb_get_letohs(tvb, offset);
3428         add_fid(tvb, pinfo, tree, offset, 2, fid);
3429         offset += 2;
3430
3431         /* create time */
3432         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3433                 hf_smb_create_time,
3434                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3435
3436         /* access time */
3437         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3438                 hf_smb_access_time,
3439                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3440
3441         /* last write time */
3442         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3443                 hf_smb_last_write_time,
3444                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3445
3446         BYTE_COUNT;
3447
3448         END_OF_SMB
3449
3450         return offset;
3451 }
3452
3453 static int
3454 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3455 {
3456         guint8 wc;
3457         guint16 bc;
3458
3459         WORD_COUNT;
3460
3461         /* create time */
3462         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3463                 hf_smb_create_time,
3464                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3465
3466         /* access time */
3467         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3468                 hf_smb_access_time,
3469                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3470
3471         /* last write time */
3472         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3473                 hf_smb_last_write_time,
3474                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3475
3476         /* data size */
3477         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3478         offset += 4;
3479
3480         /* allocation size */
3481         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3482         offset += 4;
3483
3484         /* File Attributes */
3485         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3486
3487         BYTE_COUNT;
3488
3489         END_OF_SMB
3490
3491         return offset;
3492 }
3493
3494 static int
3495 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3496 {
3497         guint8 wc;
3498         guint16 cnt=0;
3499         guint16 bc, fid;
3500
3501         WORD_COUNT;
3502
3503         /* fid */
3504         fid = tvb_get_letohs(tvb, offset);
3505         add_fid(tvb, pinfo, tree, offset, 2, fid);
3506         offset += 2;
3507
3508         /* write count */
3509         cnt = tvb_get_letohs(tvb, offset);
3510         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3511         offset += 2;
3512
3513         /* offset */
3514         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3515         offset += 4;
3516
3517         /* last write time */
3518         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3519         
3520         if(wc==12){
3521                 /* 12 reserved bytes */
3522                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3523                 offset += 12;
3524         }
3525
3526         BYTE_COUNT;
3527
3528         /* 1 pad byte */
3529         CHECK_BYTE_COUNT(1);
3530         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3531         COUNT_BYTES(1);
3532         
3533         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3534         bc = 0; /* XXX */
3535
3536         END_OF_SMB
3537
3538         return offset;
3539 }
3540  
3541 static int
3542 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3543 {
3544         guint8 wc;
3545         guint16 bc;
3546
3547         WORD_COUNT;
3548
3549         /* write count */
3550         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3551         offset += 2;
3552
3553         BYTE_COUNT;
3554
3555         END_OF_SMB
3556
3557         return offset;
3558 }
3559
3560 static int
3561 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3562 {
3563         guint8 wc;
3564         guint16 bc, fid;
3565         guint32 to;
3566
3567         WORD_COUNT;
3568
3569         /* fid */
3570         fid = tvb_get_letohs(tvb, offset);
3571         add_fid(tvb, pinfo, tree, offset, 2, fid);
3572         offset += 2;
3573
3574         /* offset */
3575         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3576         offset += 4;
3577
3578         /* max count */
3579         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3580         offset += 2;
3581
3582         /* min count */
3583         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3584         offset += 2;
3585
3586         /* timeout */
3587         to = tvb_get_letohl(tvb, offset);
3588         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3589         offset += 4;
3590
3591         /* 2 reserved bytes */
3592         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3593         offset += 2;
3594
3595         if(wc==10){
3596                 /* high offset */
3597                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3598                 offset += 4;
3599         }
3600
3601         BYTE_COUNT;
3602
3603         END_OF_SMB
3604
3605         return offset;
3606 }
3607
3608 static int
3609 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3610 {
3611         guint8 wc;
3612         guint16 bc;
3613
3614         WORD_COUNT;
3615
3616         /* units */
3617         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3618         offset += 2;
3619
3620         /* bpu */
3621         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3622         offset += 2;
3623
3624         /* block size */
3625         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3626         offset += 2;
3627
3628         /* free units */
3629         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3630         offset += 2;
3631
3632         /* 2 reserved bytes */
3633         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3634         offset += 2;
3635
3636         BYTE_COUNT;
3637
3638         END_OF_SMB
3639
3640         return offset;
3641 }
3642
3643 static int
3644 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3645 {
3646         guint8 wc;
3647         guint16 bc, fid;
3648
3649         WORD_COUNT;
3650
3651         /* fid */
3652         fid = tvb_get_letohs(tvb, offset);
3653         add_fid(tvb, pinfo, tree, offset, 2, fid);
3654         offset += 2;
3655
3656         /* offset */
3657         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3658         offset += 4;
3659
3660         /* max count */
3661         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3662         offset += 2;
3663
3664         /* min count */
3665         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3666         offset += 2;
3667
3668         /* 6 reserved bytes */
3669         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3670         offset += 6;
3671
3672         BYTE_COUNT;
3673
3674         END_OF_SMB
3675
3676         return offset;
3677 }
3678
3679 static int
3680 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3681 {
3682         guint16 datalen=0, bc;
3683         guint8 wc;
3684
3685         WORD_COUNT;
3686
3687         /* offset */
3688         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3689         offset += 4;
3690
3691         /* count */
3692         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3693         offset += 2;
3694
3695         /* 2 reserved bytes */
3696         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3697         offset += 2;
3698
3699         /* data compaction mode */
3700         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3701         offset += 2;
3702
3703         /* 2 reserved bytes */
3704         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3705         offset += 2;
3706
3707         /* data len */
3708         datalen = tvb_get_letohs(tvb, offset);
3709         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3710         offset += 2;
3711
3712         /* data offset */
3713         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3714         offset += 2;
3715
3716         BYTE_COUNT;
3717
3718         /* file data */
3719         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3720         bc = 0;
3721
3722         END_OF_SMB
3723
3724         return offset;
3725 }
3726
3727
3728 static const true_false_string tfs_write_mode_write_through = {
3729         "WRITE THROUGH requested",
3730         "Write through not requested"
3731 };
3732 static const true_false_string tfs_write_mode_return_remaining = {
3733         "RETURN REMAINING (pipe/dev) requested",
3734         "DON'T return remaining (pipe/dev)"
3735 };
3736 static const true_false_string tfs_write_mode_raw = {
3737         "Use WriteRawNamedPipe (pipe)",
3738         "DON'T use WriteRawNamedPipe (pipe)"
3739 };
3740 static const true_false_string tfs_write_mode_message_start = {
3741         "This is the START of a MESSAGE (pipe)",
3742         "This is NOT the start of a message (pipe)"
3743 };
3744 static const true_false_string tfs_write_mode_connectionless = {
3745         "CONNECTIONLESS mode requested",
3746         "Connectionless mode NOT requested"
3747 };
3748 static int
3749 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3750 {
3751         guint16 mask;
3752         proto_item *item = NULL;
3753         proto_tree *tree = NULL;
3754
3755         mask = tvb_get_letohs(tvb, offset);
3756
3757         if(parent_tree){
3758                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3759                         "Write Mode: 0x%04x", mask);
3760                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3761         }
3762
3763         if(bm&0x0080){
3764                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3765                         tvb, offset, 2, mask);
3766         }
3767         if(bm&0x0008){
3768                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3769                         tvb, offset, 2, mask);
3770         }
3771         if(bm&0x0004){
3772                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3773                         tvb, offset, 2, mask);
3774         }
3775         if(bm&0x0002){
3776                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3777                         tvb, offset, 2, mask);
3778         }
3779         if(bm&0x0001){
3780                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3781                         tvb, offset, 2, mask);
3782         }
3783
3784         offset += 2;
3785         return offset;
3786 }
3787
3788 static int
3789 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3790 {
3791         guint32 to;
3792         guint16 datalen=0, bc, fid;
3793         guint8 wc;
3794
3795         WORD_COUNT;
3796
3797         /* fid */
3798         fid = tvb_get_letohs(tvb, offset);
3799         add_fid(tvb, pinfo, tree, offset, 2, fid);
3800         offset += 2;
3801
3802         /* total data length */
3803         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3804         offset += 2;
3805
3806         /* 2 reserved bytes */
3807         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3808         offset += 2;
3809
3810         /* offset */
3811         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3812         offset += 4;
3813
3814         /* timeout */
3815         to = tvb_get_letohl(tvb, offset);
3816         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3817         offset += 4;
3818
3819         /* mode */
3820         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3821
3822         /* 4 reserved bytes */
3823         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3824         offset += 4;
3825
3826         /* data len */
3827         datalen = tvb_get_letohs(tvb, offset);
3828         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3829         offset += 2;
3830
3831         /* data offset */
3832         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3833         offset += 2;
3834
3835         BYTE_COUNT;
3836
3837         /* file data */
3838         /* XXX - use the data offset to determine where the data starts? */
3839         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3840         bc = 0;
3841
3842         END_OF_SMB
3843
3844         return offset;
3845 }
3846  
3847 static int
3848 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3849 {
3850         guint8 wc;
3851         guint16 bc;
3852
3853         WORD_COUNT;
3854
3855         /* remaining */
3856         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3857         offset += 2;
3858
3859         BYTE_COUNT;
3860
3861         END_OF_SMB
3862
3863         return offset;
3864 }
3865
3866 static int
3867 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3868 {
3869         guint32 to;
3870         guint16 datalen=0, bc, fid;
3871         guint8 wc;
3872
3873         WORD_COUNT;
3874
3875         /* fid */
3876         fid = tvb_get_letohs(tvb, offset);
3877         add_fid(tvb, pinfo, tree, offset, 2, fid);
3878         offset += 2;
3879
3880         /* total data length */
3881         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3882         offset += 2;
3883
3884         /* 2 reserved bytes */
3885         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3886         offset += 2;
3887
3888         /* offset */
3889         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3890         offset += 4;
3891
3892         /* timeout */
3893         to = tvb_get_letohl(tvb, offset);
3894         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3895         offset += 4;
3896
3897         /* mode */
3898         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3899
3900         /* request mask */
3901         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3902         offset += 4;
3903         
3904         /* data len */
3905         datalen = tvb_get_letohs(tvb, offset);
3906         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3907         offset += 2;
3908
3909         /* data offset */
3910         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3911         offset += 2;
3912
3913         BYTE_COUNT;
3914
3915         /* file data */
3916         /* XXX - use the data offset to determine where the data starts? */
3917         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3918         bc = 0;
3919
3920         END_OF_SMB
3921
3922         return offset;
3923 }
3924  
3925 static int
3926 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3927 {
3928         guint8 wc;
3929         guint16 bc;
3930
3931         WORD_COUNT;
3932
3933         /* response mask */
3934         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
3935         offset += 4;
3936         
3937         BYTE_COUNT;
3938
3939         END_OF_SMB
3940
3941         return offset;
3942 }
3943
3944 static int
3945 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3946 {
3947         guint8 wc;
3948         guint16 bc;
3949
3950         WORD_COUNT;
3951
3952         /* sid */
3953         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
3954         offset += 2;
3955
3956         BYTE_COUNT;
3957
3958         END_OF_SMB
3959
3960         return offset;
3961 }
3962
3963 static int
3964 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
3965     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3966 {
3967         proto_item *item = NULL;
3968         proto_tree *tree = NULL;
3969         int fn_len;
3970         const char *fn;
3971         char fname[11+1];
3972
3973         if(parent_tree){
3974                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
3975                         "Resume Key");
3976                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
3977         }
3978
3979         /* reserved byte */
3980         CHECK_BYTE_COUNT_SUBR(1);
3981         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
3982         COUNT_BYTES_SUBR(1);
3983
3984         /* file name */
3985         fn_len = 11;
3986         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3987                 TRUE, TRUE, bcp);
3988         CHECK_STRING_SUBR(fn);
3989         /* ensure that it's null-terminated */
3990         strncpy(fname, fn, 11);
3991         fname[11] = '\0';
3992         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
3993                 fname);
3994         COUNT_BYTES_SUBR(fn_len);
3995
3996         /* server cookie */
3997         CHECK_BYTE_COUNT_SUBR(5);
3998         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
3999         COUNT_BYTES_SUBR(5);
4000
4001         /* client cookie */
4002         CHECK_BYTE_COUNT_SUBR(4);
4003         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4004         COUNT_BYTES_SUBR(4);
4005
4006         *trunc = FALSE;
4007         return offset;
4008 }
4009
4010 static int
4011 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4012     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
4013 {
4014         proto_item *item = NULL;
4015         proto_tree *tree = NULL;
4016         int fn_len;
4017         const char *fn;
4018         char fname[13+1];
4019
4020         if(parent_tree){
4021                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4022                         "Directory Information");
4023                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4024         }
4025
4026         /* resume key */
4027         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
4028         if (*trunc)
4029                 return offset;
4030
4031         /* File Attributes */
4032         CHECK_BYTE_COUNT_SUBR(1);
4033         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
4034         *bcp -= 1;
4035
4036         /* last write time */
4037         CHECK_BYTE_COUNT_SUBR(4);
4038         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
4039                 hf_smb_last_write_time,
4040                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4041                 TRUE);
4042         *bcp -= 4;
4043
4044         /* File Size */
4045         CHECK_BYTE_COUNT_SUBR(4);
4046         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4047         COUNT_BYTES_SUBR(4);
4048
4049         /* file name */
4050         fn_len = 13;
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, 13);
4056         fname[13] = '\0';
4057         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4058                 fname);
4059         COUNT_BYTES_SUBR(fn_len);
4060
4061         *trunc = FALSE;
4062         return offset;
4063 }
4064
4065
4066 static int
4067 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4068 {
4069         int fn_len;
4070         const char *fn;
4071         guint16 rkl;
4072         guint8 wc;
4073         guint16 bc;
4074         gboolean trunc;
4075
4076         WORD_COUNT;
4077
4078         /* max count */
4079         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4080         offset += 2;
4081
4082         /* Search Attributes */
4083         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4084
4085         BYTE_COUNT;
4086
4087         /* buffer format */
4088         CHECK_BYTE_COUNT(1);
4089         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4090         COUNT_BYTES(1);
4091
4092         /* file name */
4093         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4094                 TRUE, FALSE, &bc);
4095         if (fn == NULL)
4096                 goto endofcommand;
4097         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4098                 fn);
4099         COUNT_BYTES(fn_len);
4100
4101         if (check_col(pinfo->cinfo, COL_INFO)) {
4102                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4103         }
4104
4105         /* buffer format */
4106         CHECK_BYTE_COUNT(1);
4107         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4108         COUNT_BYTES(1);
4109
4110         /* resume key length */
4111         CHECK_BYTE_COUNT(2);
4112         rkl = tvb_get_letohs(tvb, offset);
4113         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4114         COUNT_BYTES(2);
4115
4116         /* resume key */
4117         if(rkl){
4118                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4119                     &bc, &trunc);
4120                 if (trunc)
4121                         goto endofcommand;
4122         }
4123
4124         END_OF_SMB
4125
4126         return offset;
4127 }
4128
4129 static int
4130 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4131 {
4132         guint16 count=0;
4133         guint8 wc;
4134         guint16 bc;
4135         gboolean trunc;
4136
4137         WORD_COUNT;
4138
4139         /* count */
4140         count = tvb_get_letohs(tvb, offset);
4141         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4142         offset += 2;
4143
4144         BYTE_COUNT;
4145
4146         /* buffer format */
4147         CHECK_BYTE_COUNT(1);
4148         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4149         COUNT_BYTES(1);
4150
4151         /* data len */
4152         CHECK_BYTE_COUNT(2);
4153         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4154         COUNT_BYTES(2);
4155
4156         while(count--){
4157                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4158                     &bc, &trunc);
4159                 if (trunc)
4160                         goto endofcommand;
4161         }
4162
4163         END_OF_SMB
4164
4165         return offset;
4166 }
4167
4168 static const value_string locking_ol_vals[] = {
4169         {0,     "Client is not holding oplock on this file"},
4170         {1,     "Level 2 oplock currently held by client"},
4171         {0, NULL}
4172 };
4173
4174 static const true_false_string tfs_lock_type_large = {
4175         "Large file locking format requested",
4176         "Large file locking format not requested"
4177 };
4178 static const true_false_string tfs_lock_type_cancel = {
4179         "Cancel outstanding lock request",
4180         "Don't cancel outstanding lock request"
4181 };
4182 static const true_false_string tfs_lock_type_change = {
4183         "Change lock type",
4184         "Don't change lock type"
4185 };
4186 static const true_false_string tfs_lock_type_oplock = {
4187         "This is an oplock break notification/response",
4188         "This is not an oplock break notification/response"
4189 };
4190 static const true_false_string tfs_lock_type_shared = {
4191         "This is a shared lock",
4192         "This is an exclusive lock"
4193 };
4194 static int
4195 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4196 {
4197         guint8  wc, cmd=0xff, lt=0;
4198         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4199         guint32 to;
4200         proto_item *litem = NULL;
4201         proto_tree *ltree = NULL;
4202         proto_item *it = NULL;
4203         proto_tree *tr = NULL;
4204         int old_offset = offset;
4205
4206         WORD_COUNT;
4207
4208         /* next smb command */
4209         cmd = tvb_get_guint8(tvb, offset);
4210         if(cmd!=0xff){
4211                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4212         } else {
4213                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4214         }
4215         offset += 1;
4216
4217         /* reserved byte */
4218         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4219         offset += 1;
4220
4221         /* andxoffset */
4222         andxoffset = tvb_get_letohs(tvb, offset);
4223         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4224         offset += 2;
4225
4226         /* fid */
4227         fid = tvb_get_letohs(tvb, offset);
4228         add_fid(tvb, pinfo, tree, offset, 2, fid);
4229         offset += 2;
4230
4231         /* lock type */
4232         lt = tvb_get_guint8(tvb, offset);
4233         if(tree){
4234                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4235                         "Lock Type: 0x%02x", lt);
4236                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4237         }
4238         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4239                 tvb, offset, 1, lt);
4240         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4241                 tvb, offset, 1, lt);
4242         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4243                 tvb, offset, 1, lt);
4244         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4245                 tvb, offset, 1, lt);
4246         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4247                 tvb, offset, 1, lt);
4248         offset += 1;
4249
4250         /* oplock level */
4251         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4252         offset += 1;
4253
4254         /* timeout */
4255         to = tvb_get_letohl(tvb, offset);
4256         if (to == 0)
4257                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4258         else if (to == 0xffffffff)
4259                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4260         else
4261                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4262         offset += 4;
4263
4264         /* number of unlocks */
4265         un = tvb_get_letohs(tvb, offset);
4266         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4267         offset += 2;
4268
4269         /* number of locks */
4270         ln = tvb_get_letohs(tvb, offset);
4271         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4272         offset += 2;
4273
4274         BYTE_COUNT;
4275
4276         /* unlocks */
4277         if(un){
4278                 old_offset = offset;
4279
4280                 it = proto_tree_add_text(tree, tvb, offset, -1,
4281                         "Unlocks");
4282                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4283                 while(un--){
4284                         proto_item *litem = NULL;
4285                         proto_tree *ltree = NULL;
4286                         if(lt&0x10){
4287                                 /* large lock format */
4288                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4289                                         "Unlock");
4290                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4291                                 
4292                                 /* PID */
4293                                 CHECK_BYTE_COUNT(2);
4294                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4295                                 COUNT_BYTES(2);
4296
4297                                 /* 2 reserved bytes */
4298                                 CHECK_BYTE_COUNT(2);
4299                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4300                                 COUNT_BYTES(2);
4301
4302                                 /* offset */
4303                                 CHECK_BYTE_COUNT(8);
4304                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4305                                 COUNT_BYTES(8);
4306
4307                                 /* length */
4308                                 CHECK_BYTE_COUNT(8);
4309                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4310                                 COUNT_BYTES(8);
4311                         } else {
4312                                 /* normal lock format */
4313                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4314                                         "Unlock");
4315                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4316                                 
4317                                 /* PID */
4318                                 CHECK_BYTE_COUNT(2);
4319                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4320                                 COUNT_BYTES(2);
4321
4322                                 /* offset */
4323                                 CHECK_BYTE_COUNT(4);
4324                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4325                                 COUNT_BYTES(4);
4326
4327                                 /* lock count */
4328                                 CHECK_BYTE_COUNT(4);
4329                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4330                                 COUNT_BYTES(4);
4331                         }
4332                 }
4333                 proto_item_set_len(it, offset-old_offset);
4334                 it = NULL;
4335         }
4336
4337         /* locks */
4338         if(ln){
4339                 old_offset = offset;
4340
4341                 it = proto_tree_add_text(tree, tvb, offset, -1,
4342                         "Locks");
4343                 tr = proto_item_add_subtree(it, ett_smb_locks);
4344                 while(ln--){
4345                         proto_item *litem = NULL;
4346                         proto_tree *ltree = NULL;
4347                         if(lt&0x10){
4348                                 /* large lock format */
4349                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4350                                         "Lock");
4351                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4352                                 
4353                                 /* PID */
4354                                 CHECK_BYTE_COUNT(2);
4355                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4356                                 COUNT_BYTES(2);
4357
4358                                 /* 2 reserved bytes */
4359                                 CHECK_BYTE_COUNT(2);
4360                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4361                                 COUNT_BYTES(2);
4362
4363                                 /* offset */
4364                                 CHECK_BYTE_COUNT(8);
4365                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4366                                 COUNT_BYTES(8);
4367
4368                                 /* length */
4369                                 CHECK_BYTE_COUNT(8);
4370                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4371                                 COUNT_BYTES(8);
4372                         } else {
4373                                 /* normal lock format */
4374                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4375                                         "Unlock");
4376                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4377                                 
4378                                 /* PID */
4379                                 CHECK_BYTE_COUNT(2);
4380                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4381                                 COUNT_BYTES(2);
4382
4383                                 /* offset */
4384                                 CHECK_BYTE_COUNT(4);
4385                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4386                                 COUNT_BYTES(4);
4387
4388                                 /* lock count */
4389                                 CHECK_BYTE_COUNT(4);
4390                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4391                                 COUNT_BYTES(4);
4392                         }
4393                 }
4394                 proto_item_set_len(it, offset-old_offset);
4395                 it = NULL;
4396         }
4397
4398         END_OF_SMB
4399
4400         if (it != NULL) {
4401                 /*
4402                  * We ran out of byte count in the middle of dissecting
4403                  * the locks or the unlocks; set the site of the item
4404                  * we were dissecting.
4405                  */
4406                 proto_item_set_len(it, offset-old_offset);
4407         }
4408
4409         /* call AndXCommand (if there are any) */
4410         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4411
4412         return offset;
4413 }
4414
4415 static int
4416 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4417 {
4418         guint8  wc, cmd=0xff;
4419         guint16 andxoffset=0;
4420         guint16 bc;
4421
4422         WORD_COUNT;
4423
4424         /* next smb command */
4425         cmd = tvb_get_guint8(tvb, offset);
4426         if(cmd!=0xff){
4427                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4428         } else {
4429                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4430         }
4431         offset += 1;
4432
4433         /* reserved byte */
4434         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4435         offset += 1;
4436
4437         /* andxoffset */
4438         andxoffset = tvb_get_letohs(tvb, offset);
4439         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4440         offset += 2;
4441
4442         BYTE_COUNT;
4443
4444         END_OF_SMB
4445
4446         /* call AndXCommand (if there are any) */
4447         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4448
4449         return offset;
4450 }
4451
4452
4453 static const value_string oa_open_vals[] = {
4454         { 0,            "No action taken?"},
4455         { 1,            "The file existed and was opened"},
4456         { 2,            "The file did not exist but was created"},
4457         { 3,            "The file existed and was truncated"},
4458         {0,     NULL}
4459 };
4460 static const true_false_string tfs_oa_lock = {
4461         "File is currently opened only by this user",
4462         "File is opened by another user (or mode not supported by server)"
4463 };
4464 static int
4465 dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4466 {
4467         guint16 mask;
4468         proto_item *item = NULL;
4469         proto_tree *tree = NULL;
4470
4471         mask = tvb_get_letohs(tvb, offset);
4472
4473         if(parent_tree){
4474                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4475                         "Action: 0x%04x", mask);
4476                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4477         }
4478
4479         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4480                 tvb, offset, 2, mask);
4481         proto_tree_add_uint(tree, hf_smb_open_action_open,
4482                 tvb, offset, 2, mask);
4483
4484         offset += 2;
4485
4486         return offset;
4487 }
4488
4489 static const true_false_string tfs_open_flags_add_info = {
4490         "Additional information requested",
4491         "Additional information not requested"
4492 };
4493 static const true_false_string tfs_open_flags_ex_oplock = {
4494         "Exclusive oplock requested",
4495         "Exclusive oplock not requested"
4496 };
4497 static const true_false_string tfs_open_flags_batch_oplock = {
4498         "Batch oplock requested",
4499         "Batch oplock not requested"
4500 };
4501 static const true_false_string tfs_open_flags_ealen = {
4502         "Total length of EAs requested",
4503         "Total length of EAs not requested"
4504 };
4505 static int
4506 dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
4507 {
4508         guint16 mask;
4509         proto_item *item = NULL;
4510         proto_tree *tree = NULL;
4511
4512         mask = tvb_get_letohs(tvb, offset);
4513
4514         if(parent_tree){
4515                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4516                         "Flags: 0x%04x", mask);
4517                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4518         }
4519
4520         if(bm&0x0001){
4521                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4522                         tvb, offset, 2, mask);
4523         }
4524         if(bm&0x0002){
4525                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4526                         tvb, offset, 2, mask);
4527         }
4528         if(bm&0x0004){
4529                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4530                         tvb, offset, 2, mask);
4531         }
4532         if(bm&0x0008){
4533                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4534                         tvb, offset, 2, mask);
4535         }
4536
4537         offset += 2;
4538
4539         return offset;
4540 }
4541
4542 static const value_string filetype_vals[] = {
4543         { 0,            "Disk file or directory"},
4544         { 1,            "Named pipe in byte mode"},
4545         { 2,            "Named pipe in message mode"},
4546         { 3,            "Spooled printer"},
4547         {0, NULL}
4548 };
4549 static int
4550 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4551 {
4552         guint8  wc, cmd=0xff;
4553         guint16 andxoffset=0, bc;
4554         int fn_len;
4555         const char *fn;
4556
4557         WORD_COUNT;
4558
4559         /* next smb command */
4560         cmd = tvb_get_guint8(tvb, offset);
4561         if(cmd!=0xff){
4562                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4563         } else {
4564                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4565         }
4566         offset += 1;
4567
4568         /* reserved byte */
4569         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4570         offset += 1;
4571
4572         /* andxoffset */
4573         andxoffset = tvb_get_letohs(tvb, offset);
4574         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4575         offset += 2;
4576
4577         /* open flags */
4578         offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
4579
4580         /* desired access */
4581         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
4582
4583         /* Search Attributes */
4584         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4585
4586         /* File Attributes */
4587         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4588
4589         /* creation time */
4590         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
4591         
4592         /* open function */
4593         offset = dissect_open_function(tvb, pinfo, tree, offset);
4594
4595         /* allocation size */
4596         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4597         offset += 4;
4598
4599         /* 8 reserved bytes */
4600         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4601         offset += 8;
4602
4603         BYTE_COUNT;
4604
4605         /* file name */
4606         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4607                 FALSE, FALSE, &bc);
4608         if (fn == NULL)
4609                 goto endofcommand;
4610         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4611                 fn);
4612         COUNT_BYTES(fn_len);
4613
4614         if (check_col(pinfo->cinfo, COL_INFO)) {
4615                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4616         }
4617
4618         END_OF_SMB
4619
4620         /* call AndXCommand (if there are any) */
4621         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4622
4623         return offset;
4624 }
4625
4626 static const true_false_string tfs_ipc_state_nonblocking = {
4627         "Reads/writes return immediately if no data available",
4628         "Reads/writes block if no data available"
4629 };
4630 static const value_string ipc_state_endpoint_vals[] = {
4631         { 0,            "Consumer end of pipe"},
4632         { 1,            "Server end of pipe"},
4633         {0,     NULL}
4634 };
4635 static const value_string ipc_state_pipe_type_vals[] = {
4636         { 0,            "Byte stream pipe"},
4637         { 1,            "Message pipe"},
4638         {0,     NULL}
4639 };
4640 static const value_string ipc_state_read_mode_vals[] = {
4641         { 0,            "Read pipe as a byte stream"},
4642         { 1,            "Read messages from pipe"},
4643         {0,     NULL}
4644 };
4645
4646 int
4647 dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
4648     int offset, gboolean setstate)
4649 {
4650         guint16 mask;
4651         proto_item *item = NULL;
4652         proto_tree *tree = NULL;
4653
4654         mask = tvb_get_letohs(tvb, offset);
4655
4656         if(parent_tree){
4657                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4658                         "IPC State: 0x%04x", mask);
4659                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4660         }
4661
4662         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4663                 tvb, offset, 2, mask);
4664         if (!setstate) {
4665                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4666                         tvb, offset, 2, mask);
4667                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4668                         tvb, offset, 2, mask);
4669         }
4670         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4671                 tvb, offset, 2, mask);
4672         if (!setstate) {
4673                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4674                         tvb, offset, 2, mask);
4675         }
4676
4677         offset += 2;
4678
4679         return offset;
4680 }
4681
4682 static int
4683 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4684 {
4685         guint8  wc, cmd=0xff;
4686         guint16 andxoffset=0, bc;
4687         guint16 fid;
4688
4689         WORD_COUNT;
4690
4691         /* next smb command */
4692         cmd = tvb_get_guint8(tvb, offset);
4693         if(cmd!=0xff){
4694                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4695         } else {
4696                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4697         }
4698         offset += 1;
4699
4700         /* reserved byte */
4701         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4702         offset += 1;
4703
4704         /* andxoffset */
4705         andxoffset = tvb_get_letohs(tvb, offset);
4706         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4707         offset += 2;
4708
4709         /* fid */
4710         fid = tvb_get_letohs(tvb, offset);
4711         add_fid(tvb, pinfo, tree, offset, 2, fid);
4712         offset += 2;
4713
4714         /* File Attributes */
4715         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4716
4717         /* last write time */
4718         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
4719         
4720         /* File Size */
4721         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4722         offset += 4;
4723
4724         /* granted access */
4725         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
4726
4727         /* File Type */
4728         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
4729         offset += 2;
4730
4731         /* IPC State */
4732         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
4733
4734         /* open_action */
4735         offset = dissect_open_action(tvb, pinfo, tree, offset);
4736
4737         /* server fid */
4738         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
4739         offset += 4;
4740
4741         /* 2 reserved bytes */
4742         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4743         offset += 2;
4744
4745         BYTE_COUNT;
4746
4747         END_OF_SMB
4748
4749         /* call AndXCommand (if there are any) */
4750         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4751
4752         return offset;
4753 }
4754
4755 static int
4756 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4757 {
4758         guint8  wc, cmd=0xff;
4759         guint16 andxoffset=0, bc, maxcnt = 0;
4760         guint32 ofs = 0;
4761         smb_info_t *si;
4762         unsigned int fid;
4763
4764         WORD_COUNT;
4765
4766         /* next smb command */
4767         cmd = tvb_get_guint8(tvb, offset);
4768         if(cmd!=0xff){
4769                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4770         } else {
4771                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4772         }
4773         offset += 1;
4774
4775         /* reserved byte */
4776         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4777         offset += 1;
4778
4779         /* andxoffset */
4780         andxoffset = tvb_get_letohs(tvb, offset);
4781         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4782         offset += 2;
4783
4784         /* fid */
4785         fid = tvb_get_letohs(tvb, offset);
4786         add_fid(tvb, pinfo, tree, offset, 2, fid);
4787         offset += 2;
4788         if (!pinfo->fd->flags.visited) {
4789                 /* remember the FID for the processing of the response */
4790                 si = (smb_info_t *)pinfo->private_data;
4791                 si->sip->extra_info=(void *)fid;
4792         }
4793
4794         /* offset */
4795         ofs = tvb_get_letohl(tvb, offset);
4796         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4797         offset += 4;
4798
4799         /* max count */
4800         maxcnt = tvb_get_letohs(tvb, offset);
4801         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4802         offset += 2;
4803
4804         if (check_col(pinfo->cinfo, COL_INFO))
4805                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4806                                 ", %d byte%s at offset %d", maxcnt, 
4807                                 (maxcnt == 1) ? "" : "s", ofs);
4808
4809         /* min count */
4810         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4811         offset += 2;
4812
4813         /* XXX - max count high */
4814         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4815         offset += 4;
4816
4817         /* remaining */
4818         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4819         offset += 2;
4820
4821         if(wc==12){
4822                 /* high offset */
4823                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4824                 offset += 4;
4825         }
4826
4827         BYTE_COUNT;
4828
4829         END_OF_SMB
4830
4831         /* call AndXCommand (if there are any) */
4832         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4833
4834         return offset;
4835 }
4836
4837 static int
4838 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4839 {
4840         guint8  wc, cmd=0xff;
4841         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4842         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4843         int fid=0;
4844
4845         WORD_COUNT;
4846
4847         /* next smb command */
4848         cmd = tvb_get_guint8(tvb, offset);
4849         if(cmd!=0xff){
4850                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4851         } else {
4852                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4853         }
4854         offset += 1;
4855  
4856         /* reserved byte */
4857         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4858         offset += 1;
4859
4860         /* andxoffset */
4861         andxoffset = tvb_get_letohs(tvb, offset);
4862         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4863         offset += 2;
4864
4865         /* If we have seen the request, then print which FID this refers to */
4866         /* first check if we have seen the request */
4867         if(si->sip != NULL && si->sip->frame_req>0){
4868                 fid=(int)si->sip->extra_info;
4869                 add_fid(tvb, pinfo, tree, 0, 0, fid);
4870         }
4871
4872         /* remaining */
4873         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4874         offset += 2;
4875
4876         /* data compaction mode */
4877         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4878         offset += 2;
4879
4880         /* 2 reserved bytes */
4881         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4882         offset += 2;
4883
4884         /* data len */
4885         datalen = tvb_get_letohs(tvb, offset);
4886         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4887         offset += 2;
4888
4889         if (check_col(pinfo->cinfo, COL_INFO))
4890                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4891                                 ", %d byte%s", datalen, 
4892                                 (datalen == 1) ? "" : "s");
4893
4894         /* data offset */
4895         dataoffset=tvb_get_letohs(tvb, offset);
4896         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
4897         offset += 2;
4898
4899         /* 10 reserved bytes */
4900         /* XXX - first 2 bytes are data length high, not reserved */
4901         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4902         offset += 10;
4903
4904         BYTE_COUNT;
4905
4906         /* is this part of DCERPC over SMB reassembly?*/
4907         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
4908             && (bc<=tvb_length_remaining(tvb, offset)) ){
4909                 gpointer hash_value;
4910                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
4911                                                 si->ct->dcerpc_fid_to_frame,
4912                                                 si->sip->extra_info)) != NULL) {
4913                         fragment_data *fd_head;
4914                         guint32 frame = GPOINTER_TO_UINT(hash_value);
4915
4916                         /* first fragment is always from a SMB Trans command and
4917                            offset 0 of the following read/write SMB commands start
4918                            BEYOND the first Trans SMB payload. Look for offset
4919                            in first read fragment */
4920                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
4921                         if(fd_head){
4922                                 /* skip to last fragment  and add this data there*/
4923                                 while(fd_head->next){
4924                                         fd_head=fd_head->next;
4925                                 }
4926                                 /* if dataoffset was not specified in the SMB command
4927                                    then we try to guess it as good as we can
4928                                 */
4929                                 if(dataoffset==0){
4930                                         dataoffset=offset+bc-datalen;
4931                                 }
4932                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
4933                                         frame, dcerpc_fragment_table,
4934                                         fd_head->offset+fd_head->len, 
4935                                         datalen, TRUE);
4936                                 /* we completed reassembly, abort searching for more 
4937                                    fragments*/
4938                                 if(fd_head){
4939                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
4940                                                 si->sip->extra_info);   
4941                                 }
4942                         }
4943                 }
4944         }
4945
4946         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
4947            read write */
4948         if(bc){
4949                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
4950                         /* dcerpc call */
4951                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
4952                             top_tree, offset, bc, datalen, fid);
4953                 } else {
4954                         /* ordinary file data, or we didn't see the request,
4955                            so we don't know whether this is a DCERPC call
4956                            or not */
4957                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
4958                 }
4959                 bc = 0;
4960         }
4961
4962         END_OF_SMB
4963
4964         /* call AndXCommand (if there are any) */
4965         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4966
4967         return offset;
4968 }
4969
4970 static int
4971 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4972 {
4973         guint32 ofs=0;
4974         guint8  wc, cmd=0xff;
4975         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4976         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4977         unsigned int fid=0;
4978
4979         WORD_COUNT;
4980
4981         /* next smb command */
4982         cmd = tvb_get_guint8(tvb, offset);
4983         if(cmd!=0xff){
4984                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4985         } else {
4986                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4987         }
4988         offset += 1;
4989
4990         /* reserved byte */
4991         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4992         offset += 1;
4993
4994         /* andxoffset */
4995         andxoffset = tvb_get_letohs(tvb, offset);
4996         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4997         offset += 2;
4998
4999         /* fid */
5000         fid = tvb_get_letohs(tvb, offset);
5001         add_fid(tvb, pinfo, tree, offset, 2, fid);
5002         offset += 2;
5003         if (!pinfo->fd->flags.visited) {
5004                 /* remember the FID for the processing of the response */
5005                 si->sip->extra_info=(void *)fid;
5006         }
5007
5008         /* offset */
5009         ofs = tvb_get_letohl(tvb, offset);
5010         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5011         offset += 4;
5012
5013         /* reserved */
5014         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5015         offset += 4;
5016
5017         /* mode */
5018         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
5019
5020         /* remaining */
5021         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5022         offset += 2;
5023
5024         /* XXX - data length high */
5025         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5026         offset += 2;
5027
5028         /* data len */
5029         datalen = tvb_get_letohs(tvb, offset);
5030         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5031         offset += 2;
5032
5033         /* data offset */
5034         dataoffset=tvb_get_letohs(tvb, offset);
5035         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5036         offset += 2;
5037
5038         /* FIXME: add byte/offset to COL_INFO */
5039
5040         if(wc==14){
5041                 /* high offset */
5042                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5043                 offset += 4;
5044         }
5045
5046         BYTE_COUNT;
5047
5048         /* is this part of DCERPC over SMB reassembly?*/
5049         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5050                 gpointer hash_value;
5051                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5052                         si->sip->extra_info);
5053                 if(hash_value){
5054                         fragment_data *fd_head;
5055                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5056
5057                         /* first fragment is always from a SMB Trans command and
5058                            offset 0 of the following read/write SMB commands start
5059                            BEYOND the first Trans SMB payload. Look for offset
5060                            in first read fragment */
5061                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5062                         if(fd_head){
5063                                 /* skip to last fragment  and add this data there*/
5064                                 while(fd_head->next){
5065                                         fd_head=fd_head->next;
5066                                 }
5067                                 /* if dataoffset was not specified in the SMB command
5068                                    then we try to guess it as good as we can
5069                                 */
5070                                 if(dataoffset==0){
5071                                         dataoffset=offset+bc-datalen;
5072                                 }
5073                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5074                                         frame, dcerpc_fragment_table,
5075                                         fd_head->offset+fd_head->len, 
5076                                         datalen, TRUE);
5077                                 /* we completed reassembly, abort searching for more 
5078                                    fragments*/
5079                                 if(fd_head){
5080                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5081                                                 si->sip->extra_info);   
5082                                 }
5083                         }
5084                 }
5085         }
5086
5087         /* file data */
5088         if (bc != 0) {
5089                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5090                         /* dcerpc call */
5091                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5092                             top_tree, offset, bc, datalen, fid);
5093                 } else {
5094                         /* ordinary file data */
5095                         offset = dissect_file_data(tvb, pinfo, tree, offset,
5096                             bc, datalen);
5097                 }
5098                 bc = 0;
5099         }
5100
5101         END_OF_SMB
5102
5103         /* call AndXCommand (if there are any) */
5104         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5105
5106         return offset;
5107 }
5108
5109 static int
5110 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5111 {
5112         guint8  wc, cmd=0xff;
5113         guint16 andxoffset=0, bc;
5114         smb_info_t *si;
5115
5116         WORD_COUNT;
5117
5118         /* next smb command */
5119         cmd = tvb_get_guint8(tvb, offset);
5120         if(cmd!=0xff){
5121                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5122         } else {
5123                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5124         }
5125         offset += 1;
5126  
5127         /* reserved byte */
5128         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5129         offset += 1;
5130
5131         /* andxoffset */
5132         andxoffset = tvb_get_letohs(tvb, offset);
5133         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5134         offset += 2;
5135
5136         /* If we have seen the request, then print which FID this refers to */
5137         si = (smb_info_t *)pinfo->private_data;
5138         /* first check if we have seen the request */
5139         if(si->sip != NULL && si->sip->frame_req>0){
5140                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5141         }
5142
5143         /* write count */
5144         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5145         offset += 2;
5146
5147         /* remaining */
5148         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5149         offset += 2;
5150
5151         /* 4 reserved bytes */
5152         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5153         offset += 4;
5154
5155         BYTE_COUNT;
5156
5157         END_OF_SMB
5158
5159         /* call AndXCommand (if there are any) */
5160         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5161
5162         return offset;
5163 }
5164
5165
5166 static const true_false_string tfs_setup_action_guest = {
5167         "Logged in as GUEST",
5168         "Not logged in as GUEST"
5169 };
5170 static int
5171 dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5172 {
5173         guint16 mask;
5174         proto_item *item = NULL;
5175         proto_tree *tree = NULL;
5176
5177         mask = tvb_get_letohs(tvb, offset);
5178
5179         if(parent_tree){
5180                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5181                         "Action: 0x%04x", mask);
5182                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5183         }
5184
5185         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5186                 tvb, offset, 2, mask);
5187
5188         offset += 2;
5189
5190         return offset;
5191 }
5192  
5193
5194 static int
5195 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5196 {
5197         guint8  wc, cmd=0xff;
5198         guint16 bc;
5199         guint16 andxoffset=0;
5200         int an_len;
5201         const char *an;
5202         int dn_len;
5203         const char *dn;
5204         guint16 pwlen=0;
5205         guint16 sbloblen=0;
5206         guint16 apwlen=0, upwlen=0;
5207
5208         WORD_COUNT;
5209
5210         /* next smb command */
5211         cmd = tvb_get_guint8(tvb, offset);
5212         if(cmd!=0xff){
5213                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5214         } else {
5215                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5216         }
5217         offset += 1;
5218
5219         /* reserved byte */
5220         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5221         offset += 1;
5222
5223         /* andxoffset */
5224         andxoffset = tvb_get_letohs(tvb, offset);
5225         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5226         offset += 2;
5227
5228         /* Maximum Buffer Size */
5229         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5230         offset += 2;
5231
5232         /* Maximum Multiplex Count */
5233         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5234         offset += 2;
5235
5236         /* VC Number */
5237         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5238         offset += 2;
5239
5240         /* session key */
5241         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5242         offset += 4;
5243
5244         switch (wc) {
5245         case 10:
5246                 /* password length, ASCII*/
5247                 pwlen = tvb_get_letohs(tvb, offset);
5248                 proto_tree_add_uint(tree, hf_smb_password_len,
5249                         tvb, offset, 2, pwlen);
5250                 offset += 2;
5251
5252                 /* 4 reserved bytes */
5253                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5254                 offset += 4;
5255
5256                 break;
5257
5258         case 12:
5259                 /* security blob length */
5260                 sbloblen = tvb_get_letohs(tvb, offset);
5261                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5262                 offset += 2;
5263
5264                 /* 4 reserved bytes */
5265                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5266                 offset += 4;
5267
5268                 /* capabilities */
5269                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5270                 offset += 4;
5271
5272                 break;
5273
5274         case 13:
5275                 /* password length, ANSI*/
5276                 apwlen = tvb_get_letohs(tvb, offset);
5277                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5278                         tvb, offset, 2, apwlen);
5279                 offset += 2;
5280
5281                 /* password length, Unicode*/
5282                 upwlen = tvb_get_letohs(tvb, offset);
5283                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5284                         tvb, offset, 2, upwlen);
5285                 offset += 2;
5286
5287                 /* 4 reserved bytes */
5288                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5289                 offset += 4;
5290
5291                 /* capabilities */
5292                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5293                 offset += 4;
5294
5295                 break;
5296         }
5297
5298         BYTE_COUNT;
5299
5300         if (wc==12) {
5301                 /* security blob */
5302                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5303                    data structure, at least in NT 5.0-and-later
5304                    server replies? */
5305                 if(sbloblen){
5306                         CHECK_BYTE_COUNT(sbloblen);
5307                         proto_tree_add_item(tree, hf_smb_security_blob,
5308                                 tvb, offset, sbloblen, TRUE);
5309                         COUNT_BYTES(sbloblen);
5310                 }
5311
5312                 /* OS */
5313                 an = get_unicode_or_ascii_string(tvb, &offset,
5314                         pinfo, &an_len, FALSE, FALSE, &bc);
5315                 if (an == NULL)
5316                         goto endofcommand;
5317                 proto_tree_add_string(tree, hf_smb_os, tvb,
5318                         offset, an_len, an);
5319                 COUNT_BYTES(an_len);
5320
5321                 /* LANMAN */
5322                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5323                  * padding/null string/whatever in front of this. W2K doesn't
5324                  * appear to. I suspect that's a bug that got fixed; I also
5325                  * suspect that, in practice, nobody ever looks at that field
5326                  * because the bug didn't appear to get fixed until NT 5.0....
5327                  */
5328                 an = get_unicode_or_ascii_string(tvb, &offset,
5329                         pinfo, &an_len, FALSE, FALSE, &bc);
5330                 if (an == NULL)
5331                         goto endofcommand;
5332                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5333                         offset, an_len, an);
5334                 COUNT_BYTES(an_len);
5335
5336                 /* Primary domain */
5337                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5338                  * byte in front of this, at least if all the strings are
5339                  * ASCII and the account name is empty. Another bug?
5340                  */
5341                 dn = get_unicode_or_ascii_string(tvb, &offset,
5342                         pinfo, &dn_len, FALSE, FALSE, &bc);
5343                 if (dn == NULL)
5344                         goto endofcommand;
5345                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5346                         offset, dn_len, dn);
5347                 COUNT_BYTES(dn_len);
5348         } else {
5349                 switch (wc) {
5350
5351                 case 10:
5352                         if(pwlen){
5353                                 /* password, ASCII */
5354                                 CHECK_BYTE_COUNT(pwlen);
5355                                 proto_tree_add_item(tree, hf_smb_password, 
5356                                         tvb, offset, pwlen, TRUE);
5357                                 COUNT_BYTES(pwlen);
5358                         }
5359
5360                         break;
5361
5362                 case 13:
5363                         if(apwlen){
5364                                 /* password, ANSI */
5365                                 CHECK_BYTE_COUNT(apwlen);
5366                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5367                                         tvb, offset, apwlen, TRUE);
5368                                 COUNT_BYTES(apwlen);
5369                         }
5370
5371                         if(upwlen){
5372                                 /* password, Unicode */
5373                                 CHECK_BYTE_COUNT(upwlen);
5374                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5375                                         tvb, offset, upwlen, TRUE);
5376                                 COUNT_BYTES(upwlen);
5377                         }
5378
5379                         break;
5380                 }
5381
5382                 /* Account Name */
5383                 an = get_unicode_or_ascii_string(tvb, &offset,
5384                         pinfo, &an_len, FALSE, FALSE, &bc);
5385                 if (an == NULL)
5386                         goto endofcommand;
5387                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5388                         an);
5389                 COUNT_BYTES(an_len);
5390
5391                 /* Primary domain */
5392                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5393                  * byte in front of this, at least if all the strings are
5394                  * ASCII and the account name is empty. Another bug?
5395                  */
5396                 dn = get_unicode_or_ascii_string(tvb, &offset,
5397                         pinfo, &dn_len, FALSE, FALSE, &bc);
5398                 if (dn == NULL)
5399                         goto endofcommand;
5400                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5401                         offset, dn_len, dn);
5402                 COUNT_BYTES(dn_len);
5403
5404                 if (check_col(pinfo->cinfo, COL_INFO)) {
5405                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5406
5407                         if (!dn[0] && !an[0])
5408                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5409                                                 "anonymous");
5410                         else
5411                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5412                                                 "%s\\%s", dn,an);
5413                 }
5414
5415                 /* OS */
5416                 an = get_unicode_or_ascii_string(tvb, &offset,
5417                         pinfo, &an_len, FALSE, FALSE, &bc);
5418                 if (an == NULL)
5419                         goto endofcommand;
5420                 proto_tree_add_string(tree, hf_smb_os, tvb,
5421                         offset, an_len, an);
5422                 COUNT_BYTES(an_len);
5423
5424                 /* LANMAN */
5425                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5426                  * padding/null string/whatever in front of this. W2K doesn't
5427                  * appear to. I suspect that's a bug that got fixed; I also
5428                  * suspect that, in practice, nobody ever looks at that field
5429                  * because the bug didn't appear to get fixed until NT 5.0....
5430                  */
5431                 an = get_unicode_or_ascii_string(tvb, &offset,
5432                         pinfo, &an_len, FALSE, FALSE, &bc);
5433                 if (an == NULL)
5434                         goto endofcommand;
5435                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5436                         offset, an_len, an);
5437                 COUNT_BYTES(an_len);
5438         }
5439
5440         END_OF_SMB
5441
5442         /* call AndXCommand (if there are any) */
5443         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5444
5445         return offset;
5446 }
5447
5448 static int
5449 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5450 {
5451         guint8  wc, cmd=0xff;
5452         guint16 andxoffset=0, bc;
5453         guint16 sbloblen=0;
5454         int an_len;
5455         const char *an;
5456
5457         WORD_COUNT;
5458
5459         /* next smb command */
5460         cmd = tvb_get_guint8(tvb, offset);
5461         if(cmd!=0xff){
5462                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5463         } else {
5464                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5465         }
5466         offset += 1;
5467
5468         /* reserved byte */
5469         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5470         offset += 1;
5471
5472         /* andxoffset */
5473         andxoffset = tvb_get_letohs(tvb, offset);
5474         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5475         offset += 2;
5476
5477         /* flags */
5478         offset = dissect_setup_action(tvb, pinfo, tree, offset);
5479
5480         if(wc==4){
5481                 /* security blob length */
5482                 sbloblen = tvb_get_letohs(tvb, offset);
5483                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5484                 offset += 2;
5485         }
5486
5487         BYTE_COUNT;
5488
5489         if(wc==4) {
5490                 /* security blob */
5491                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5492                    data structure, at least in NT 5.0-and-later
5493                    server replies? */
5494                 if(sbloblen){
5495                         CHECK_BYTE_COUNT(sbloblen);
5496                         proto_tree_add_item(tree, hf_smb_security_blob,
5497                                 tvb, offset, sbloblen, TRUE);
5498                         COUNT_BYTES(sbloblen);
5499                 }
5500         }
5501
5502         /* OS */
5503         an = get_unicode_or_ascii_string(tvb, &offset,
5504                 pinfo, &an_len, FALSE, FALSE, &bc);
5505         if (an == NULL)
5506                 goto endofcommand;
5507         proto_tree_add_string(tree, hf_smb_os, tvb,
5508                 offset, an_len, an);
5509         COUNT_BYTES(an_len);
5510
5511         /* LANMAN */
5512         an = get_unicode_or_ascii_string(tvb, &offset,
5513                 pinfo, &an_len, FALSE, FALSE, &bc);
5514         if (an == NULL)
5515                 goto endofcommand;
5516         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5517                 offset, an_len, an);
5518         COUNT_BYTES(an_len);
5519
5520         if(wc==3) {
5521                 /* Primary domain */
5522                 an = get_unicode_or_ascii_string(tvb, &offset,
5523                         pinfo, &an_len, FALSE, FALSE, &bc);
5524                 if (an == NULL)
5525                         goto endofcommand;
5526                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5527                         offset, an_len, an);
5528                 COUNT_BYTES(an_len);
5529         }
5530
5531         END_OF_SMB
5532
5533         /* call AndXCommand (if there are any) */
5534         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5535
5536         return offset;
5537 }
5538
5539  
5540 static int
5541 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5542 {
5543         guint8  wc, cmd=0xff;
5544         guint16 andxoffset=0;
5545         guint16 bc;
5546
5547         WORD_COUNT;
5548
5549         /* next smb command */
5550         cmd = tvb_get_guint8(tvb, offset);
5551         if(cmd!=0xff){
5552                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5553         } else {
5554                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5555         }
5556         offset += 1;
5557
5558         /* reserved byte */
5559         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5560         offset += 1;
5561
5562         /* andxoffset */
5563         andxoffset = tvb_get_letohs(tvb, offset);
5564         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5565         offset += 2;
5566
5567         BYTE_COUNT;
5568
5569         END_OF_SMB
5570
5571         /* call AndXCommand (if there are any) */
5572         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5573
5574         return offset;
5575 }
5576
5577  
5578 static const true_false_string tfs_connect_support_search = {
5579         "Exclusive search bits supported",
5580         "Exclusive search bits not supported"
5581 };
5582 static const true_false_string tfs_connect_support_in_dfs = {
5583         "Share is in Dfs",
5584         "Share isn't in Dfs"
5585 };
5586
5587 static int
5588 dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5589 {
5590         guint16 mask;
5591         proto_item *item = NULL;
5592         proto_tree *tree = NULL;
5593
5594         mask = tvb_get_letohs(tvb, offset);
5595
5596         if(parent_tree){
5597                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5598                         "Optional Support: 0x%04x", mask);
5599                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5600         }
5601
5602         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5603                 tvb, offset, 2, mask);
5604         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5605                 tvb, offset, 2, mask);
5606
5607         offset += 2;
5608
5609         return offset;
5610 }
5611
5612 static const true_false_string tfs_disconnect_tid = {
5613         "DISCONNECT TID",
5614         "Do NOT disconnect TID"
5615 };
5616
5617 static int
5618 dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5619 {
5620         guint16 mask;
5621         proto_item *item = NULL;
5622         proto_tree *tree = NULL;
5623
5624         mask = tvb_get_letohs(tvb, offset);
5625
5626         if(parent_tree){
5627                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5628                         "Flags: 0x%04x", mask);
5629                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5630         }
5631
5632         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5633                 tvb, offset, 2, mask);
5634
5635         offset += 2;
5636
5637         return offset;
5638 }
5639
5640 static int
5641 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5642 {
5643         guint8  wc, cmd=0xff;
5644         guint16 bc;
5645         guint16 andxoffset=0, pwlen=0;
5646         int an_len;
5647         const char *an;
5648
5649         WORD_COUNT;
5650
5651         /* next smb command */
5652         cmd = tvb_get_guint8(tvb, offset);
5653         if(cmd!=0xff){
5654                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5655         } else {
5656                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5657         }
5658         offset += 1;
5659
5660         /* reserved byte */
5661         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5662         offset += 1;
5663
5664         /* andxoffset */
5665         andxoffset = tvb_get_letohs(tvb, offset);
5666         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5667         offset += 2;
5668
5669         /* flags */
5670         offset = dissect_connect_flags(tvb, pinfo, tree, offset);
5671
5672         /* password length*/
5673         pwlen = tvb_get_letohs(tvb, offset);
5674         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5675         offset += 2;
5676
5677         BYTE_COUNT;
5678
5679         /* password */
5680         CHECK_BYTE_COUNT(pwlen);
5681         proto_tree_add_item(tree, hf_smb_password, 
5682                 tvb, offset, pwlen, TRUE);
5683         COUNT_BYTES(pwlen);
5684
5685         /* Path */
5686         an = get_unicode_or_ascii_string(tvb, &offset,
5687                 pinfo, &an_len, FALSE, FALSE, &bc);
5688         if (an == NULL)
5689                 goto endofcommand;
5690         proto_tree_add_string(tree, hf_smb_path, tvb,
5691                 offset, an_len, an);
5692         COUNT_BYTES(an_len);
5693
5694         if (check_col(pinfo->cinfo, COL_INFO)) {
5695                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
5696         }
5697
5698         /*
5699          * NOTE: the Service string is always ASCII, even if the
5700          * "strings are Unicode" bit is set in the flags2 field
5701          * of the SMB.
5702          */
5703
5704         /* Service */
5705         /* XXX - what if this runs past bc? */
5706         an_len = tvb_strsize(tvb, offset);
5707         CHECK_BYTE_COUNT(an_len);
5708         an = tvb_get_ptr(tvb, offset, an_len);
5709         proto_tree_add_string(tree, hf_smb_service, tvb,
5710                 offset, an_len, an);
5711         COUNT_BYTES(an_len);
5712
5713         END_OF_SMB
5714
5715         /* call AndXCommand (if there are any) */
5716         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5717
5718         return offset;
5719 }
5720
5721
5722 static int
5723 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5724 {
5725         guint8  wc, wleft, cmd=0xff;
5726         guint16 andxoffset=0;
5727         guint16 bc;
5728         int an_len;
5729         const char *an;
5730
5731         WORD_COUNT;
5732
5733         wleft = wc;     /* this is at least 1 */
5734
5735         /* next smb command */
5736         cmd = tvb_get_guint8(tvb, offset);
5737         if(cmd!=0xff){
5738                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5739         } else {
5740                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5741         }
5742         offset += 1;
5743
5744         /* reserved byte */
5745         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5746         offset += 1;
5747
5748         wleft--;
5749         if (wleft == 0)
5750                 goto bytecount;
5751
5752         /* andxoffset */
5753         andxoffset = tvb_get_letohs(tvb, offset);
5754         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5755         offset += 2;
5756         wleft--;
5757         if (wleft == 0)
5758                 goto bytecount;
5759
5760         /* flags */
5761         offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
5762         wleft--;
5763
5764         /* XXX - I've seen captures where this is 7, but I have no
5765            idea how to dissect it.  I'm guessing the third word
5766            contains connect support bits, which looks plausible
5767            from the values I've seen. */
5768
5769         while (wleft != 0) {
5770                 proto_tree_add_text(tree, tvb, offset, 2,
5771                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
5772                 offset += 2;
5773                 wleft--;
5774         }
5775
5776         BYTE_COUNT;
5777
5778         /*
5779          * NOTE: even though the SNIA CIFS spec doesn't say there's
5780          * a "Service" string if there's a word count of 2, the
5781          * document at
5782          *
5783          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
5784          *
5785          * (it's in an ugly format - text intended to be sent to a
5786          * printer, with backspaces and overstrikes used for boldfacing
5787          * and underlining; UNIX "col -b" can be used to strip the
5788          * overstrikes out) says there's a "Service" string there, and
5789          * some network traffic has it.
5790          */
5791
5792         /*
5793          * NOTE: the Service string is always ASCII, even if the
5794          * "strings are Unicode" bit is set in the flags2 field
5795          * of the SMB.
5796          */
5797
5798         /* Service */
5799         /* XXX - what if this runs past bc? */
5800         an_len = tvb_strsize(tvb, offset);
5801         CHECK_BYTE_COUNT(an_len);
5802         an = tvb_get_ptr(tvb, offset, an_len);
5803         proto_tree_add_string(tree, hf_smb_service, tvb,
5804                 offset, an_len, an);
5805         COUNT_BYTES(an_len);
5806
5807         /* Now when we know the service type, store it so that we know it for later commands down
5808            this tree */
5809         if(!pinfo->fd->flags.visited){
5810                 smb_info_t *si = (smb_info_t *)pinfo->private_data;
5811                 /* Remove any previous entry for this TID */
5812                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5813                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5814                 }
5815                 if(strcmp(an,"IPC") == 0){
5816                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5817                 } else {
5818                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
5819                 }
5820         }
5821
5822
5823         if(wc==3){
5824                 if (bc != 0) {
5825                         /*
5826                          * Sometimes this isn't present.
5827                          */
5828
5829                         /* Native FS */
5830                         an = get_unicode_or_ascii_string(tvb, &offset,
5831                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
5832                         if (an == NULL)
5833                                 goto endofcommand;
5834                         proto_tree_add_string(tree, hf_smb_fs, tvb,
5835                                 offset, an_len, an);
5836                         COUNT_BYTES(an_len);
5837                 }
5838         }
5839
5840         END_OF_SMB
5841
5842         /* call AndXCommand (if there are any) */
5843         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5844
5845         return offset;
5846 }
5847
5848
5849
5850 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5851    NT Transaction command  begins here
5852    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
5853 #define NT_TRANS_CREATE         1
5854 #define NT_TRANS_IOCTL          2
5855 #define NT_TRANS_SSD            3
5856 #define NT_TRANS_NOTIFY         4
5857 #define NT_TRANS_RENAME         5
5858 #define NT_TRANS_QSD            6
5859 #define NT_TRANS_GET_USER_QUOTA 7
5860 #define NT_TRANS_SET_USER_QUOTA 8
5861 static const value_string nt_cmd_vals[] = {
5862         {NT_TRANS_CREATE,               "NT CREATE"},
5863         {NT_TRANS_IOCTL,                "NT IOCTL"},
5864         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
5865         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
5866         {NT_TRANS_RENAME,               "NT RENAME"},
5867         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
5868         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
5869         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
5870         {0, NULL}
5871 };
5872
5873 static const value_string nt_ioctl_isfsctl_vals[] = {
5874         {0,     "Device IOCTL"},
5875         {1,     "FS control : FSCTL"},
5876         {0, NULL}
5877 };
5878
5879 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
5880 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
5881         "Apply the command to share root handle (MUST BE Dfs)",
5882         "Apply to this share",
5883 };
5884
5885 static const value_string nt_notify_action_vals[] = {
5886         {1,     "ADDED (object was added"},
5887         {2,     "REMOVED (object was removed)"},
5888         {3,     "MODIFIED (object was modified)"},
5889         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
5890         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
5891         {6,     "ADDED_STREAM (a stream was added)"},
5892         {7,     "REMOVED_STREAM (a stream was removed)"},
5893         {8,     "MODIFIED_STREAM (a stream was modified)"},
5894         {0, NULL}
5895 };
5896
5897 static const value_string watch_tree_vals[] = {
5898         {0,     "Current directory only"},
5899         {1,     "Subdirectories also"},
5900         {0, NULL}
5901 };
5902
5903 #define NT_NOTIFY_STREAM_WRITE  0x00000800
5904 #define NT_NOTIFY_STREAM_SIZE   0x00000400
5905 #define NT_NOTIFY_STREAM_NAME   0x00000200
5906 #define NT_NOTIFY_SECURITY      0x00000100
5907 #define NT_NOTIFY_EA            0x00000080
5908 #define NT_NOTIFY_CREATION      0x00000040
5909 #define NT_NOTIFY_LAST_ACCESS   0x00000020
5910 #define NT_NOTIFY_LAST_WRITE    0x00000010
5911 #define NT_NOTIFY_SIZE          0x00000008
5912 #define NT_NOTIFY_ATTRIBUTES    0x00000004
5913 #define NT_NOTIFY_DIR_NAME      0x00000002
5914 #define NT_NOTIFY_FILE_NAME     0x00000001
5915 static const true_false_string tfs_nt_notify_stream_write = {
5916         "Notify on changes to STREAM WRITE",
5917         "Do NOT notify on changes to stream write",
5918 };
5919 static const true_false_string tfs_nt_notify_stream_size = {
5920         "Notify on changes to STREAM SIZE",
5921         "Do NOT notify on changes to stream size",
5922 };
5923 static const true_false_string tfs_nt_notify_stream_name = {
5924         "Notify on changes to STREAM NAME",
5925         "Do NOT notify on changes to stream name",
5926 };
5927 static const true_false_string tfs_nt_notify_security = {
5928         "Notify on changes to SECURITY",
5929         "Do NOT notify on changes to security",
5930 };
5931 static const true_false_string tfs_nt_notify_ea = {
5932         "Notify on changes to EA",
5933         "Do NOT notify on changes to EA",
5934 };
5935 static const true_false_string tfs_nt_notify_creation = {
5936         "Notify on changes to CREATION TIME",
5937         "Do NOT notify on changes to creation time",
5938 };
5939 static const true_false_string tfs_nt_notify_last_access = {
5940         "Notify on changes to LAST ACCESS TIME",
5941         "Do NOT notify on changes to last access time",
5942 };
5943 static const true_false_string tfs_nt_notify_last_write = {
5944         "Notify on changes to LAST WRITE TIME",
5945         "Do NOT notify on changes to last write time",
5946 };
5947 static const true_false_string tfs_nt_notify_size = {
5948         "Notify on changes to SIZE",
5949         "Do NOT notify on changes to size",
5950 };
5951 static const true_false_string tfs_nt_notify_attributes = {
5952         "Notify on changes to ATTRIBUTES",
5953         "Do NOT notify on changes to attributes",
5954 };
5955 static const true_false_string tfs_nt_notify_dir_name = {
5956         "Notify on changes to DIR NAME",
5957         "Do NOT notify on changes to dir name",
5958 };
5959 static const true_false_string tfs_nt_notify_file_name = {
5960         "Notify on changes to FILE NAME",
5961         "Do NOT notify on changes to file name",
5962 };
5963
5964 static const value_string create_disposition_vals[] = {
5965         {0,     "Supersede (supersede existing file (if it exists))"},
5966         {1,     "Open (if file exists open it, else fail)"},
5967         {2,     "Create (if file exists fail, else create it)"},
5968         {3,     "Open If (if file exists open it, else create it)"},
5969         {4,     "Overwrite (if file exists overwrite, else fail)"},
5970         {5,     "Overwrite If (if file exists overwrite, else create it)"},
5971         {0, NULL}
5972 };
5973
5974 static const value_string impersonation_level_vals[] = {
5975         {0,     "Anonymous"},
5976         {1,     "Identification"},
5977         {2,     "Impersonation"},
5978         {3,     "Delegation"},
5979         {0, NULL}
5980 };
5981
5982 static const true_false_string tfs_nt_security_flags_context_tracking = {
5983         "Security tracking mode is DYNAMIC",
5984         "Security tracking mode is STATIC",
5985 };
5986
5987 static const true_false_string tfs_nt_security_flags_effective_only = {
5988         "ONLY ENABLED aspects of the client's security context are available",
5989         "ALL aspects of the client's security context are available",
5990 };
5991
5992 static const true_false_string tfs_nt_create_bits_oplock = {
5993         "Requesting OPLOCK",
5994         "Does NOT request oplock"
5995 };
5996
5997 static const true_false_string tfs_nt_create_bits_boplock = {
5998         "Requesting BATCH OPLOCK",
5999         "Does NOT request batch oplock"
6000 };
6001
6002 /*
6003  * XXX - must be a directory, and can be a file, or can be a directory,
6004  * and must be a file?
6005  */
6006 static const true_false_string tfs_nt_create_bits_dir = {
6007         "Target of open MUST be a DIRECTORY",
6008         "Target of open can be a file"
6009 };
6010
6011 static const true_false_string tfs_nt_access_mask_generic_read = {
6012         "GENERIC READ is set",
6013         "Generic read is NOT set"
6014 };
6015 static const true_false_string tfs_nt_access_mask_generic_write = {
6016         "GENERIC WRITE is set",
6017         "Generic write is NOT set"
6018 };
6019 static const true_false_string tfs_nt_access_mask_generic_execute = {
6020         "GENERIC EXECUTE is set",
6021         "Generic execute is NOT set"
6022 };
6023 static const true_false_string tfs_nt_access_mask_generic_all = {
6024         "GENERIC ALL is set",
6025         "Generic all is NOT set"
6026 };
6027 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6028         "MAXIMUM ALLOWED is set",
6029         "Maximum allowed is NOT set"
6030 };
6031 static const true_false_string tfs_nt_access_mask_system_security = {
6032         "SYSTEM SECURITY is set",
6033         "System security is NOT set"
6034 };
6035 static const true_false_string tfs_nt_access_mask_synchronize = {
6036         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6037         "Can NOT wait on handle to synchronize on completion of I/O"
6038 };
6039 static const true_false_string tfs_nt_access_mask_write_owner = {
6040         "Can WRITE OWNER (take ownership)",
6041         "Can NOT write owner (take ownership)"
6042 };
6043 static const true_false_string tfs_nt_access_mask_write_dac = {
6044         "OWNER may WRITE the DAC",
6045         "Owner may NOT write to the DAC"
6046 };
6047 static const true_false_string tfs_nt_access_mask_read_control = {
6048         "READ ACCESS to owner, group and ACL of the SID",
6049         "Read access is NOT granted to owner, group and ACL of the SID"
6050 };
6051 static const true_false_string tfs_nt_access_mask_delete = {
6052         "DELETE access",
6053         "NO delete access"
6054 };
6055 static const true_false_string tfs_nt_access_mask_write_attributes = {
6056         "WRITE ATTRIBUTES access",
6057         "NO write attributes access"
6058 };
6059 static const true_false_string tfs_nt_access_mask_read_attributes = {
6060         "READ ATTRIBUTES access",
6061         "NO read attributes access"
6062 };
6063 static const true_false_string tfs_nt_access_mask_delete_child = {
6064         "DELETE CHILD access",
6065         "NO delete child access"
6066 };
6067 static const true_false_string tfs_nt_access_mask_execute = {
6068         "EXECUTE access",
6069         "NO execute access"
6070 };
6071 static const true_false_string tfs_nt_access_mask_write_ea = {
6072         "WRITE EXTENDED ATTRIBUTES access",
6073         "NO write extended attributes access"
6074 };
6075 static const true_false_string tfs_nt_access_mask_read_ea = {
6076         "READ EXTENDED ATTRIBUTES access",
6077         "NO read extended attributes access"
6078 };
6079 static const true_false_string tfs_nt_access_mask_append = {
6080         "APPEND access",
6081         "NO append access"
6082 };
6083 static const true_false_string tfs_nt_access_mask_write = {
6084         "WRITE access",
6085         "NO write access"
6086 };
6087 static const true_false_string tfs_nt_access_mask_read = {
6088         "READ access",
6089         "NO read access"
6090 };
6091
6092 static const true_false_string tfs_nt_share_access_delete = {
6093         "Object can be shared for DELETE",
6094         "Object can NOT be shared for delete"
6095 };
6096 static const true_false_string tfs_nt_share_access_write = {
6097         "Object can be shared for WRITE",
6098         "Object can NOT be shared for write"
6099 };
6100 static const true_false_string tfs_nt_share_access_read = {
6101         "Object can be shared for READ",
6102         "Object can NOT be shared for delete"
6103 };
6104
6105 static const value_string oplock_level_vals[] = {
6106         {0,     "No oplock granted"},
6107         {1,     "Exclusive oplock granted"},
6108         {2,     "Batch oplock granted"},
6109         {3,     "Level II oplock granted"},
6110         {0, NULL}
6111 };
6112
6113 static const value_string device_type_vals[] = {
6114         {0x00000001,    "Beep"},
6115         {0x00000002,    "CDROM"},
6116         {0x00000003,    "CDROM Filesystem"},
6117         {0x00000004,    "Controller"},
6118         {0x00000005,    "Datalink"},
6119         {0x00000006,    "Dfs"},
6120         {0x00000007,    "Disk"},
6121         {0x00000008,    "Disk Filesystem"},
6122         {0x00000009,    "Filesystem"},
6123         {0x0000000a,    "Inport Port"},
6124         {0x0000000b,    "Keyboard"},
6125         {0x0000000c,    "Mailslot"},
6126         {0x0000000d,    "MIDI-In"},
6127         {0x0000000e,    "MIDI-Out"},
6128         {0x0000000f,    "Mouse"},
6129         {0x00000010,    "Multi UNC Provider"},
6130         {0x00000011,    "Named Pipe"},
6131         {0x00000012,    "Network"},
6132         {0x00000013,    "Network Browser"},
6133         {0x00000014,    "Network Filesystem"},
6134         {0x00000015,    "NULL"},
6135         {0x00000016,    "Parallel Port"},
6136         {0x00000017,    "Physical card"},
6137         {0x00000018,    "Printer"},
6138         {0x00000019,    "Scanner"},
6139         {0x0000001a,    "Serial Mouse port"},
6140         {0x0000001b,    "Serial port"},
6141         {0x0000001c,    "Screen"},
6142         {0x0000001d,    "Sound"},
6143         {0x0000001e,    "Streams"},
6144         {0x0000001f,    "Tape"},
6145         {0x00000020,    "Tape Filesystem"},
6146         {0x00000021,    "Transport"},
6147         {0x00000022,    "Unknown"},
6148         {0x00000023,    "Video"},
6149         {0x00000024,    "Virtual Disk"},
6150         {0x00000025,    "WAVE-In"},
6151         {0x00000026,    "WAVE-Out"},
6152         {0x00000027,    "8042 Port"},
6153         {0x00000028,    "Network Redirector"},
6154         {0x00000029,    "Battery"},
6155         {0x0000002a,    "Bus Extender"},
6156         {0x0000002b,    "Modem"},
6157         {0x0000002c,    "VDM"},
6158         {0,     NULL}
6159 };
6160
6161 static const value_string is_directory_vals[] = {
6162         {0,     "This is NOT a directory"},
6163         {1,     "This is a DIRECTORY"},
6164         {0, NULL}
6165 };
6166
6167 typedef struct _nt_trans_data {
6168         int subcmd;
6169         guint32 sd_len;
6170         guint32 ea_len;
6171 } nt_trans_data;
6172
6173
6174
6175 static int
6176 dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6177 {
6178         guint8 mask;
6179         proto_item *item = NULL;
6180         proto_tree *tree = NULL;
6181
6182         mask = tvb_get_guint8(tvb, offset);
6183
6184         if(parent_tree){
6185                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6186                         "Security Flags: 0x%02x", mask);
6187                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6188         }
6189
6190         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6191                 tvb, offset, 1, mask);
6192         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6193                 tvb, offset, 1, mask);
6194
6195         offset += 1;
6196
6197         return offset;
6198 }
6199
6200 static int
6201 dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6202 {
6203         guint32 mask;
6204         proto_item *item = NULL;
6205         proto_tree *tree = NULL;
6206
6207         mask = tvb_get_letohl(tvb, offset);
6208
6209         if(parent_tree){
6210                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6211                         "Share Access: 0x%08x", mask);
6212                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6213         }
6214
6215         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6216                 tvb, offset, 4, mask);
6217         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6218                 tvb, offset, 4, mask);
6219         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6220                 tvb, offset, 4, mask);
6221
6222         offset += 4;
6223
6224         return offset;
6225 }
6226
6227
6228 static int
6229 dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6230 {
6231         guint32 mask;
6232         proto_item *item = NULL;
6233         proto_tree *tree = NULL;
6234
6235         mask = tvb_get_letohl(tvb, offset);
6236
6237         if(parent_tree){
6238                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6239                         "Access Mask: 0x%08x", mask);
6240                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6241         }
6242
6243         /*
6244          * Some of these bits come from 
6245          *
6246          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6247          *
6248          * and others come from the section on ZwOpenFile in "Windows(R)
6249          * NT(R)/2000 Native API Reference".
6250          */
6251         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6252                 tvb, offset, 4, mask);
6253         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6254                 tvb, offset, 4, mask);
6255         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6256                 tvb, offset, 4, mask);
6257         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6258                 tvb, offset, 4, mask);
6259         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6260                 tvb, offset, 4, mask);
6261         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6262                 tvb, offset, 4, mask);
6263         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6264                 tvb, offset, 4, mask);
6265         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6266                 tvb, offset, 4, mask);
6267         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6268                 tvb, offset, 4, mask);
6269         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6270                 tvb, offset, 4, mask);
6271         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6272                 tvb, offset, 4, mask);
6273         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6274                 tvb, offset, 4, mask);
6275         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6276                 tvb, offset, 4, mask);
6277         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6278                 tvb, offset, 4, mask);
6279         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6280                 tvb, offset, 4, mask);
6281         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6282                 tvb, offset, 4, mask);
6283         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6284                 tvb, offset, 4, mask);
6285         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6286                 tvb, offset, 4, mask);
6287         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6288                 tvb, offset, 4, mask);
6289         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6290                 tvb, offset, 4, mask);
6291
6292         offset += 4;
6293
6294         return offset;
6295 }
6296
6297 static int
6298 dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6299 {
6300         guint32 mask;
6301         proto_item *item = NULL;
6302         proto_tree *tree = NULL;
6303
6304         mask = tvb_get_letohl(tvb, offset);
6305
6306         if(parent_tree){
6307                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6308                         "Create Flags: 0x%08x", mask);
6309                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6310         }
6311
6312         /*
6313          * XXX - it's 0x00000016 in at least one capture, but
6314          * Network Monitor doesn't say what the 0x00000010 bit is.
6315          * Does the Win32 API documentation, or NT Native API book,
6316          * suggest anything?
6317          */
6318         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6319                 tvb, offset, 4, mask);
6320         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6321                 tvb, offset, 4, mask);
6322         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6323                 tvb, offset, 4, mask);
6324
6325         offset += 4;
6326
6327         return offset;
6328 }
6329
6330 /*
6331  * XXX - there are some more flags in the description of "ZwOpenFile()"
6332  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6333  * the wire as well?  (The spec at
6334  *
6335  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6336  *
6337  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6338  * via the SMB protocol.  The NT redirector should convert this option
6339  * to FILE_WRITE_THROUGH."
6340  *
6341  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6342  * values one would infer from their position in the list of flags for
6343  * "ZwOpenFile()".  Most of the others probably have those values
6344  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6345  * which might go over the wire (for the benefit of backup/restore software).
6346  */
6347 static const true_false_string tfs_nt_create_options_directory = {
6348         "File being created/opened must be a directory",
6349         "File being created/opened must not be a directory"
6350 };
6351 static const true_false_string tfs_nt_create_options_write_through = {
6352         "Writes should flush buffered data before completing",
6353         "Writes need not flush buffered data before completing"
6354 };
6355 static const true_false_string tfs_nt_create_options_sequential_only = {
6356         "The file will only be accessed sequentially",
6357         "The file might not only be accessed sequentially"
6358 };
6359 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6360         "All operations SYNCHRONOUS, waits subject to termination from alert",
6361         "Operations NOT necessarily synchronous"
6362 };
6363 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6364         "All operations SYNCHRONOUS, waits not subject to alert",
6365         "Operations NOT necessarily synchronous"
6366 };
6367 static const true_false_string tfs_nt_create_options_non_directory = {
6368         "File being created/opened must not be a directory",
6369         "File being created/opened must be a directory"
6370 };
6371 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6372         "The client does not understand extended attributes",
6373         "The client understands extended attributes"
6374 };
6375 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6376         "The client understands only 8.3 file names",
6377         "The client understands long file names"
6378 };
6379 static const true_false_string tfs_nt_create_options_random_access = {
6380         "The file will be accessed randomly",
6381         "The file will not be accessed randomly"
6382 };
6383 static const true_false_string tfs_nt_create_options_delete_on_close = {
6384         "The file should be deleted when it is closed",
6385         "The file should not be deleted when it is closed"
6386 };
6387
6388 static int
6389 dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6390 {
6391         guint32 mask;
6392         proto_item *item = NULL;
6393         proto_tree *tree = NULL;
6394
6395         mask = tvb_get_letohl(tvb, offset);
6396
6397         if(parent_tree){
6398                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6399                         "Create Options: 0x%08x", mask);
6400                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6401         }
6402
6403         /*
6404          * From
6405          *
6406          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6407          */
6408         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6409                 tvb, offset, 4, mask);
6410         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6411                 tvb, offset, 4, mask);
6412         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6413                 tvb, offset, 4, mask);
6414         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6415                 tvb, offset, 4, mask);
6416         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6417                 tvb, offset, 4, mask);
6418         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6419                 tvb, offset, 4, mask);
6420         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6421                 tvb, offset, 4, mask);
6422         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6423                 tvb, offset, 4, mask);
6424         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6425                 tvb, offset, 4, mask);
6426         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6427                 tvb, offset, 4, mask);
6428
6429         offset += 4;
6430
6431         return offset;
6432 }
6433  
6434 static int
6435 dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6436 {
6437         guint32 mask;
6438         proto_item *item = NULL;
6439         proto_tree *tree = NULL;
6440
6441         mask = tvb_get_letohl(tvb, offset);
6442
6443         if(parent_tree){
6444                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6445                         "Completion Filter: 0x%08x", mask);
6446                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6447         }
6448  
6449         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6450                 tvb, offset, 4, mask);
6451         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6452                 tvb, offset, 4, mask);
6453         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6454                 tvb, offset, 4, mask);
6455         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6456                 tvb, offset, 4, mask);
6457         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6458                 tvb, offset, 4, mask);
6459         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6460                 tvb, offset, 4, mask);
6461         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6462                 tvb, offset, 4, mask);
6463         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6464                 tvb, offset, 4, mask);
6465         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6466                 tvb, offset, 4, mask);
6467         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6468                 tvb, offset, 4, mask);
6469         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6470                 tvb, offset, 4, mask);
6471         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6472                 tvb, offset, 4, mask);
6473
6474         offset += 4;
6475         return offset;
6476 }
6477  
6478 static int
6479 dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6480 {
6481         guint8 mask;
6482         proto_item *item = NULL;
6483         proto_tree *tree = NULL;
6484
6485         mask = tvb_get_guint8(tvb, offset);
6486
6487         if(parent_tree){
6488                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6489                         "Completion Filter: 0x%02x", mask);
6490                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6491         }
6492
6493         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6494                 tvb, offset, 1, mask);
6495
6496         offset += 1;
6497         return offset;
6498 }
6499
6500 /*
6501  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6502  * Native API Reference".
6503  */
6504 static const true_false_string tfs_nt_qsd_owner = {
6505         "Requesting OWNER security information",
6506         "NOT requesting owner security information",
6507 };
6508
6509 static const true_false_string tfs_nt_qsd_group = {
6510         "Requesting GROUP security information",
6511         "NOT requesting group security information",
6512 };
6513
6514 static const true_false_string tfs_nt_qsd_dacl = {
6515         "Requesting DACL security information",
6516         "NOT requesting DACL security information",
6517 };
6518
6519 static const true_false_string tfs_nt_qsd_sacl = {
6520         "Requesting SACL security information",
6521         "NOT requesting SACL security information",
6522 };
6523
6524 #define NT_QSD_OWNER    0x00000001
6525 #define NT_QSD_GROUP    0x00000002
6526 #define NT_QSD_DACL     0x00000004
6527 #define NT_QSD_SACL     0x00000008
6528
6529 static int
6530 dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6531 {
6532         guint32 mask;
6533         proto_item *item = NULL;
6534         proto_tree *tree = NULL;
6535
6536         mask = tvb_get_letohl(tvb, offset);
6537
6538         if(parent_tree){
6539                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6540                         "Security Information: 0x%08x", mask);
6541                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6542         }
6543
6544         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6545                 tvb, offset, 4, mask);
6546         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6547                 tvb, offset, 4, mask);
6548         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6549                 tvb, offset, 4, mask);
6550         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6551                 tvb, offset, 4, mask);
6552
6553         offset += 4;
6554
6555         return offset;
6556 }
6557
6558 static void
6559 free_g_string(void *arg)
6560 {
6561         GString *gstring = arg;
6562
6563         g_string_free(arg, TRUE);
6564 }
6565
6566 int
6567 dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6568 {
6569         proto_item *item = NULL;
6570         proto_tree *tree = NULL;
6571         int old_offset = offset, sa_offset = offset;
6572         guint *s_auths = NULL;
6573         guint rid;
6574         guint8 revision;
6575         guint8 num_auth;
6576         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6577         int i;
6578         GString *gstr;
6579
6580         if(parent_tree){
6581                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6582                                            "NT %s SID", name);
6583                 tree = proto_item_add_subtree(item, ett_smb_sid);
6584         }
6585
6586         /* revision of sid */
6587         revision = tvb_get_guint8(tvb, offset);
6588         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6589         offset += 1;
6590
6591         switch(revision){
6592         case 1:  
6593         case 2:  /* Not sure what the different revision numbers mean */
6594           /* number of authorities*/
6595           num_auth = tvb_get_guint8(tvb, offset);
6596           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6597           offset += 1;
6598
6599           /* XXX perhaps we should have these thing searchable?
6600              a new FT_xxx thingie? SMB is quite common!*/
6601           /* identifier authorities */
6602
6603           /* FIXME: We should dynamically allocate the authorities array,
6604              which is only one thing. Then we don't have to allocate two
6605              strings below etc ...
6606           */
6607
6608           for(i=0;i<6;i++){
6609             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
6610
6611             offset++;
6612           }
6613
6614           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
6615
6616           sa_offset = offset;
6617
6618           CLEANUP_PUSH(free, s_auths);
6619
6620           s_auths = g_malloc(sizeof(guint) * num_auth);
6621
6622           /* sub authorities, leave RID to last */
6623           /* FIXME: If we take an exception now, we lose the whole 
6624              sub-authorities string thang */
6625           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
6626             /* XXX should not be letohl but native byteorder according to
6627                samba header files. considering that all non-x86 NT ports
6628                are dead we can (?) assume that non le byte encodings
6629                will be "uncommon"?*/
6630               s_auths[i] = tvb_get_letohl(tvb, offset);
6631               offset+=4;
6632           }
6633
6634           CLEANUP_CALL_AND_POP;
6635
6636           gstr = g_string_new("");
6637           
6638           for (i = 0; i < (num_auth>4?(num_auth - 1):num_auth); i++)
6639               g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"), s_auths[i]);
6640
6641           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
6642
6643           if (num_auth > 4) {
6644             rid = tvb_get_letohl(tvb, offset);
6645             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
6646             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
6647             offset+=4;
6648           }
6649           else {
6650             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
6651           }
6652
6653         }
6654
6655         proto_item_set_len(item, offset-old_offset);
6656         return offset;
6657 }
6658
6659
6660 static const value_string ace_type_vals[] = {
6661   { 0, "Access Allowed"},
6662   { 1, "Access Denied"},
6663   { 2, "System Audit"},
6664   { 3, "System Alarm"},
6665   { 0, NULL}
6666 };
6667 static const true_false_string tfs_ace_flags_object_inherit = {
6668   "Subordinate files will inherit this ACE",
6669   "Subordinate files will not inherit this ACE"
6670 };
6671 static const true_false_string tfs_ace_flags_container_inherit = {
6672   "Subordinate containers will inherit this ACE",
6673   "Subordinate containers will not inherit this ACE"
6674 };
6675 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
6676   "Subordinate object will not propagate the inherited ACE further",
6677   "Subordinate object will propagate the inherited ACE further"
6678 };
6679 static const true_false_string tfs_ace_flags_inherit_only = {
6680   "This ACE does not apply to the current object",
6681   "This ACE applies to the current object"
6682 };
6683 static const true_false_string tfs_ace_flags_inherited_ace = {
6684   "This ACE was inherited from its parent object",
6685   "This ACE was not inherited from its parent object"
6686 };
6687 static const true_false_string tfs_ace_flags_successful_access = {
6688   "Successful accesses will be audited",
6689   "Successful accesses will not be audited"
6690 };
6691 static const true_false_string tfs_ace_flags_failed_access = {
6692   "Failed accesses will be audited",
6693   "Failed accesses will not be audited"
6694 };
6695
6696 #define APPEND_ACE_TEXT(flag, item, string) \
6697         if(flag){                                                       \
6698                 if(item)                                                \
6699                         proto_item_append_text(item, string, sep);      \
6700                 sep = ", ";                                             \
6701         }
6702
6703 static int
6704 dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6705 {
6706         proto_item *item = NULL;
6707         proto_tree *tree = NULL;
6708         guint8 mask;
6709         char *sep = " ";
6710
6711         mask = tvb_get_guint8(tvb, offset);
6712         if(parent_tree){
6713                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6714                                            "NT ACE Flags: 0x%02x", mask);
6715                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
6716         }
6717
6718         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
6719                        tvb, offset, 1, mask);
6720         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
6721
6722         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
6723                        tvb, offset, 1, mask);
6724         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
6725
6726         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
6727                        tvb, offset, 1, mask);
6728         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
6729
6730         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
6731                        tvb, offset, 1, mask);
6732         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
6733
6734         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
6735                        tvb, offset, 1, mask);
6736         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
6737
6738         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
6739                        tvb, offset, 1, mask);
6740         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
6741
6742         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
6743                        tvb, offset, 1, mask);
6744         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
6745
6746
6747         offset += 1;
6748         return offset;
6749 }
6750
6751 static int
6752 dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6753 {
6754         proto_item *item = NULL;
6755         proto_tree *tree = NULL;
6756         int old_offset = offset;
6757         
6758         if(parent_tree){
6759                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6760                                            "NT ACE: ");
6761                 tree = proto_item_add_subtree(item, ett_smb_ace);
6762         }
6763
6764         /* type */
6765         if(item){
6766           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
6767         }
6768         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
6769         offset += 1;
6770
6771         /* flags */
6772         offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
6773
6774         /* size */
6775         proto_tree_add_item(tree, hf_smb_ace_size, tvb, offset, 2, TRUE);
6776         offset += 2;
6777
6778         /* access mask */
6779         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6780
6781         /* SID */
6782         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
6783
6784         proto_item_set_len(item, offset-old_offset);
6785         return offset;
6786 }
6787
6788 static int
6789 dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6790 {
6791         proto_item *item = NULL;
6792         proto_tree *tree = NULL;
6793         int old_offset = offset;
6794         guint16 revision, size;
6795         guint32 num_aces;
6796
6797         if(parent_tree){
6798                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6799                                            "NT %s ACL", name);
6800                 tree = proto_item_add_subtree(item, ett_smb_acl);
6801         }
6802
6803         /* revision */
6804         revision = tvb_get_letohs(tvb, offset);
6805         proto_tree_add_uint(tree, hf_smb_acl_revision,
6806                 tvb, offset, 2, revision);
6807         offset += 2;
6808
6809         switch(revision){
6810         case 2:  /* only version we will ever see of this structure?*/
6811         case 3:
6812           /* size */
6813           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
6814           offset += 2;
6815
6816           /* number of ace structures */
6817           num_aces = tvb_get_letohl(tvb, offset);
6818           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
6819                               tvb, offset, 4, num_aces);
6820           offset += 4;
6821
6822           while(num_aces--){
6823             offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
6824           }
6825         }
6826
6827         proto_item_set_len(item, offset-old_offset);
6828         return offset;
6829 }
6830
6831 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
6832   "OWNER is DEFAULTED",
6833   "Owner is NOT defaulted"
6834 };
6835 static const true_false_string tfs_sec_desc_type_group_defaulted = {
6836   "GROUP is DEFAULTED",
6837   "Group is NOT defaulted"
6838 };
6839 static const true_false_string tfs_sec_desc_type_dacl_present = {
6840   "DACL is PRESENT",
6841   "DACL is NOT present"
6842 };
6843 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
6844   "DACL is DEFAULTED",
6845   "DACL is NOT defaulted"
6846 };
6847 static const true_false_string tfs_sec_desc_type_sacl_present = {
6848   "SACL is PRESENT",
6849   "SACL is NOT present"
6850 };
6851 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
6852   "SACL is DEFAULTED",
6853   "SACL is NOT defaulted"
6854 };
6855 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
6856   "DACL has AUTO INHERIT REQUIRED",
6857   "DACL does NOT require auto inherit"
6858 };
6859 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
6860   "SACL has AUTO INHERIT REQUIRED",
6861   "SACL does NOT require auto inherit"
6862 };
6863 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
6864   "DACL is AUTO INHERITED",
6865   "DACL is NOT auto inherited"
6866 };
6867 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
6868   "SACL is AUTO INHERITED",
6869   "SACL is NOT auto inherited"
6870 };
6871 static const true_false_string tfs_sec_desc_type_dacl_protected = {
6872   "The DACL is PROTECTED",
6873   "The DACL is NOT protected"
6874 };
6875 static const true_false_string tfs_sec_desc_type_sacl_protected = {
6876   "The SACL is PROTECTED",
6877   "The SACL is NOT protected"
6878 };
6879 static const true_false_string tfs_sec_desc_type_self_relative = {
6880   "This SecDesc is SELF RELATIVE",
6881   "This SecDesc is NOT self relative"
6882 };
6883
6884
6885 static int
6886 dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6887 {
6888         proto_item *item = NULL;
6889         proto_tree *tree = NULL;
6890         guint16 mask;
6891
6892         mask = tvb_get_letohs(tvb, offset);
6893         if(parent_tree){
6894                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6895                                            "Type: 0x%04x", mask);
6896                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
6897         }
6898
6899         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
6900                                tvb, offset, 2, mask);
6901         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
6902                                tvb, offset, 2, mask);
6903         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
6904                                tvb, offset, 2, mask);
6905         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
6906                                tvb, offset, 2, mask);
6907         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
6908                                tvb, offset, 2, mask);
6909         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
6910                                tvb, offset, 2, mask);
6911         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
6912                                tvb, offset, 2, mask);
6913         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
6914                                tvb, offset, 2, mask);
6915         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
6916                                tvb, offset, 2, mask);
6917         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
6918                                tvb, offset, 2, mask);
6919         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
6920                                tvb, offset, 2, mask);
6921         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
6922                                tvb, offset, 2, mask);
6923         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
6924                                tvb, offset, 2, mask);
6925
6926
6927         offset += 2;
6928         return offset;
6929 }
6930
6931 /* This function is also called from DCREPC services; it may be that, in
6932    some cases, the NDR syntax must be followed, but that's not the case,
6933    for example, for the security descriptor inside an LSA Security
6934    Descriptor structure.
6935
6936    A "len" of -1 means that the NDR syntax must be followed.
6937    In that case, we assume that owner SID, group SID, SACL, and DACL objects
6938    are always stored in order (when present) and that all of them are aligned
6939    on a 4 byte boundary, and we no longer use the xxx_offset other than to
6940    check that they are non-NULL to be compatible with DCERPC NDR Unique.
6941
6942    Otherwise, we use the offsets to see where the owner SID, group SID,
6943    SACL, and DACL are stored. */
6944 int
6945 dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
6946 {
6947         proto_item *item = NULL;
6948         proto_tree *tree = NULL;
6949         guint16 revision;
6950         int old_offset = offset;
6951         guint32 owner_sid_offset;
6952         guint32 group_sid_offset;
6953         guint32 sacl_offset;
6954         guint32 dacl_offset;
6955
6956         if(parent_tree){
6957                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6958                                            "NT Security Descriptor");
6959                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
6960         }
6961
6962         /* revision */
6963         revision = tvb_get_letohs(tvb, offset);
6964         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
6965                 tvb, offset, 2, revision);
6966         offset += 2;
6967
6968         switch(revision){
6969         case 1:  /* only version we will ever see of this structure?*/
6970           /* type */
6971           offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
6972
6973           /* offset to owner sid */
6974           owner_sid_offset = tvb_get_letohl(tvb, offset);
6975           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
6976           offset += 4;
6977
6978           /* offset to group sid */
6979           group_sid_offset = tvb_get_letohl(tvb, offset);
6980           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
6981           offset += 4;
6982
6983           /* offset to sacl */
6984           sacl_offset = tvb_get_letohl(tvb, offset);
6985           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
6986           offset += 4;
6987
6988           /* offset to dacl */
6989           dacl_offset = tvb_get_letohl(tvb, offset);
6990           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
6991           offset += 4;
6992
6993           /*owner SID*/
6994           if(owner_sid_offset){
6995             if (len == -1)
6996               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Owner");
6997             else
6998               dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
6999           }
7000
7001           /*group SID*/
7002           if(group_sid_offset){
7003             if (len == -1)
7004               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Group");
7005             else
7006               dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
7007           }
7008
7009           /* sacl */
7010           if(sacl_offset){
7011             if (len == -1)
7012               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "System (SACL)");
7013             else
7014               dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
7015           }
7016
7017           /* dacl */
7018           if(dacl_offset){
7019             if (len == -1)
7020               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "User (DACL)");
7021             else
7022               dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
7023           }
7024
7025         }
7026
7027         if (len == -1)
7028                 proto_item_set_len(item, offset-old_offset);
7029         return offset;
7030 }
7031
7032 static int
7033 dissect_nt_user_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
7034 {
7035         int old_offset, old_sid_offset;
7036         guint32 qsize;
7037
7038         do {
7039                 old_offset=offset;
7040
7041                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7042                 qsize=tvb_get_letohl(tvb, offset);
7043                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7044                 COUNT_BYTES_TRANS_SUBR(4);
7045
7046                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7047                 /* length of SID */
7048                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7049                 COUNT_BYTES_TRANS_SUBR(4);
7050
7051                 /* 16 unknown bytes */
7052                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7053                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7054                             offset, 8, TRUE);
7055                 COUNT_BYTES_TRANS_SUBR(8);
7056
7057                 /* number of bytes for used quota */
7058                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7059                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7060                 COUNT_BYTES_TRANS_SUBR(8);
7061
7062                 /* number of bytes for quota warning */
7063                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7064                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7065                 COUNT_BYTES_TRANS_SUBR(8);
7066
7067                 /* number of bytes for quota limit */
7068                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7069                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7070                 COUNT_BYTES_TRANS_SUBR(8);
7071
7072                 /* SID of the user */
7073                 old_sid_offset=offset;
7074                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7075                 *bcp -= (offset-old_sid_offset);
7076
7077                 if(qsize){
7078                         offset = old_offset+qsize;
7079                 }
7080         }while(qsize);
7081
7082
7083         return offset;
7084 }
7085
7086
7087 static int
7088 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7089 {
7090         proto_item *item = NULL;
7091         proto_tree *tree = NULL;
7092         smb_info_t *si;
7093         int old_offset = offset;
7094         guint16 bcp=bc; /* XXX fixme */
7095
7096         si = (smb_info_t *)pinfo->private_data;
7097
7098         if(parent_tree){
7099                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7100                                 "%s Data",
7101                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7102                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7103         }
7104
7105         switch(ntd->subcmd){
7106         case NT_TRANS_CREATE:
7107                 /* security descriptor */
7108                 if(ntd->sd_len){
7109                         offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
7110                 }
7111
7112                 /* extended attributes */
7113                 if(ntd->ea_len){
7114                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7115                         offset += ntd->ea_len;
7116                 }
7117
7118                 break;
7119         case NT_TRANS_IOCTL:
7120                 /* ioctl data */
7121                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7122                 offset += bc;
7123
7124                 break;
7125         case NT_TRANS_SSD:
7126                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, bc);
7127                 break;
7128         case NT_TRANS_NOTIFY:
7129                 break;
7130         case NT_TRANS_RENAME:
7131                 /* XXX not documented */
7132                 break;
7133         case NT_TRANS_QSD:
7134                 break;
7135         case NT_TRANS_GET_USER_QUOTA:
7136                 /* unknown 4 bytes */
7137                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7138                             offset, 4, TRUE);
7139                 offset += 4;
7140
7141                 /* length of SID */
7142                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7143                 offset +=4;
7144
7145                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7146                 break;
7147         case NT_TRANS_SET_USER_QUOTA:
7148                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7149                 break;
7150         }
7151
7152         /* ooops there were data we didnt know how to process */
7153         if((offset-old_offset) < bc){
7154                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7155                     bc - (offset-old_offset), TRUE);
7156                 offset += bc - (offset-old_offset);
7157         }
7158
7159         return offset;
7160 }
7161
7162 static int
7163 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)
7164 {
7165         proto_item *item = NULL;
7166         proto_tree *tree = NULL;
7167         smb_info_t *si;
7168         guint32 fn_len;
7169         const char *fn;
7170
7171         si = (smb_info_t *)pinfo->private_data;
7172
7173         if(parent_tree){
7174                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7175                                 "%s Parameters",
7176                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7177                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7178         }
7179
7180         switch(ntd->subcmd){
7181         case NT_TRANS_CREATE:
7182                 /* Create flags */
7183                 offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
7184                 bc -= 4;
7185
7186                 /* root directory fid */
7187                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7188                 COUNT_BYTES(4);
7189
7190                 /* nt access mask */
7191                 offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
7192                 bc -= 4;
7193         
7194                 /* allocation size */
7195                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7196                 COUNT_BYTES(8);
7197         
7198                 /* Extended File Attributes */
7199                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7200                 bc -= 4;
7201
7202                 /* share access */
7203                 offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
7204                 bc -= 4;
7205         
7206                 /* create disposition */
7207                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7208                 COUNT_BYTES(4);
7209
7210                 /* create options */
7211                 offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
7212                 bc -= 4;
7213
7214                 /* sd length */
7215                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7216                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7217                 COUNT_BYTES(4);
7218
7219                 /* ea length */
7220                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7221                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7222                 COUNT_BYTES(4);
7223
7224                 /* file name len */
7225                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7226                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7227                 COUNT_BYTES(4);
7228
7229                 /* impersonation level */
7230                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7231                 COUNT_BYTES(4);
7232         
7233                 /* security flags */
7234                 offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
7235                 bc -= 1;
7236
7237                 /* file name */
7238                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7239                 if (fn != NULL) {
7240                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7241                                 fn);
7242                         COUNT_BYTES(fn_len);
7243                 }
7244
7245                 break;
7246         case NT_TRANS_IOCTL:
7247                 break;
7248         case NT_TRANS_SSD: {
7249                 guint16 fid;
7250
7251                 /* fid */
7252                 fid = tvb_get_letohs(tvb, offset);
7253                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7254                 offset += 2;
7255
7256                 /* 2 reserved bytes */
7257                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7258                 offset += 2;
7259
7260                 /* security information */
7261                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7262                 break;
7263         }
7264         case NT_TRANS_NOTIFY:
7265                 break;
7266         case NT_TRANS_RENAME:
7267                 /* XXX not documented */
7268                 break;
7269         case NT_TRANS_QSD: {
7270                 guint16 fid;
7271
7272                 /* fid */
7273                 fid = tvb_get_letohs(tvb, offset);
7274                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7275                 offset += 2;
7276
7277                 /* 2 reserved bytes */
7278                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7279                 offset += 2;
7280
7281                 /* security information */
7282                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7283                 break;
7284         }
7285         case NT_TRANS_GET_USER_QUOTA:
7286                 /* not decoded yet */
7287                 break;
7288         case NT_TRANS_SET_USER_QUOTA:
7289                 /* not decoded yet */
7290                 break;
7291         }
7292
7293         return offset;
7294 }
7295
7296 static int
7297 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7298 {
7299         proto_item *item = NULL;
7300         proto_tree *tree = NULL;
7301         smb_info_t *si;
7302         int old_offset = offset;
7303
7304         si = (smb_info_t *)pinfo->private_data;
7305
7306         if(parent_tree){
7307                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7308                                 "%s Setup",
7309                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7310                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7311         }
7312  
7313         switch(ntd->subcmd){
7314         case NT_TRANS_CREATE:
7315                 break;
7316         case NT_TRANS_IOCTL: {
7317                 guint16 fid;
7318
7319                 /* function code */
7320                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7321                 offset += 4;
7322
7323                 /* fid */
7324                 fid = tvb_get_letohs(tvb, offset);
7325                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7326                 offset += 2;
7327
7328                 /* isfsctl */
7329                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7330                 offset += 1;
7331
7332                 /* isflags */
7333                 offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
7334
7335                 break;
7336         }
7337         case NT_TRANS_SSD:
7338                 break;
7339         case NT_TRANS_NOTIFY: {
7340                 guint16 fid;
7341
7342                 /* completion filter */
7343                 offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
7344
7345                 /* fid */
7346                 fid = tvb_get_letohs(tvb, offset);
7347                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7348                 offset += 2;
7349
7350                 /* watch tree */
7351                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7352                 offset += 1;
7353
7354                 /* reserved byte */
7355                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7356                 offset += 1;
7357
7358                 break;
7359         }
7360         case NT_TRANS_RENAME:
7361                 /* XXX not documented */
7362                 break;
7363         case NT_TRANS_QSD:
7364                 break;
7365         case NT_TRANS_GET_USER_QUOTA:
7366                 /* not decoded yet */
7367                 break;
7368         case NT_TRANS_SET_USER_QUOTA:
7369                 /* not decoded yet */
7370                 break;
7371         }
7372  
7373         return old_offset+len;
7374 }
7375
7376
7377 static int
7378 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7379 {
7380         guint8 wc, sc;
7381         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7382         smb_info_t *si;
7383         smb_saved_info_t *sip;
7384         int subcmd;
7385         nt_trans_data ntd;
7386         guint16 bc;
7387         int padcnt;
7388         smb_nt_transact_info_t *nti;
7389
7390         si = (smb_info_t *)pinfo->private_data;
7391         sip = si->sip;
7392
7393         WORD_COUNT;
7394
7395         if(wc>=19){
7396                 /* primary request */
7397                 /* max setup count */
7398                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7399                 offset += 1;
7400
7401                 /* 2 reserved bytes */
7402                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7403                 offset += 2;
7404         } else {
7405                 /* secondary request */
7406                 /* 3 reserved bytes */
7407                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7408                 offset += 3;
7409         }
7410
7411
7412         /* total param count */
7413         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7414         offset += 4;
7415         
7416         /* total data count */
7417         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7418         offset += 4;
7419
7420         if(wc>=19){
7421                 /* primary request */
7422                 /* max param count */
7423                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7424                 offset += 4;
7425
7426                 /* max data count */
7427                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7428                 offset += 4;
7429         }
7430
7431         /* param count */
7432         pc = tvb_get_letohl(tvb, offset);
7433         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7434         offset += 4;
7435         
7436         /* param offset */
7437         po = tvb_get_letohl(tvb, offset);
7438         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7439         offset += 4;
7440
7441         /* param displacement */
7442         if(wc>=19){
7443                 /* primary request*/
7444                 pd = 0;
7445         } else {
7446                 /* secondary request */
7447                 pd = tvb_get_letohl(tvb, offset);
7448                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7449                 offset += 4;
7450         }
7451
7452         /* data count */
7453         dc = tvb_get_letohl(tvb, offset);
7454         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7455         offset += 4;
7456
7457         /* data offset */
7458         od = tvb_get_letohl(tvb, offset);
7459         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7460         offset += 4;
7461
7462         /* data displacement */
7463         if(wc>=19){
7464                 /* primary request */
7465                 dd = 0;
7466         } else {
7467                 /* secondary request */
7468                 dd = tvb_get_letohl(tvb, offset);
7469                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7470                 offset += 4;
7471         }
7472
7473         /* setup count */
7474         if(wc>=19){
7475                 /* primary request */
7476                 sc = tvb_get_guint8(tvb, offset);
7477                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7478                 offset += 1;
7479         } else {
7480                 /* secondary request */
7481                 sc = 0;
7482         }
7483
7484         /* function */
7485         if(wc>=19){
7486                 /* primary request */
7487                 subcmd = tvb_get_letohs(tvb, offset);
7488                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7489                 if(check_col(pinfo->cinfo, COL_INFO)){
7490                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7491                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7492                 }
7493                 ntd.subcmd = subcmd;
7494                 if (!si->unidir) {
7495                         if(!pinfo->fd->flags.visited){
7496                                 /* 
7497                                  * Allocate a new smb_nt_transact_info_t
7498                                  * structure.
7499                                  */
7500                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7501                                 nti->subcmd = subcmd;
7502                                 sip->extra_info = nti;
7503                         }
7504                 }
7505         } else {
7506                 /* secondary request */
7507                 if(check_col(pinfo->cinfo, COL_INFO)){
7508                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7509                 }
7510         }
7511         offset += 2;
7512
7513         /* this is a padding byte */
7514         if(offset%1){
7515                 /* pad byte */
7516                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7517                 offset += 1;
7518         }
7519
7520         /* if there were any setup bytes, decode them */
7521         if(sc){
7522                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7523                 offset += sc*2;
7524         }
7525
7526         BYTE_COUNT;
7527         
7528         /* parameters */
7529         if(po>(guint32)offset){
7530                 /* We have some initial padding bytes.
7531                 */
7532                 padcnt = po-offset;
7533                 if (padcnt > bc)
7534                         padcnt = bc;
7535                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7536                 COUNT_BYTES(padcnt);
7537         }
7538         if(pc){
7539                 CHECK_BYTE_COUNT(pc);
7540                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7541                 COUNT_BYTES(pc);
7542         }
7543
7544         /* data */
7545         if(od>(guint32)offset){
7546                 /* We have some initial padding bytes.
7547                 */
7548                 padcnt = od-offset;
7549                 if (padcnt > bc)
7550                         padcnt = bc;
7551                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7552                 COUNT_BYTES(padcnt);
7553         }
7554         if(dc){
7555                 CHECK_BYTE_COUNT(dc);
7556                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7557                 COUNT_BYTES(dc);
7558         }
7559
7560         END_OF_SMB
7561
7562         return offset;
7563 }
7564
7565
7566
7567 static int
7568 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7569 {
7570         proto_item *item = NULL;
7571         proto_tree *tree = NULL;
7572         smb_info_t *si;
7573         smb_nt_transact_info_t *nti;
7574         guint16 bcp;
7575
7576         si = (smb_info_t *)pinfo->private_data;
7577         if (si->sip != NULL)
7578                 nti = si->sip->extra_info;
7579         else
7580                 nti = NULL;
7581
7582         if(parent_tree){
7583                 if(nti != NULL){
7584                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7585                                 "%s Data",
7586                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7587                 } else {
7588                         /*
7589                          * We never saw the request to which this is a
7590                          * response.
7591                          */
7592                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7593                                 "Unknown NT Transaction Data (matching request not seen)");
7594                 }
7595                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7596         }
7597
7598         if (nti == NULL) {
7599                 offset += len;
7600                 return offset;
7601         }
7602         switch(nti->subcmd){
7603         case NT_TRANS_CREATE:
7604                 break;
7605         case NT_TRANS_IOCTL:
7606                 /* ioctl data */
7607                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7608                 offset += len;
7609
7610                 break;
7611         case NT_TRANS_SSD:
7612                 break;
7613         case NT_TRANS_NOTIFY:
7614                 break;
7615         case NT_TRANS_RENAME:
7616                 /* XXX not documented */
7617                 break;
7618         case NT_TRANS_QSD:
7619                 /*
7620                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7621                  * which may be documented in the Win32 documentation
7622                  * somewhere.
7623                  */
7624                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
7625                 break;
7626         case NT_TRANS_GET_USER_QUOTA:
7627                 bcp=len;
7628                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7629                 break;
7630         case NT_TRANS_SET_USER_QUOTA:
7631                 /* not decoded yet */
7632                 break;
7633         }
7634
7635         return offset;
7636 }
7637  
7638 static int
7639 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)
7640 {
7641         proto_item *item = NULL;
7642         proto_tree *tree = NULL;
7643         guint32 fn_len;
7644         const char *fn;
7645         smb_info_t *si;
7646         smb_nt_transact_info_t *nti;
7647         guint16 fid;
7648         int old_offset;
7649         guint32 neo;
7650         int padcnt;
7651
7652         si = (smb_info_t *)pinfo->private_data;
7653         if (si->sip != NULL)
7654                 nti = si->sip->extra_info;
7655         else
7656                 nti = NULL;
7657
7658         if(parent_tree){
7659                 if(nti != NULL){
7660                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7661                                 "%s Parameters",
7662                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7663                 } else {
7664                         /*
7665                          * We never saw the request to which this is a
7666                          * response.
7667                          */
7668                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7669                                 "Unknown NT Transaction Parameters (matching request not seen)");
7670                 }
7671                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7672         }
7673
7674         if (nti == NULL) {
7675                 offset += len;
7676                 return offset;
7677         }
7678         switch(nti->subcmd){
7679         case NT_TRANS_CREATE:
7680                 /* oplock level */
7681                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7682                 offset += 1;
7683
7684                 /* reserved byte */
7685                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7686                 offset += 1;
7687                 
7688                 /* fid */
7689                 fid = tvb_get_letohs(tvb, offset);
7690                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7691                 offset += 2;
7692
7693                 /* create action */
7694                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7695                 offset += 4;
7696
7697                 /* ea error offset */
7698                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7699                 offset += 4;
7700
7701                 /* create time */
7702                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7703                         hf_smb_create_time);
7704         
7705                 /* access time */
7706                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7707                         hf_smb_access_time);
7708         
7709                 /* last write time */
7710                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7711                         hf_smb_last_write_time);
7712         
7713                 /* last change time */
7714                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7715                         hf_smb_change_time);
7716         
7717                 /* Extended File Attributes */
7718                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7719
7720                 /* allocation size */
7721                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7722                 offset += 8;
7723
7724                 /* end of file */
7725                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7726                 offset += 8;
7727
7728                 /* File Type */
7729                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7730                 offset += 2;
7731
7732                 /* device state */
7733                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
7734
7735                 /* is directory */
7736                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7737                 offset += 1;
7738                 break;
7739         case NT_TRANS_IOCTL:
7740                 break;
7741         case NT_TRANS_SSD:
7742                 break;
7743         case NT_TRANS_NOTIFY:
7744                 while(len){
7745                         old_offset = offset;
7746
7747                         /* next entry offset */
7748                         neo = tvb_get_letohl(tvb, offset);
7749                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
7750                         COUNT_BYTES(4);
7751                         len -= 4;
7752                         /* broken implementations */
7753                         if(len<0)break;
7754         
7755                         /* action */
7756                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
7757                         COUNT_BYTES(4);
7758                         len -= 4;
7759                         /* broken implementations */
7760                         if(len<0)break;
7761
7762                         /* file name len */
7763                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
7764                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7765                         COUNT_BYTES(4);
7766                         len -= 4;
7767                         /* broken implementations */
7768                         if(len<0)break;
7769
7770                         /* file name */
7771                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7772                         if (fn == NULL)
7773                                 break;
7774                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7775                                 fn);
7776                         COUNT_BYTES(fn_len);
7777                         len -= fn_len;
7778                         /* broken implementations */
7779                         if(len<0)break;
7780
7781                         if (neo == 0)
7782                                 break;  /* no more structures */
7783
7784                         /* skip to next structure */
7785                         padcnt = (old_offset + neo) - offset;
7786                         if (padcnt < 0) {
7787                                 /*
7788                                  * XXX - this is bogus; flag it?
7789                                  */
7790                                 padcnt = 0;
7791                         }
7792                         if (padcnt != 0) {
7793                                 COUNT_BYTES(padcnt);
7794                                 len -= padcnt;
7795                                 /* broken implementations */
7796                                 if(len<0)break;
7797                         }
7798                 }
7799                 break;
7800         case NT_TRANS_RENAME:
7801                 /* XXX not documented */
7802                 break;
7803         case NT_TRANS_QSD:
7804                 /*
7805                  * This appears to be the size of the security
7806                  * descriptor; the calling sequence of
7807                  * "ZwQuerySecurityObject()" suggests that it would
7808                  * be.  The actual security descriptor wouldn't
7809                  * follow if the max data count in the request
7810                  * was smaller; this lets the client know how
7811                  * big a buffer it needs to provide.
7812                  */
7813                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
7814                 offset += 4;
7815                 break;
7816         case NT_TRANS_GET_USER_QUOTA:
7817                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
7818                         tvb_get_letohl(tvb, offset));
7819                 offset += 4;
7820                 break;
7821         case NT_TRANS_SET_USER_QUOTA:
7822                 /* not decoded yet */
7823                 break;
7824         }
7825
7826         return offset;
7827 }
7828  
7829 static int
7830 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7831 {
7832         proto_item *item = NULL;
7833         proto_tree *tree = NULL;
7834         smb_info_t *si;
7835         smb_nt_transact_info_t *nti;
7836
7837         si = (smb_info_t *)pinfo->private_data;
7838         if (si->sip != NULL)
7839                 nti = si->sip->extra_info;
7840         else
7841                 nti = NULL;
7842
7843         if(parent_tree){
7844                 if(nti != NULL){
7845                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7846                                 "%s Setup",
7847                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7848                 } else {
7849                         /*
7850                          * We never saw the request to which this is a
7851                          * response.
7852                          */
7853                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7854                                 "Unknown NT Transaction Setup (matching request not seen)");
7855                 }
7856                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7857         }
7858
7859         if (nti == NULL) {
7860                 offset += len;
7861                 return offset;
7862         }
7863         switch(nti->subcmd){
7864         case NT_TRANS_CREATE:
7865                 break;
7866         case NT_TRANS_IOCTL:
7867                 break;
7868         case NT_TRANS_SSD:
7869                 break;
7870         case NT_TRANS_NOTIFY:
7871                 break;
7872         case NT_TRANS_RENAME:
7873                 /* XXX not documented */
7874                 break;
7875         case NT_TRANS_QSD:
7876                 break;
7877         case NT_TRANS_GET_USER_QUOTA:
7878                 /* not decoded yet */
7879                 break;
7880         case NT_TRANS_SET_USER_QUOTA:
7881                 /* not decoded yet */
7882                 break;
7883         }
7884
7885         return offset;
7886 }
7887
7888 static int
7889 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7890 {
7891         guint8 wc, sc;
7892         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
7893         guint32 td=0, tp=0;
7894         smb_info_t *si;
7895         smb_nt_transact_info_t *nti;
7896         static nt_trans_data ntd;
7897         guint16 bc;
7898         int padcnt;
7899         fragment_data *r_fd = NULL;
7900         tvbuff_t *pd_tvb=NULL;
7901         gboolean save_fragmented;
7902
7903         si = (smb_info_t *)pinfo->private_data;
7904         if (si->sip != NULL)
7905                 nti = si->sip->extra_info;
7906         else
7907                 nti = NULL;
7908
7909         /* primary request */
7910         if(nti != NULL){
7911                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
7912                 if(check_col(pinfo->cinfo, COL_INFO)){
7913                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7914                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
7915                 }
7916         } else {
7917                 proto_tree_add_text(tree, tvb, offset, 0,
7918                         "Function: <unknown function - could not find matching request>");
7919                 if(check_col(pinfo->cinfo, COL_INFO)){
7920                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
7921                 }
7922         }
7923
7924         WORD_COUNT;
7925
7926         /* 3 reserved bytes */
7927         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7928         offset += 3;
7929
7930         /* total param count */
7931         tp = tvb_get_letohl(tvb, offset);
7932         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
7933         offset += 4;
7934         
7935         /* total data count */
7936         td = tvb_get_letohl(tvb, offset);
7937         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
7938         offset += 4;
7939
7940         /* param count */
7941         pc = tvb_get_letohl(tvb, offset);
7942         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7943         offset += 4;
7944         
7945         /* param offset */
7946         po = tvb_get_letohl(tvb, offset);
7947         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7948         offset += 4;
7949
7950         /* param displacement */
7951         pd = tvb_get_letohl(tvb, offset);
7952         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7953         offset += 4;
7954
7955         /* data count */
7956         dc = tvb_get_letohl(tvb, offset);
7957         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7958         offset += 4;
7959
7960         /* data offset */
7961         od = tvb_get_letohl(tvb, offset);
7962         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7963         offset += 4;
7964
7965         /* data displacement */
7966         dd = tvb_get_letohl(tvb, offset);
7967         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7968         offset += 4;
7969
7970         /* setup count */
7971         sc = tvb_get_guint8(tvb, offset);
7972         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7973         offset += 1;
7974
7975         /* setup data */        
7976         if(sc){
7977                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
7978                 offset += sc*2;
7979         }
7980
7981         BYTE_COUNT;
7982
7983         /* reassembly of SMB NT Transaction data payload.
7984            In this section we do reassembly of both the data and parameters
7985            blocks of the SMB transaction command.
7986         */
7987         save_fragmented = pinfo->fragmented;
7988         /* do we need reassembly? */
7989         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
7990                 /* oh yeah, either data or parameter section needs 
7991                    reassembly...
7992                 */
7993                 pinfo->fragmented = TRUE;
7994                 if(smb_trans_reassembly){
7995                         /* ...and we were told to do reassembly */
7996                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
7997                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
7998                                                              po, pc, pd, td+tp);
7999                                 
8000                         }
8001                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8002                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8003                                                              od, dc, dd+tp, td+tp);
8004                         }
8005                 }
8006         }
8007
8008         /* if we got a reassembled fd structure from the reassembly routine we
8009            must create pd_tvb from it 
8010         */
8011         if(r_fd){
8012                 proto_tree *tr;
8013                 proto_item *it;
8014                 fragment_data *fd;
8015                 
8016                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8017                                              r_fd->datalen);
8018                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8019                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
8020                 pinfo->fragmented = FALSE;
8021
8022                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
8023                 tr = proto_item_add_subtree(it, ett_smb_segments);
8024                 for(fd=r_fd->next;fd;fd=fd->next){
8025                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
8026                                             "Frame:%u Data:%u-%u",
8027                                             fd->frame, fd->offset,
8028                                             fd->offset+fd->len-1);
8029                 }
8030         }
8031
8032
8033         if(pd_tvb){
8034           /* we have reassembled data, grab param and data from there */
8035           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8036                                           &ntd, tvb_length(pd_tvb));
8037           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8038         } else {
8039           /* we do not have reassembled data, just use what we have in the 
8040              packet as well as we can */
8041           /* parameters */
8042           if(po>(guint32)offset){
8043             /* We have some initial padding bytes.
8044              */
8045             padcnt = po-offset;
8046             if (padcnt > bc)
8047               padcnt = bc;
8048             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8049             COUNT_BYTES(padcnt);
8050           }
8051           if(pc){
8052             CHECK_BYTE_COUNT(pc);
8053             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8054             COUNT_BYTES(pc);
8055           }
8056           
8057           /* data */
8058           if(od>(guint32)offset){
8059             /* We have some initial padding bytes.
8060              */
8061             padcnt = od-offset;
8062             if (padcnt > bc)
8063               padcnt = bc;
8064             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8065             COUNT_BYTES(padcnt);
8066           }
8067           if(dc){
8068             CHECK_BYTE_COUNT(dc);
8069             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8070             COUNT_BYTES(dc);
8071           }
8072         }
8073         pinfo->fragmented = save_fragmented;
8074
8075         END_OF_SMB
8076
8077         return offset;
8078 }
8079
8080 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8081    NT Transaction command  ends here
8082    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8083
8084 static const value_string print_mode_vals[] = {
8085         {0,     "Text Mode"},
8086         {1,     "Graphics Mode"},
8087         {0, NULL}
8088 };
8089  
8090 static int
8091 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8092 {
8093         int fn_len;
8094         const char *fn;
8095         guint8 wc;
8096         guint16 bc;
8097
8098         WORD_COUNT;
8099
8100         /* setup len */
8101         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8102         offset += 2;
8103
8104         /* print mode */
8105         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8106         offset += 2;
8107
8108         BYTE_COUNT;
8109
8110         /* buffer format */
8111         CHECK_BYTE_COUNT(1);
8112         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8113         COUNT_BYTES(1);
8114
8115         /* print identifier */
8116         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
8117         if (fn == NULL)
8118                 goto endofcommand;
8119         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8120                 fn);
8121         COUNT_BYTES(fn_len);
8122
8123         END_OF_SMB
8124
8125         return offset;
8126 }
8127
8128
8129 static int
8130 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8131 {
8132         int cnt;
8133         guint8 wc;
8134         guint16 bc, fid;
8135
8136         WORD_COUNT;
8137
8138         /* fid */
8139         fid = tvb_get_letohs(tvb, offset);
8140         add_fid(tvb, pinfo, tree, offset, 2, fid);
8141         offset += 2;
8142
8143         BYTE_COUNT;
8144
8145         /* buffer format */
8146         CHECK_BYTE_COUNT(1);
8147         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8148         COUNT_BYTES(1);
8149
8150         /* data len */
8151         CHECK_BYTE_COUNT(2);
8152         cnt = tvb_get_letohs(tvb, offset);
8153         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8154         COUNT_BYTES(2);
8155
8156         /* file data */
8157         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
8158
8159         END_OF_SMB
8160
8161         return offset;
8162 }
8163
8164
8165 static const value_string print_status_vals[] = {
8166         {1,     "Held or Stopped"},
8167         {2,     "Printing"},
8168         {3,     "Awaiting print"},
8169         {4,     "In intercept"},
8170         {5,     "File had error"},
8171         {6,     "Printer error"},
8172         {0, NULL}
8173 };
8174  
8175 static int
8176 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8177 {
8178         guint8 wc;
8179         guint16 bc;
8180
8181         WORD_COUNT;
8182
8183         /* max count */
8184         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8185         offset += 2;
8186
8187         /* start index */
8188         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8189         offset += 2;
8190
8191         BYTE_COUNT;
8192
8193         END_OF_SMB
8194
8195         return offset;
8196 }
8197
8198 static int
8199 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8200     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8201 {
8202         proto_item *item = NULL;
8203         proto_tree *tree = NULL;
8204         int fn_len;
8205         const char *fn;
8206
8207         if(parent_tree){
8208                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8209                         "Queue entry");
8210                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8211         }
8212
8213         /* queued time */
8214         CHECK_BYTE_COUNT_SUBR(4);
8215         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8216                 hf_smb_print_queue_date,
8217                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8218         *bcp -= 4;
8219
8220         /* status */
8221         CHECK_BYTE_COUNT_SUBR(1);
8222         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8223         COUNT_BYTES_SUBR(1);
8224
8225         /* spool file number */
8226         CHECK_BYTE_COUNT_SUBR(2);
8227         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8228         COUNT_BYTES_SUBR(2);
8229
8230         /* spool file size */
8231         CHECK_BYTE_COUNT_SUBR(4);
8232         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8233         COUNT_BYTES_SUBR(4);
8234
8235         /* reserved byte */
8236         CHECK_BYTE_COUNT_SUBR(1);
8237         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8238         COUNT_BYTES_SUBR(1);
8239
8240         /* file name */
8241         fn_len = 16;
8242         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
8243         CHECK_STRING_SUBR(fn);
8244         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8245                 fn);
8246         COUNT_BYTES_SUBR(fn_len);
8247
8248         *trunc = FALSE;
8249         return offset;
8250 }
8251
8252 static int
8253 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8254 {
8255         guint16 cnt=0, len;
8256         guint8 wc;
8257         guint16 bc;
8258         gboolean trunc;
8259
8260         WORD_COUNT;
8261
8262         /* count */
8263         cnt = tvb_get_letohs(tvb, offset);
8264         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8265         offset += 2;
8266
8267         /* restart index */
8268         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8269         offset += 2;
8270
8271         BYTE_COUNT;
8272
8273         /* buffer format */
8274         CHECK_BYTE_COUNT(1);
8275         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8276         COUNT_BYTES(1);
8277
8278         /* data len */
8279         CHECK_BYTE_COUNT(2);
8280         len = tvb_get_letohs(tvb, offset);
8281         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8282         COUNT_BYTES(2);
8283
8284         /* queue elements */
8285         while(cnt--){
8286                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8287                     &bc, &trunc);
8288                 if (trunc)
8289                         goto endofcommand;
8290         }
8291
8292         END_OF_SMB
8293
8294         return offset;
8295 }
8296
8297
8298 static int
8299 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8300 {
8301         guint8  wc, cmd=0xff;
8302         guint16 andxoffset=0;
8303         guint16 bc;
8304         int fn_len;
8305         const char *fn;
8306
8307         WORD_COUNT;
8308
8309         /* next smb command */
8310         cmd = tvb_get_guint8(tvb, offset);
8311         if(cmd!=0xff){
8312                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8313         } else {
8314                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8315         }
8316         offset += 1;
8317
8318         /* reserved byte */
8319         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8320         offset += 1;
8321
8322         /* andxoffset */
8323         andxoffset = tvb_get_letohs(tvb, offset);
8324         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8325         offset += 2;
8326
8327         /* reserved byte */
8328         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8329         offset += 1;
8330
8331         /* file name len */
8332         fn_len = tvb_get_letohs(tvb, offset);
8333         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8334         offset += 2;
8335
8336         /* Create flags */
8337         offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
8338
8339         /* root directory fid */
8340         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8341         offset += 4;
8342
8343         /* nt access mask */
8344         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
8345
8346         /* allocation size */
8347         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8348         offset += 8;
8349
8350         /* Extended File Attributes */
8351         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8352
8353         /* share access */
8354         offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
8355
8356         /* create disposition */
8357         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8358         offset += 4;
8359
8360         /* create options */
8361         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
8362
8363         /* impersonation level */
8364         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8365         offset += 4;
8366
8367         /* security flags */
8368         offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
8369
8370         BYTE_COUNT;
8371
8372         /* file name */
8373         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8374         if (fn == NULL)
8375                 goto endofcommand;
8376         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8377                 fn);
8378         COUNT_BYTES(fn_len);
8379
8380         if (check_col(pinfo->cinfo, COL_INFO)) {
8381                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8382         }
8383
8384         END_OF_SMB
8385
8386         /* call AndXCommand (if there are any) */
8387         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8388
8389         return offset;
8390 }
8391  
8392
8393 static int
8394 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8395 {
8396         guint8  wc, cmd=0xff;
8397         guint16 andxoffset=0;
8398         guint16 bc;
8399         guint16 fid;
8400
8401         WORD_COUNT;
8402
8403         /* next smb command */
8404         cmd = tvb_get_guint8(tvb, offset);
8405         if(cmd!=0xff){
8406                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8407         } else {
8408                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8409         }
8410         offset += 1;
8411
8412         /* reserved byte */
8413         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8414         offset += 1;
8415
8416         /* andxoffset */
8417         andxoffset = tvb_get_letohs(tvb, offset);
8418         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8419         offset += 2;
8420
8421         /* oplock level */
8422         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8423         offset += 1;
8424
8425         /* fid */
8426         fid = tvb_get_letohs(tvb, offset);
8427         add_fid(tvb, pinfo, tree, offset, 2, fid);
8428         offset += 2;
8429
8430         /* create action */
8431         /*XXX is this really the same as create disposition in the request? it looks so*/
8432         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8433         offset += 4;
8434
8435         /* create time */
8436         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8437                 hf_smb_create_time);
8438         
8439         /* access time */
8440         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8441                 hf_smb_access_time);
8442         
8443         /* last write time */
8444         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8445                 hf_smb_last_write_time);
8446
8447         /* last change time */
8448         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8449                 hf_smb_change_time);
8450         
8451         /* Extended File Attributes */
8452         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8453
8454         /* allocation size */
8455         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8456         offset += 8;
8457
8458         /* end of file */
8459         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8460         offset += 8;
8461
8462         /* File Type */
8463         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8464         offset += 2;
8465
8466         /* IPC State */
8467         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
8468
8469         /* is directory */
8470         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8471         offset += 1;
8472
8473         BYTE_COUNT;
8474
8475         END_OF_SMB
8476
8477         /* call AndXCommand (if there are any) */
8478         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8479
8480         return offset;
8481 }
8482
8483
8484 static int
8485 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8486 {
8487         guint8 wc;
8488         guint16 bc;
8489
8490         WORD_COUNT;
8491  
8492         BYTE_COUNT;
8493
8494         END_OF_SMB
8495
8496         return offset;
8497 }
8498
8499 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8500    BEGIN Transaction/Transaction2 Primary and secondary requests
8501    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8502
8503
8504 static const value_string trans2_cmd_vals[] = {
8505         { 0x00,         "OPEN2" },
8506         { 0x01,         "FIND_FIRST2" },
8507         { 0x02,         "FIND_NEXT2" },
8508         { 0x03,         "QUERY_FS_INFORMATION" },
8509         { 0x04,         "SET_FS_QUOTA" },
8510         { 0x05,         "QUERY_PATH_INFORMATION" },
8511         { 0x06,         "SET_PATH_INFORMATION" },
8512         { 0x07,         "QUERY_FILE_INFORMATION" },
8513         { 0x08,         "SET_FILE_INFORMATION" },
8514         { 0x09,         "FSCTL" },
8515         { 0x0A,         "IOCTL2" },
8516         { 0x0B,         "FIND_NOTIFY_FIRST" },
8517         { 0x0C,         "FIND_NOTIFY_NEXT" },
8518         { 0x0D,         "CREATE_DIRECTORY" },
8519         { 0x0E,         "SESSION_SETUP" },
8520         { 0x10,         "GET_DFS_REFERRAL" },
8521         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
8522         { 0,    NULL }
8523 };
8524
8525 static const true_false_string tfs_tf_dtid = {
8526         "Also DISCONNECT TID",
8527         "Do NOT disconnect TID"
8528 };
8529 static const true_false_string tfs_tf_owt = {
8530         "One Way Transaction (NO RESPONSE)",
8531         "Two way transaction"
8532 };
8533
8534 static const true_false_string tfs_ff2_backup = {
8535         "Find WITH backup intent",
8536         "No backup intent"
8537 };
8538 static const true_false_string tfs_ff2_continue = {
8539         "CONTINUE search from previous position",
8540         "New search, do NOT continue from previous position"
8541 };
8542 static const true_false_string tfs_ff2_resume = {
8543         "Return RESUME keys",
8544         "Do NOT return resume keys"
8545 };
8546 static const true_false_string tfs_ff2_close_eos = {
8547         "CLOSE search if END OF SEARCH is reached",
8548         "Do NOT close search if end of search reached"
8549 };
8550 static const true_false_string tfs_ff2_close = {
8551         "CLOSE search after this request",
8552         "Do NOT close search after this request"
8553 };
8554
8555 /* used by
8556    TRANS2_FIND_FIRST2
8557 */
8558 static const value_string ff2_il_vals[] = {
8559         { 1,            "Info Standard  (4.3.4.1)"},
8560         { 2,            "Info Query EA Size  (4.3.4.2)"},
8561         { 3,            "Info Query EAs From List  (4.3.4.2)"},
8562         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
8563         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
8564         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
8565         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
8566         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
8567         {0, NULL}
8568 };
8569
8570 /* values used by :
8571         TRANS2_QUERY_PATH_INFORMATION
8572         TRANS2_SET_PATH_INFORMATION
8573 */
8574 static const value_string qpi_loi_vals[] = {
8575         { 1,            "Info Standard  (4.2.14.1)"},
8576         { 2,            "Info Query EA Size  (4.2.14.1)"},
8577         { 3,            "Info Query EAs From List  (4.2.14.2)"},
8578         { 4,            "Info Query All EAs  (4.2.14.2)"},
8579         { 6,            "Info Is Name Valid  (4.2.14.3)"},
8580         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
8581         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
8582         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
8583         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
8584         { 0x0107,       "Query File All Info  (4.2.14.8)"},
8585         { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
8586         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
8587         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
8588         { 0x0200,       "Set File Unix Basic"},
8589         { 0x0201,       "Set File Unix Link"},
8590         { 0x0202,       "Set File Unix HardLink"},
8591         {0, NULL}
8592 };
8593
8594 static const value_string qfsi_vals[] = {
8595         { 1,            "Info Allocation"},
8596         { 2,            "Info Volume"},
8597         { 0x0102,       "Query FS Volume Info"},
8598         { 0x0103,       "Query FS Size Info"},
8599         { 0x0104,       "Query FS Device Info"},
8600         { 0x0105,       "Query FS Attribute Info"},
8601         { 1006,         "Query FS Quota Info"},
8602         {0, NULL}
8603 };
8604
8605 static const value_string delete_pending_vals[] = {
8606         {0,     "Normal, no pending delete"},
8607         {1,     "This object has DELETE PENDING"},
8608         {0, NULL}
8609 };
8610
8611 static const value_string alignment_vals[] = {
8612         {0,     "Byte alignment"},
8613         {1,     "Word (16bit) alignment"},
8614         {3,     "Long (32bit) alignment"},
8615         {7,     "8 byte boundary alignment"},
8616         {0x0f,  "16 byte boundary alignment"},
8617         {0x1f,  "32 byte boundary alignment"},
8618         {0x3f,  "64 byte boundary alignment"},
8619         {0x7f,  "128 byte boundary alignment"},
8620         {0xff,  "256 byte boundary alignment"},
8621         {0x1ff, "512 byte boundary alignment"},
8622         {0, NULL}
8623 };
8624
8625
8626 static const true_false_string tfs_get_dfs_server_hold_storage = {
8627         "Referral SERVER HOLDS STORAGE for the file",
8628         "Referral server does NOT hold storage for the file"
8629 };
8630 static const true_false_string tfs_get_dfs_fielding = {
8631         "The server in referral is FIELDING CAPABLE",
8632         "The server in referrals is NOT fielding capable"
8633 };
8634
8635 static const true_false_string tfs_dfs_referral_flags_strip = {
8636         "STRIP off pathconsumed characters before submitting",
8637         "Do NOT strip off any characters"
8638 };
8639
8640 static const value_string dfs_referral_server_type_vals[] = {
8641         {0,     "Don't know"},
8642         {1,     "SMB Server"},
8643         {2,     "Netware Server"},
8644         {3,     "Domain Server"},
8645         {0, NULL}
8646 };
8647
8648
8649 static const true_false_string tfs_device_char_removable = {
8650         "This is a REMOVABLE device",
8651         "This is NOT a removable device"
8652 };
8653 static const true_false_string tfs_device_char_read_only = {
8654         "This is a READ-ONLY device",
8655         "This is NOT a read-only device"
8656 };
8657 static const true_false_string tfs_device_char_floppy = {
8658         "This is a FLOPPY DISK device",
8659         "This is NOT a floppy disk device"
8660 };
8661 static const true_false_string tfs_device_char_write_once = {
8662         "This is a WRITE-ONCE device",
8663         "This is NOT a write-once device"
8664 };
8665 static const true_false_string tfs_device_char_remote = {
8666         "This is a REMOTE device",
8667         "This is NOT a remote device"
8668 };
8669 static const true_false_string tfs_device_char_mounted = {
8670         "This device is MOUNTED",
8671         "This device is NOT mounted"
8672 };
8673 static const true_false_string tfs_device_char_virtual = {
8674         "This is a VIRTUAL device",
8675         "This is NOT a virtual device"
8676 };
8677
8678
8679 static const true_false_string tfs_fs_attr_css = {
8680         "This FS supports CASE SENSITIVE SEARCHes",
8681         "This FS does NOT support case sensitive searches"
8682 };
8683 static const true_false_string tfs_fs_attr_cpn = {
8684         "This FS supports CASE PRESERVED NAMES",
8685         "This FS does NOT support case preserved names"
8686 };
8687 static const true_false_string tfs_fs_attr_pacls = {
8688         "This FS supports PERSISTENT ACLs",
8689         "This FS does NOT support persistent acls"
8690 };
8691 static const true_false_string tfs_fs_attr_fc = {
8692         "This FS supports COMPRESSED FILES",
8693         "This FS does NOT support compressed files"
8694 };
8695 static const true_false_string tfs_fs_attr_vq = {
8696         "This FS supports VOLUME QUOTAS",
8697         "This FS does NOT support volume quotas"
8698 };
8699 static const true_false_string tfs_fs_attr_dim = {
8700         "This FS is on a MOUNTED DEVICE",
8701         "This FS is NOT on a mounted device"
8702 };
8703 static const true_false_string tfs_fs_attr_vic = {
8704         "This FS is on a COMPRESSED VOLUME",
8705         "This FS is NOT on a compressed volume"
8706 };
8707
8708
8709
8710 static int
8711 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8712 {
8713         guint16 mask;
8714         proto_item *item = NULL;
8715         proto_tree *tree = NULL;
8716
8717         mask = tvb_get_letohs(tvb, offset);
8718
8719         if(parent_tree){
8720                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8721                         "Flags: 0x%04x", mask);
8722                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
8723         }
8724
8725         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
8726                 tvb, offset, 2, mask);
8727         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
8728                 tvb, offset, 2, mask);
8729         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
8730                 tvb, offset, 2, mask);
8731         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
8732                 tvb, offset, 2, mask);
8733         proto_tree_add_boolean(tree, hf_smb_ff2_close,
8734                 tvb, offset, 2, mask);
8735
8736         offset += 2;
8737
8738         return offset;
8739 }
8740
8741 static int
8742 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
8743     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
8744 {
8745         proto_item *item = NULL;
8746         proto_tree *tree = NULL;
8747         smb_info_t *si;
8748         smb_transact2_info_t *t2i;
8749         int fn_len;
8750         const char *fn;
8751         int old_offset = offset;
8752
8753         si = (smb_info_t *)pinfo->private_data;
8754         if (si->sip != NULL)
8755                 t2i = si->sip->extra_info;
8756         else
8757                 t2i = NULL;
8758
8759         if(parent_tree){
8760                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8761                                 "%s Parameters",
8762                                 val_to_str(subcmd, trans2_cmd_vals, 
8763                                            "Unknown (0x%02x)"));
8764                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
8765         }
8766
8767         switch(subcmd){
8768         case 0x00:      /*TRANS2_OPEN2*/
8769                 /* open flags */
8770                 CHECK_BYTE_COUNT_TRANS(2);
8771                 offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
8772                 bc -= 2;
8773
8774                 /* desired access */
8775                 CHECK_BYTE_COUNT_TRANS(2);
8776                 offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
8777                 bc -= 2;
8778
8779                 /* 2 reserved bytes */
8780                 CHECK_BYTE_COUNT_TRANS(2);
8781                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8782                 COUNT_BYTES_TRANS(2);
8783
8784                 /* File Attributes */
8785                 CHECK_BYTE_COUNT_TRANS(2);
8786                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8787                 bc -= 2;
8788
8789                 /* create time */
8790                 CHECK_BYTE_COUNT_TRANS(4);
8791                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8792                         hf_smb_create_time,
8793                         hf_smb_create_dos_date, hf_smb_create_dos_time,
8794                         TRUE);
8795                 bc -= 4;
8796
8797                 /* open function */
8798                 CHECK_BYTE_COUNT_TRANS(2);
8799                 offset = dissect_open_function(tvb, pinfo, tree, offset);
8800                 bc -= 2;
8801
8802                 /* allocation size */
8803                 CHECK_BYTE_COUNT_TRANS(4);
8804                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
8805                 COUNT_BYTES_TRANS(4);
8806
8807                 /* 10 reserved bytes */
8808                 CHECK_BYTE_COUNT_TRANS(10);
8809                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
8810                 COUNT_BYTES_TRANS(10);
8811
8812                 /* file name */
8813                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8814                 CHECK_STRING_TRANS(fn);
8815                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8816                         fn);
8817                 COUNT_BYTES_TRANS(fn_len);
8818
8819                 if (check_col(pinfo->cinfo, COL_INFO)) {
8820                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8821                         fn);
8822                 }
8823
8824                 /* XXX dont know how to decode FEAList */
8825                 break;
8826         case 0x01:      /*TRANS2_FIND_FIRST2*/
8827                 /* Search Attributes */
8828                 CHECK_BYTE_COUNT_TRANS(2);
8829                 offset = dissect_search_attributes(tvb, pinfo, tree, offset);
8830                 bc -= 2;
8831
8832                 /* search count */
8833                 CHECK_BYTE_COUNT_TRANS(2);
8834                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8835                 COUNT_BYTES_TRANS(2);
8836
8837                 /* Find First2 flags */
8838                 CHECK_BYTE_COUNT_TRANS(2);
8839                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8840                 bc -= 2;
8841
8842                 /* Find First2 information level */
8843                 CHECK_BYTE_COUNT_TRANS(2);
8844                 si->info_level = tvb_get_letohs(tvb, offset);
8845                 if (!pinfo->fd->flags.visited)
8846                         t2i->info_level = si->info_level;
8847                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8848                 COUNT_BYTES_TRANS(2);
8849
8850                 /* storage type */
8851                 CHECK_BYTE_COUNT_TRANS(4);
8852                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
8853                 COUNT_BYTES_TRANS(4);
8854
8855                 /* search pattern */
8856                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8857                 CHECK_STRING_TRANS(fn);
8858                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
8859                         fn);
8860                 COUNT_BYTES_TRANS(fn_len);
8861
8862                 if (check_col(pinfo->cinfo, COL_INFO)) {
8863                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
8864                         fn);
8865                 }
8866
8867                 /* XXX dont know how to decode FEAList */
8868
8869                 break;
8870         case 0x02:      /*TRANS2_FIND_NEXT2*/
8871                 /* sid */
8872                 CHECK_BYTE_COUNT_TRANS(2);
8873                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
8874                 COUNT_BYTES_TRANS(2);
8875
8876                 /* search count */
8877                 CHECK_BYTE_COUNT_TRANS(2);
8878                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8879                 COUNT_BYTES_TRANS(2);
8880
8881                 /* Find First2 information level */
8882                 CHECK_BYTE_COUNT_TRANS(2);
8883                 si->info_level = tvb_get_letohs(tvb, offset);
8884                 if (!pinfo->fd->flags.visited)
8885                         t2i->info_level = si->info_level;
8886                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8887                 COUNT_BYTES_TRANS(2);
8888
8889                 /* resume key */
8890                 CHECK_BYTE_COUNT_TRANS(4);
8891                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
8892                 COUNT_BYTES_TRANS(4);
8893
8894                 /* Find First2 flags */
8895                 CHECK_BYTE_COUNT_TRANS(2);
8896                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8897                 bc -= 2;
8898
8899                 /* file name */
8900                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8901                 CHECK_STRING_TRANS(fn);
8902                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8903                         fn);
8904                 COUNT_BYTES_TRANS(fn_len);
8905
8906                 if (check_col(pinfo->cinfo, COL_INFO)) {
8907                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
8908                         fn);
8909                 }
8910
8911                 break;
8912         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
8913                 /* level of interest */
8914                 CHECK_BYTE_COUNT_TRANS(2);
8915                 si->info_level = tvb_get_letohs(tvb, offset);
8916                 if (!pinfo->fd->flags.visited)
8917                         t2i->info_level = si->info_level;
8918                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
8919                 COUNT_BYTES_TRANS(2);
8920
8921                 break;
8922         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
8923                 /* level of interest */
8924                 CHECK_BYTE_COUNT_TRANS(2);
8925                 si->info_level = tvb_get_letohs(tvb, offset);
8926                 if (!pinfo->fd->flags.visited)
8927                         t2i->info_level = si->info_level;
8928                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8929                 COUNT_BYTES_TRANS(2);
8930                 
8931                 /* 4 reserved bytes */
8932                 CHECK_BYTE_COUNT_TRANS(4);
8933                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
8934                 COUNT_BYTES_TRANS(4);
8935
8936                 /* file name */
8937                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8938                 CHECK_STRING_TRANS(fn);
8939                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8940                         fn);
8941                 COUNT_BYTES_TRANS(fn_len);
8942
8943                 if (check_col(pinfo->cinfo, COL_INFO)) {
8944                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8945                         fn);
8946                 }
8947
8948                 break;
8949         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
8950                 /* level of interest */
8951                 CHECK_BYTE_COUNT_TRANS(2);
8952                 si->info_level = tvb_get_letohs(tvb, offset);
8953                 if (!pinfo->fd->flags.visited)
8954                         t2i->info_level = si->info_level;
8955                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8956                 COUNT_BYTES_TRANS(2);
8957                 
8958                 /* 4 reserved bytes */
8959                 CHECK_BYTE_COUNT_TRANS(4);
8960                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
8961                 COUNT_BYTES_TRANS(4);
8962
8963                 /* file name */
8964                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8965                 CHECK_STRING_TRANS(fn);
8966                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8967                         fn);
8968                 COUNT_BYTES_TRANS(fn_len);
8969
8970                 if (check_col(pinfo->cinfo, COL_INFO)) {
8971                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8972                         fn);
8973                 }
8974
8975                 break;
8976         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
8977                 guint16 fid;
8978
8979                 /* fid */
8980                 CHECK_BYTE_COUNT_TRANS(2);
8981                 fid = tvb_get_letohs(tvb, offset);
8982                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8983                 COUNT_BYTES_TRANS(2);
8984
8985                 /* level of interest */
8986                 CHECK_BYTE_COUNT_TRANS(2);
8987                 si->info_level = tvb_get_letohs(tvb, offset);
8988                 if (!pinfo->fd->flags.visited)
8989                         t2i->info_level = si->info_level;
8990                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8991                 COUNT_BYTES_TRANS(2);
8992                 
8993                 break;
8994         }
8995         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
8996                 guint16 fid;
8997
8998                 /* fid */
8999                 CHECK_BYTE_COUNT_TRANS(2);
9000                 fid = tvb_get_letohs(tvb, offset);
9001                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9002                 COUNT_BYTES_TRANS(2);
9003
9004                 /* level of interest */
9005                 CHECK_BYTE_COUNT_TRANS(2);
9006                 si->info_level = tvb_get_letohs(tvb, offset);
9007                 if (!pinfo->fd->flags.visited)
9008                         t2i->info_level = si->info_level;
9009                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9010                 COUNT_BYTES_TRANS(2);
9011                 
9012                 /* 2 reserved bytes */
9013                 CHECK_BYTE_COUNT_TRANS(2);
9014                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9015                 COUNT_BYTES_TRANS(2);
9016
9017                 break;
9018         }
9019         case 0x09:      /*TRANS2_FSCTL*/
9020         case 0x0a:      /*TRANS2_IOCTL2*/
9021                 /* these calls have no parameter block in the request */
9022                 break;
9023         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
9024         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
9025                 /* XXX unknown structure*/
9026                 break;
9027         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9028                 /* 4 reserved bytes */
9029                 CHECK_BYTE_COUNT_TRANS(4);
9030                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9031                 COUNT_BYTES_TRANS(4);
9032
9033                 /* dir name */
9034                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
9035                         FALSE, FALSE, &bc);
9036                 CHECK_STRING_TRANS(fn);
9037                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9038                         fn);
9039                 COUNT_BYTES_TRANS(fn_len);
9040
9041                 if (check_col(pinfo->cinfo, COL_INFO)) {
9042                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9043                         fn);
9044                 }
9045
9046                 /* XXX optional FEAList, unknown what FEAList looks like*/
9047                 break;
9048         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9049                 /* XXX unknown structure*/
9050                 break;
9051         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9052                 /* referral level */
9053                 CHECK_BYTE_COUNT_TRANS(2);
9054                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9055                 COUNT_BYTES_TRANS(2);
9056                 
9057                 /* file name */
9058                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9059                 CHECK_STRING_TRANS(fn);
9060                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9061                         fn);
9062                 COUNT_BYTES_TRANS(fn_len);
9063
9064                 if (check_col(pinfo->cinfo, COL_INFO)) {
9065                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9066                         fn);
9067                 }
9068
9069                 break;
9070         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9071                 /* file name */
9072                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9073                 CHECK_STRING_TRANS(fn);
9074                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9075                         fn);
9076                 COUNT_BYTES_TRANS(fn_len);
9077
9078                 if (check_col(pinfo->cinfo, COL_INFO)) {
9079                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9080                         fn);
9081                 }
9082
9083                 break;
9084         }
9085
9086         /* ooops there were data we didnt know how to process */
9087         if((offset-old_offset) < bc){
9088                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9089                     bc - (offset-old_offset), TRUE);
9090                 offset += bc - (offset-old_offset);
9091         }
9092
9093         return offset;
9094 }
9095
9096 /*
9097  * XXX - just use "dissect_connect_flags()" here?
9098  */
9099 static guint16
9100 dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9101 {
9102         guint16 mask;
9103         proto_item *item = NULL;
9104         proto_tree *tree = NULL;
9105
9106         mask = tvb_get_letohs(tvb, offset);
9107
9108         if(parent_tree){
9109                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9110                         "Flags: 0x%04x", mask);
9111                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9112         }
9113
9114         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9115                 tvb, offset, 2, mask);
9116         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9117                 tvb, offset, 2, mask);
9118
9119         return mask;
9120 }
9121  
9122
9123 static int
9124 dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9125 {
9126         guint16 mask;
9127         proto_item *item = NULL;
9128         proto_tree *tree = NULL;
9129
9130         mask = tvb_get_letohs(tvb, offset);
9131
9132         if(parent_tree){
9133                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9134                         "Flags: 0x%04x", mask);
9135                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9136         }
9137
9138         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9139                 tvb, offset, 2, mask);
9140         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9141                 tvb, offset, 2, mask);
9142
9143         offset += 2;
9144         return offset;
9145 }
9146
9147 static int
9148 dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9149 {
9150         guint16 mask;
9151         proto_item *item = NULL;
9152         proto_tree *tree = NULL;
9153
9154         mask = tvb_get_letohs(tvb, offset);
9155
9156         if(parent_tree){
9157                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9158                         "Flags: 0x%04x", mask);
9159                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9160         }
9161
9162         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9163                 tvb, offset, 2, mask);
9164
9165         offset += 2;
9166
9167         return offset;
9168 }
9169
9170
9171 /* dfs inconsistency data  (4.4.2)
9172 */
9173 static int
9174 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9175     proto_tree *tree, int offset, guint16 *bcp)
9176 {
9177         int fn_len;
9178         const char *fn;
9179
9180         /*XXX shouldn this data hold version and size? unclear from doc*/
9181         /* referral version */
9182         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9183         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9184         COUNT_BYTES_TRANS_SUBR(2);
9185
9186         /* referral size */
9187         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9188         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9189         COUNT_BYTES_TRANS_SUBR(2);
9190
9191         /* referral server type */
9192         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9193         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9194         COUNT_BYTES_TRANS_SUBR(2);
9195
9196         /* referral flags */
9197         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9198         offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
9199         *bcp -= 2;
9200
9201         /* node name */
9202         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9203         CHECK_STRING_TRANS_SUBR(fn);
9204         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9205                 fn);
9206         COUNT_BYTES_TRANS_SUBR(fn_len);
9207
9208         return offset;
9209 }
9210
9211 /* get dfs referral data  (4.4.1)
9212 */
9213 static int
9214 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9215     proto_tree *tree, int offset, guint16 *bcp)
9216 {
9217         guint16 numref;
9218         guint16 refsize;
9219         guint16 pathoffset;
9220         guint16 altpathoffset;
9221         guint16 nodeoffset;
9222         int fn_len;
9223         int stroffset;
9224         int offsetoffset;
9225         guint16 save_bc;
9226         const char *fn;
9227         int unklen;
9228         int ucstring_end;
9229         int ucstring_len;
9230
9231         /* path consumed */
9232         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9233         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9234         COUNT_BYTES_TRANS_SUBR(2);
9235
9236         /* num referrals */
9237         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9238         numref = tvb_get_letohs(tvb, offset);
9239         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9240         COUNT_BYTES_TRANS_SUBR(2);
9241
9242         /* get dfs flags */
9243         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9244         offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
9245         *bcp -= 2;
9246
9247         /* XXX - in at least one capture there appears to be 2 bytes
9248            of stuff after the Dfs flags, perhaps so that the header
9249            in front of the referral list is a multiple of 4 bytes long. */
9250         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9251         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9252         COUNT_BYTES_TRANS_SUBR(2);
9253
9254         /* if there are any referrals */
9255         if(numref){
9256                 proto_item *ref_item = NULL;
9257                 proto_tree *ref_tree = NULL;
9258                 int old_offset=offset;
9259
9260                 if(tree){
9261                         ref_item = proto_tree_add_text(tree,
9262                                 tvb, offset, *bcp, "Referrals");
9263                         ref_tree = proto_item_add_subtree(ref_item,
9264                                 ett_smb_dfs_referrals);
9265                 }
9266                 ucstring_end = -1;
9267
9268                 while(numref--){
9269                         proto_item *ri = NULL;
9270                         proto_tree *rt = NULL;
9271                         int old_offset=offset;
9272                         guint16 version;
9273
9274                         if(tree){
9275                                 ri = proto_tree_add_text(ref_tree,
9276                                         tvb, offset, *bcp, "Referral");
9277                                 rt = proto_item_add_subtree(ri,
9278                                         ett_smb_dfs_referral);
9279                         }
9280                 
9281                         /* referral version */
9282                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9283                         version = tvb_get_letohs(tvb, offset);
9284                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9285                                 tvb, offset, 2, version);
9286                         COUNT_BYTES_TRANS_SUBR(2);
9287
9288                         /* referral size */
9289                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9290                         refsize = tvb_get_letohs(tvb, offset);
9291                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9292                         COUNT_BYTES_TRANS_SUBR(2);
9293
9294                         /* referral server type */
9295                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9296                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9297                         COUNT_BYTES_TRANS_SUBR(2);
9298
9299                         /* referral flags */
9300                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9301                         offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
9302                         *bcp -= 2;
9303
9304                         switch(version){
9305
9306                         case 1:
9307                                 /* node name */
9308                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9309                                 CHECK_STRING_TRANS_SUBR(fn);
9310                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9311                                         fn);
9312                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9313                                 break;
9314
9315                         case 2:
9316                         case 3: /* XXX - like version 2, but not identical;
9317                                    seen in a capture, but the format isn't
9318                                    documented */
9319                                 /* proximity */
9320                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9321                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9322                                 COUNT_BYTES_TRANS_SUBR(2);
9323
9324                                 /* ttl */
9325                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9326                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9327                                 COUNT_BYTES_TRANS_SUBR(2);
9328
9329                                 /* path offset */
9330                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9331                                 pathoffset = tvb_get_letohs(tvb, offset);
9332                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9333                                 COUNT_BYTES_TRANS_SUBR(2);
9334
9335                                 /* alt path offset */
9336                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9337                                 altpathoffset = tvb_get_letohs(tvb, offset);
9338                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
9339                                 COUNT_BYTES_TRANS_SUBR(2);
9340
9341                                 /* node offset */
9342                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9343                                 nodeoffset = tvb_get_letohs(tvb, offset);
9344                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
9345                                 COUNT_BYTES_TRANS_SUBR(2);
9346
9347                                 /* path */
9348                                 if (pathoffset != 0) {
9349                                         stroffset = old_offset + pathoffset;
9350                                         offsetoffset = stroffset - offset;
9351                                         if (offsetoffset > 0 &&
9352                                             *bcp > offsetoffset) {
9353                                                 save_bc = *bcp;
9354                                                 *bcp -= offsetoffset;
9355                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9356                                                 CHECK_STRING_TRANS_SUBR(fn);
9357                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
9358                                                         fn);
9359                                                 stroffset += fn_len;
9360                                                 if (ucstring_end < stroffset)
9361                                                         ucstring_end = stroffset;
9362                                                 *bcp = save_bc;
9363                                         }
9364                                 }
9365                         
9366                                 /* alt path */
9367                                 if (altpathoffset != 0) {
9368                                         stroffset = old_offset + altpathoffset;
9369                                         offsetoffset = stroffset - offset;
9370                                         if (offsetoffset > 0 &&
9371                                             *bcp > offsetoffset) {
9372                                                 save_bc = *bcp;
9373                                                 *bcp -= offsetoffset;
9374                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9375                                                 CHECK_STRING_TRANS_SUBR(fn);
9376                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
9377                                                         fn);
9378                                                 stroffset += fn_len;
9379                                                 if (ucstring_end < stroffset)
9380                                                         ucstring_end = stroffset;
9381                                                 *bcp = save_bc;
9382                                         }
9383                                 }
9384                         
9385                                 /* node */
9386                                 if (nodeoffset != 0) {
9387                                         stroffset = old_offset + nodeoffset;
9388                                         offsetoffset = stroffset - offset;
9389                                         if (offsetoffset > 0 &&
9390                                             *bcp > offsetoffset) {
9391                                                 save_bc = *bcp;
9392                                                 *bcp -= offsetoffset;
9393                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9394                                                 CHECK_STRING_TRANS_SUBR(fn);
9395                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
9396                                                         fn);
9397                                                 stroffset += fn_len;
9398                                                 if (ucstring_end < stroffset)
9399                                                         ucstring_end = stroffset;
9400                                                 *bcp = save_bc;
9401                                         }
9402                                 }
9403                                 break;
9404                         }
9405
9406                         /*
9407                          * Show anything beyond the length of the referral
9408                          * as unknown data.
9409                          */
9410                         unklen = (old_offset + refsize) - offset;
9411                         if (unklen < 0) {
9412                                 /*
9413                                  * XXX - the length is bogus.
9414                                  */
9415                                 unklen = 0;
9416                         }
9417                         if (unklen != 0) {
9418                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
9419                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
9420                                     offset, unklen, TRUE);
9421                                 COUNT_BYTES_TRANS_SUBR(unklen);
9422                         }
9423
9424                         proto_item_set_len(ri, offset-old_offset);
9425                 }
9426
9427                 /*
9428                  * Treat the offset past the end of the last Unicode
9429                  * string after the referrals (if any) as the last
9430                  * offset.
9431                  */
9432                 if (ucstring_end > offset) {
9433                         ucstring_len = ucstring_end - offset;
9434                         if (*bcp < ucstring_len)
9435                                 ucstring_len = *bcp;
9436                         offset += ucstring_len;
9437                         *bcp -= ucstring_len;
9438                 }
9439                 proto_item_set_len(ref_item, offset-old_offset);
9440         }
9441
9442         return offset;
9443 }
9444
9445
9446 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
9447    as described in 4.2.14.1
9448 */
9449 static int
9450 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9451     int offset, guint16 *bcp, gboolean *trunc)
9452 {
9453         /* create time */
9454         CHECK_BYTE_COUNT_SUBR(4);
9455         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9456                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
9457                 FALSE);
9458         *bcp -= 4;
9459
9460         /* access time */
9461         CHECK_BYTE_COUNT_SUBR(4);
9462         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9463                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
9464                 FALSE);
9465         *bcp -= 4;
9466
9467         /* last write time */
9468         CHECK_BYTE_COUNT_SUBR(4);
9469         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9470                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
9471                 FALSE);
9472         *bcp -= 4;
9473
9474         /* data size */
9475         CHECK_BYTE_COUNT_SUBR(4);
9476         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9477         COUNT_BYTES_SUBR(4);
9478
9479         /* allocation size */
9480         CHECK_BYTE_COUNT_SUBR(4);
9481         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9482         COUNT_BYTES_SUBR(4);
9483
9484         /* File Attributes */
9485         CHECK_BYTE_COUNT_SUBR(2);
9486         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9487         *bcp -= 2;
9488
9489         /* ea size */
9490         CHECK_BYTE_COUNT_SUBR(4);
9491         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9492         COUNT_BYTES_SUBR(4);
9493
9494         *trunc = FALSE;
9495         return offset;
9496 }
9497
9498 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
9499    as described in 4.2.14.2
9500 */
9501 static int
9502 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9503     int offset, guint16 *bcp, gboolean *trunc)
9504 {
9505         /* list length */
9506         CHECK_BYTE_COUNT_SUBR(4);
9507         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
9508         COUNT_BYTES_SUBR(4);
9509
9510         *trunc = FALSE;
9511         return offset;
9512 }
9513
9514 /* this dissects the SMB_INFO_IS_NAME_VALID
9515    as described in 4.2.14.3
9516 */
9517 static int
9518 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9519     int offset, guint16 *bcp, gboolean *trunc)
9520 {
9521         int fn_len;
9522         const char *fn;
9523
9524         /* file name */
9525         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9526         CHECK_STRING_SUBR(fn);
9527         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9528                 fn);
9529         COUNT_BYTES_SUBR(fn_len);
9530
9531         *trunc = FALSE;
9532         return offset;
9533 }
9534
9535 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
9536    as described in 4.2.14.4
9537 */
9538 static int
9539 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9540     int offset, guint16 *bcp, gboolean *trunc)
9541 {
9542         /* create time */
9543         CHECK_BYTE_COUNT_SUBR(8);
9544         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9545                 hf_smb_create_time);
9546         *bcp -= 8;
9547         
9548         /* access time */
9549         CHECK_BYTE_COUNT_SUBR(8);
9550         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9551                 hf_smb_access_time);
9552         *bcp -= 8;
9553         
9554         /* last write time */
9555         CHECK_BYTE_COUNT_SUBR(8);
9556         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9557                 hf_smb_last_write_time);
9558         *bcp -= 8;
9559         
9560         /* last change time */
9561         CHECK_BYTE_COUNT_SUBR(8);
9562         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9563                 hf_smb_change_time);
9564         *bcp -= 8;
9565         
9566         /* File Attributes */
9567         CHECK_BYTE_COUNT_SUBR(2);
9568         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9569         *bcp -= 2;
9570
9571         *trunc = FALSE;
9572         return offset;
9573 }
9574
9575 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
9576    as described in 4.2.14.5
9577 */
9578 static int
9579 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9580     int offset, guint16 *bcp, gboolean *trunc)
9581 {
9582         /* allocation size */
9583         CHECK_BYTE_COUNT_SUBR(8);
9584         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9585         COUNT_BYTES_SUBR(8);
9586
9587         /* end of file */
9588         CHECK_BYTE_COUNT_SUBR(8);
9589         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9590         COUNT_BYTES_SUBR(8);
9591
9592         /* number of links */
9593         CHECK_BYTE_COUNT_SUBR(4);
9594         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
9595         COUNT_BYTES_SUBR(4);
9596
9597         /* delete pending */
9598         CHECK_BYTE_COUNT_SUBR(2);
9599         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
9600         COUNT_BYTES_SUBR(2);
9601
9602         /* is directory */
9603         CHECK_BYTE_COUNT_SUBR(1);
9604         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9605         COUNT_BYTES_SUBR(1);
9606
9607         *trunc = FALSE;
9608         return offset;
9609 }
9610
9611 /* this dissects the SMB_QUERY_FILE_EA_INFO
9612    as described in 4.2.14.6
9613 */
9614 static int
9615 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9616     int offset, guint16 *bcp, gboolean *trunc)
9617 {
9618         /* ea size */
9619         CHECK_BYTE_COUNT_SUBR(4);
9620         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9621         COUNT_BYTES_SUBR(4);
9622
9623         *trunc = FALSE;
9624         return offset;
9625 }
9626
9627 /* this dissects the SMB_QUERY_FILE_NAME_INFO
9628    as described in 4.2.14.7
9629    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
9630    as described in 4.2.14.9
9631 */
9632 static int
9633 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9634     int offset, guint16 *bcp, gboolean *trunc)
9635 {
9636         int fn_len;
9637         const char *fn;
9638
9639         /* file name len */
9640         CHECK_BYTE_COUNT_SUBR(4);
9641         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
9642         COUNT_BYTES_SUBR(4);
9643
9644         /* file name */
9645         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9646         CHECK_STRING_SUBR(fn);
9647         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9648                 fn);
9649         COUNT_BYTES_SUBR(fn_len);
9650
9651         *trunc = FALSE;
9652         return offset;
9653 }
9654
9655 /* this dissects the SMB_QUERY_FILE_ALL_INFO
9656    as described in 4.2.14.8
9657 */
9658 static int
9659 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9660     int offset, guint16 *bcp, gboolean *trunc)
9661 {
9662
9663         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
9664         if (trunc)
9665                 return offset;
9666         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
9667         if (trunc)
9668                 return offset;
9669
9670         /* index number */
9671         CHECK_BYTE_COUNT_SUBR(8);
9672         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9673         COUNT_BYTES_SUBR(8);
9674
9675         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9676         if (trunc)
9677                 return offset;
9678
9679         /* access flags */
9680         CHECK_BYTE_COUNT_SUBR(4);
9681         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
9682         COUNT_BYTES_SUBR(4);
9683
9684         /* index number */
9685         CHECK_BYTE_COUNT_SUBR(8);
9686         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9687         COUNT_BYTES_SUBR(8);
9688
9689         /* current offset */
9690         CHECK_BYTE_COUNT_SUBR(8);
9691         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
9692         COUNT_BYTES_SUBR(8);
9693
9694         /* mode */
9695         CHECK_BYTE_COUNT_SUBR(4);
9696         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
9697         *bcp -= 4;
9698
9699         /* alignment */
9700         CHECK_BYTE_COUNT_SUBR(4);
9701         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
9702         COUNT_BYTES_SUBR(4);
9703         
9704         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9705
9706         return offset;
9707 }
9708
9709 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
9710    as described in 4.2.14.10
9711 */
9712 static int
9713 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9714     int offset, guint16 *bcp, gboolean *trunc)
9715 {
9716         proto_item *item;
9717         proto_tree *tree;
9718         int old_offset;
9719         guint32 neo;
9720         int fn_len;
9721         const char *fn;
9722         int padcnt;
9723
9724         for (;;) {
9725                 old_offset = offset;
9726
9727                 /* next entry offset */
9728                 CHECK_BYTE_COUNT_SUBR(4);
9729                 if(parent_tree){
9730                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
9731                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9732                 } else {
9733                         item = NULL;
9734                         tree = NULL;
9735                 }
9736
9737                 neo = tvb_get_letohl(tvb, offset);
9738                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9739                 COUNT_BYTES_SUBR(4);
9740         
9741                 /* stream name len */
9742                 CHECK_BYTE_COUNT_SUBR(4);
9743                 fn_len = tvb_get_letohl(tvb, offset);
9744                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
9745                 COUNT_BYTES_SUBR(4);
9746         
9747                 /* stream size */
9748                 CHECK_BYTE_COUNT_SUBR(8);
9749                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
9750                 COUNT_BYTES_SUBR(8);
9751
9752                 /* allocation size */
9753                 CHECK_BYTE_COUNT_SUBR(8);
9754                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9755                 COUNT_BYTES_SUBR(8);
9756
9757                 /* stream name */
9758                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9759                 CHECK_STRING_SUBR(fn);
9760                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
9761                         fn);
9762                 COUNT_BYTES_SUBR(fn_len);
9763  
9764                 proto_item_append_text(item, ": %s", fn);
9765                 proto_item_set_len(item, offset-old_offset);
9766
9767                 if (neo == 0)
9768                         break;  /* no more structures */
9769
9770                 /* skip to next structure */
9771                 padcnt = (old_offset + neo) - offset;
9772                 if (padcnt < 0) {
9773                         /*
9774                          * XXX - this is bogus; flag it?
9775                          */
9776                         padcnt = 0;
9777                 }
9778                 if (padcnt != 0) {
9779                         CHECK_BYTE_COUNT_SUBR(padcnt);
9780                         COUNT_BYTES_SUBR(padcnt);
9781                 }
9782         }
9783
9784         *trunc = FALSE;
9785         return offset;
9786 }
9787
9788 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
9789    as described in 4.2.14.11
9790 */
9791 static int
9792 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9793     int offset, guint16 *bcp, gboolean *trunc)
9794 {
9795         /* compressed file size */
9796         CHECK_BYTE_COUNT_SUBR(8);
9797         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
9798         COUNT_BYTES_SUBR(8);
9799
9800         /* compression format */
9801         CHECK_BYTE_COUNT_SUBR(2);
9802         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
9803         COUNT_BYTES_SUBR(2);
9804         
9805         /* compression unit shift */
9806         CHECK_BYTE_COUNT_SUBR(1);
9807         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
9808         COUNT_BYTES_SUBR(1);
9809         
9810         /* compression chunk shift */
9811         CHECK_BYTE_COUNT_SUBR(1);
9812         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
9813         COUNT_BYTES_SUBR(1);
9814         
9815         /* compression cluster shift */
9816         CHECK_BYTE_COUNT_SUBR(1);
9817         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
9818         COUNT_BYTES_SUBR(1);
9819         
9820         /* 3 reserved bytes */
9821         CHECK_BYTE_COUNT_SUBR(3);
9822         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9823         COUNT_BYTES_SUBR(3);
9824
9825         *trunc = FALSE;
9826         return offset;
9827 }
9828
9829
9830
9831 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
9832 static int
9833 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
9834     int offset, guint16 *bcp)
9835 {
9836         smb_info_t *si;
9837         gboolean trunc;
9838
9839         if(!*bcp){
9840                 return offset;
9841         }
9842         
9843         si = (smb_info_t *)pinfo->private_data;
9844         switch(si->info_level){
9845         case 1:         /*Info Standard*/
9846         case 2:         /*Info Query EA Size*/
9847                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
9848                     &trunc);
9849                 break;
9850         case 3:         /*Info Query EAs From List*/
9851         case 4:         /*Info Query All EAs*/
9852                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
9853                     &trunc);
9854                 break;
9855         case 6:         /*Info Is Name Valid*/
9856                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
9857                     &trunc);
9858                 break;
9859         case 0x0101:    /*Query File Basic Info*/
9860                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
9861                     &trunc);
9862                 break;
9863         case 0x0102:    /*Query File Standard Info*/
9864                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
9865                     &trunc);
9866                 break;
9867         case 0x0103:    /*Query File EA Info*/
9868                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
9869                     &trunc);
9870                 break;
9871         case 0x0104:    /*Query File Name Info*/
9872                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9873                     &trunc);
9874                 break;
9875         case 0x0107:    /*Query File All Info*/
9876                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
9877                     &trunc);
9878                 break;
9879         case 0x0108:    /*Query File Alt File Info*/
9880                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9881                     &trunc);
9882                 break;
9883         case 0x0109:    /*Query File Stream Info*/
9884                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
9885                     &trunc);
9886                 break;
9887         case 0x010b:    /*Query File Compression Info*/
9888                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
9889                     &trunc);
9890                 break;
9891         case 0x0200:    /*Set File Unix Basic*/
9892                 /* XXX add this from the SNIA doc */
9893                 break;
9894         case 0x0201:    /*Set File Unix Link*/
9895                 /* XXX add this from the SNIA doc */
9896                 break;
9897         case 0x0202:    /*Set File Unix HardLink*/
9898                 /* XXX add this from the SNIA doc */
9899                 break;
9900         }
9901         
9902         return offset;
9903 }
9904
9905
9906 static const true_false_string tfs_quota_flags_deny_disk = {
9907         "DENY DISK SPACE for users exceeding quota limit",
9908         "Do NOT deny disk space for users exceeding quota limit"
9909 };
9910 static const true_false_string tfs_quota_flags_log_limit = {
9911         "LOG EVENT when a user exceeds their QUOTA LIMIT",
9912         "Do NOT log event when a user exceeds their quota limit"
9913 };
9914 static const true_false_string tfs_quota_flags_log_warning = {
9915         "LOG EVENT when a user exceeds their WARNING LEVEL",
9916         "Do NOT log event when a user exceeds their warning level"
9917 };
9918 static const true_false_string tfs_quota_flags_enabled = {
9919         "Quotas are ENABLED of this fs",
9920         "Quotas are NOT enabled on this fs"
9921 };
9922 static void
9923 dissect_quota_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9924 {
9925         guint8 mask;
9926         proto_item *item = NULL;
9927         proto_tree *tree = NULL;
9928
9929         mask = tvb_get_guint8(tvb, offset);
9930
9931         if(parent_tree){
9932                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
9933                         "Quota Flags: 0x%02x %s", mask,
9934                         mask?"Enabled":"Disabled");
9935                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
9936         }
9937
9938         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
9939                 tvb, offset, 1, mask);
9940         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
9941                 tvb, offset, 1, mask);
9942         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
9943                 tvb, offset, 1, mask);
9944
9945         if(mask && (!(mask&0x01))){
9946                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
9947                         tvb, offset, 1, 0x01);
9948         } else {
9949                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
9950                         tvb, offset, 1, mask);
9951         }
9952
9953 }
9954
9955 static int
9956 dissect_nt_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
9957 {
9958         /* first 24 bytes are unknown */
9959         CHECK_BYTE_COUNT_TRANS_SUBR(24);
9960         proto_tree_add_item(tree, hf_smb_unknown, tvb,
9961                     offset, 24, TRUE);
9962         COUNT_BYTES_TRANS_SUBR(24);
9963
9964         /* number of bytes for quota warning */
9965         CHECK_BYTE_COUNT_TRANS_SUBR(8);
9966         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
9967         COUNT_BYTES_TRANS_SUBR(8);
9968
9969         /* number of bytes for quota limit */
9970         CHECK_BYTE_COUNT_TRANS_SUBR(8);
9971         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
9972         COUNT_BYTES_TRANS_SUBR(8);
9973
9974         /* one byte of quota flags */
9975         CHECK_BYTE_COUNT_TRANS_SUBR(1);
9976         dissect_quota_flags(tvb, pinfo, tree, offset);
9977         COUNT_BYTES_TRANS_SUBR(1);
9978
9979         /* these 7 bytes are unknown */
9980         CHECK_BYTE_COUNT_TRANS_SUBR(7);
9981         proto_tree_add_item(tree, hf_smb_unknown, tvb,
9982                     offset, 7, TRUE);
9983         COUNT_BYTES_TRANS_SUBR(7);
9984
9985         return offset;
9986 }
9987
9988 static int
9989 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
9990     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
9991 {
9992         proto_item *item = NULL;
9993         proto_tree *tree = NULL;
9994         smb_info_t *si;
9995
9996         si = (smb_info_t *)pinfo->private_data;
9997
9998         if(parent_tree){
9999                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10000                                 "%s Data",
10001                                 val_to_str(subcmd, trans2_cmd_vals, 
10002                                                 "Unknown (0x%02x)"));
10003                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10004         }
10005
10006         switch(subcmd){
10007         case 0x00:      /*TRANS2_OPEN2*/
10008                 /* XXX FAEList here?*/
10009                 break;
10010         case 0x01:      /*TRANS2_FIND_FIRST2*/
10011                 /* XXX FAEList here?*/
10012                 break;
10013         case 0x02:      /*TRANS2_FIND_NEXT2*/
10014                 /* no data field in this request */
10015                 break;
10016         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10017                 /* no data field in this request */
10018                 break;
10019         case 0x04:      /* TRANS2_SET_QUOTA */
10020                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, &dc);
10021                 break;
10022         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10023                 /* no data field in this request */
10024                 break;
10025         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10026                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10027                 break;
10028         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10029                 /* no data field in this request */
10030                 break;
10031         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10032                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10033                 break;
10034         case 0x09:      /*TRANS2_FSCTL*/
10035                 /*XXX dont know how to decode this yet */
10036                 break;
10037         case 0x0a:      /*TRANS2_IOCTL2*/
10038                 /*XXX dont know how to decode this yet */
10039                 break;
10040         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10041                 /*XXX dont know how to decode this yet */
10042                 break;
10043         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10044                 /*XXX dont know how to decode this yet */
10045                 break;
10046         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10047                 /* no data block for this one */
10048                 break;
10049         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10050                 /*XXX dont know how to decode this yet */
10051                 break;
10052         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10053                 /* no data field in this request */
10054                 break;
10055         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10056                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10057                 break;
10058         }
10059
10060         /* ooops there were data we didnt know how to process */
10061         if(dc != 0){
10062                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10063                 offset += dc;
10064         }
10065
10066         return offset;
10067 }
10068
10069
10070 static void
10071 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10072     packet_info *pinfo, proto_tree *tree)
10073 {
10074         int i;
10075         int offset;
10076         guint length;
10077
10078         /*
10079          * Show the setup words.
10080          */
10081         if (s_tvb != NULL) {
10082                 length = tvb_reported_length(s_tvb);
10083                 for (i = 0, offset = 0; length >= 2;
10084                     i++, offset += 2, length -= 2) {
10085                         /*
10086                          * XXX - add a setup word filterable field?
10087                          */
10088                         proto_tree_add_text(tree, s_tvb, offset, 2,
10089                             "Setup Word %d: 0x%04x", i,
10090                             tvb_get_letohs(s_tvb, offset));
10091                 }
10092         }
10093
10094         /*
10095          * Show the parameters, if any.
10096          */
10097         if (p_tvb != NULL) {
10098                 length = tvb_reported_length(p_tvb);
10099                 if (length != 0) {
10100                         proto_tree_add_text(tree, p_tvb, 0, length,
10101                             "Parameters: %s",
10102                             tvb_bytes_to_str(p_tvb, 0, length));
10103                 }
10104         }
10105
10106         /*
10107          * Show the data, if any.
10108          */
10109         if (d_tvb != NULL) {
10110                 length = tvb_reported_length(d_tvb);
10111                 if (length != 0) {
10112                         proto_tree_add_text(tree, d_tvb, 0, length,
10113                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10114                 }
10115         }
10116 }
10117
10118 /* This routine handles the following 4 calls
10119    Transaction  0x25
10120    Transaction Secondary 0x26
10121    Transaction2 0x32
10122    Transaction2 Secondary 0x33
10123 */
10124 static int
10125 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
10126 {
10127         guint8 wc, sc=0;
10128         int so=offset;
10129         int sl=0;
10130         int spo=offset;
10131         int spc=0;
10132         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10133         int subcmd = -1;
10134         guint32 to;
10135         int an_len;
10136         const char *an = NULL;
10137         smb_info_t *si;
10138         smb_transact2_info_t *t2i;
10139         smb_transact_info_t *tri;
10140         guint16 bc;
10141         int padcnt;
10142         gboolean dissected_trans;
10143
10144         si = (smb_info_t *)pinfo->private_data;
10145
10146         WORD_COUNT;
10147
10148         if(wc==8){
10149                 /*secondary client request*/
10150
10151                 /* total param count, only a 16bit integer here*/
10152                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10153                 offset += 2;
10154         
10155                 /* total data count , only 16bit integer here*/
10156                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10157                 offset += 2;
10158
10159                 /* param count */
10160                 pc = tvb_get_letohs(tvb, offset);
10161                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10162                 offset += 2;
10163
10164                 /* param offset */
10165                 po = tvb_get_letohs(tvb, offset);
10166                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10167                 offset += 2;
10168
10169                 /* param disp */
10170                 pd = tvb_get_letohs(tvb, offset);
10171                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10172                 offset += 2;
10173         
10174                 /* data count */
10175                 dc = tvb_get_letohs(tvb, offset);
10176                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10177                 offset += 2;
10178
10179                 /* data offset */
10180                 od = tvb_get_letohs(tvb, offset);
10181                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10182                 offset += 2;
10183         
10184                 /* data disp */
10185                 dd = tvb_get_letohs(tvb, offset);
10186                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10187                 offset += 2;
10188
10189                 if(si->cmd==SMB_COM_TRANSACTION2){
10190                         guint16 fid;
10191
10192                         /* fid */
10193                         fid = tvb_get_letohs(tvb, offset);
10194                         add_fid(tvb, pinfo, tree, offset, 2, fid);
10195
10196                         offset += 2;
10197                 }
10198
10199                 /* There are no setup words. */
10200                 so = offset;
10201                 sc = 0;
10202                 sl = 0;
10203         } else {
10204                 /* it is not a secondary request */
10205
10206                 /* total param count , only a 16 bit integer here*/
10207                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10208                 offset += 2;
10209
10210                 /* total data count , only 16bit integer here*/
10211                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10212                 offset += 2;
10213
10214                 /* max param count , only 16bit integer here*/
10215                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10216                 offset += 2;
10217
10218                 /* max data count, only 16bit integer here*/
10219                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10220                 offset += 2;
10221
10222                 /* max setup count, only 16bit integer here*/
10223                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10224                 offset += 1;
10225
10226                 /* reserved byte */
10227                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10228                 offset += 1;
10229
10230                 /* transaction flags */
10231                 tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
10232                 offset += 2;
10233
10234                 /* timeout */
10235                 to = tvb_get_letohl(tvb, offset);
10236                 if (to == 0)
10237                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
10238                 else if (to == 0xffffffff)
10239                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
10240                 else
10241                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
10242                 offset += 4;
10243
10244                 /* 2 reserved bytes */
10245                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10246                 offset += 2;
10247
10248                 /* param count */
10249                 pc = tvb_get_letohs(tvb, offset);
10250                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10251                 offset += 2;
10252         
10253                 /* param offset */
10254                 po = tvb_get_letohs(tvb, offset);
10255                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10256                 offset += 2;
10257
10258                 /* param displacement is zero here */
10259                 pd = 0;
10260
10261                 /* data count */
10262                 dc = tvb_get_letohs(tvb, offset);
10263                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10264                 offset += 2;
10265
10266                 /* data offset */
10267                 od = tvb_get_letohs(tvb, offset);
10268                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10269                 offset += 2;
10270
10271                 /* data displacement is zero here */
10272                 dd = 0;
10273
10274                 /* setup count */
10275                 sc = tvb_get_guint8(tvb, offset);
10276                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10277                 offset += 1;
10278
10279                 /* reserved byte */
10280                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10281                 offset += 1;
10282                 
10283                 /* this is where the setup bytes, if any start */       
10284                 so = offset;
10285                 sl = sc*2;
10286
10287                 /* if there were any setup bytes, decode them */
10288                 if(sc){
10289                         switch(si->cmd){
10290
10291                         case SMB_COM_TRANSACTION2:
10292                                 /* TRANSACTION2 only has one setup word and
10293                                    that is the subcommand code. */
10294                                 subcmd = tvb_get_letohs(tvb, offset);
10295                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
10296                                     tvb, offset, 2, subcmd);
10297                                 if (check_col(pinfo->cinfo, COL_INFO)) {
10298                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10299                                             val_to_str(subcmd, trans2_cmd_vals, 
10300                                                 "Unknown (0x%02x)"));
10301                                 }
10302                                 if (!si->unidir) {
10303                                         if(!pinfo->fd->flags.visited){
10304                                                 /* 
10305                                                  * Allocate a new
10306                                                  * smb_transact2_info_t
10307                                                  * structure.
10308                                                  */
10309                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
10310                                                 t2i->subcmd = subcmd;
10311                                                 t2i->info_level = -1;
10312                                                 si->sip->extra_info = t2i;
10313                                         }
10314                                 }     
10315                                 break;
10316
10317                         case SMB_COM_TRANSACTION:
10318                                 /* TRANSACTION setup words processed below */
10319                                 break;
10320                         }
10321
10322                         offset += sl;
10323                 }
10324         }
10325
10326         BYTE_COUNT;
10327         
10328         if(wc!=8){
10329                 /* primary request */
10330                 /* name is NULL if transaction2 */
10331                 if(si->cmd == SMB_COM_TRANSACTION){
10332                         /* Transaction Name */
10333                         an = get_unicode_or_ascii_string(tvb, &offset,
10334                                 pinfo, &an_len, FALSE, FALSE, &bc);
10335                         if (an == NULL)
10336                                 goto endofcommand;
10337                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
10338                                 offset, an_len, an);
10339                         COUNT_BYTES(an_len);
10340                 }
10341         }
10342
10343         /*
10344          * The pipe or mailslot arguments for Transaction start with
10345          * the first setup word (or where the first setup word would
10346          * be if there were any setup words), and run to the current
10347          * offset (which could mean that there aren't any).
10348          */
10349         spo = so;
10350         spc = offset - spo;
10351
10352         /* parameters */
10353         if(po>offset){
10354                 /* We have some initial padding bytes.
10355                 */
10356                 padcnt = po-offset;
10357                 if (padcnt > bc)
10358                         padcnt = bc;
10359                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10360                 COUNT_BYTES(padcnt);
10361         }
10362         if(pc){
10363                 CHECK_BYTE_COUNT(pc);
10364                 switch(si->cmd) {
10365
10366                 case SMB_COM_TRANSACTION2:
10367                         /* TRANSACTION2 parameters*/
10368                         offset = dissect_transaction2_request_parameters(tvb,
10369                             pinfo, tree, offset, subcmd, pc);
10370                         bc -= pc;
10371                         break;
10372
10373                 case SMB_COM_TRANSACTION:
10374                         /* TRANSACTION parameters processed below */
10375                         COUNT_BYTES(pc);
10376                         break;
10377                 }
10378         }
10379
10380         /* data */
10381         if(od>offset){
10382                 /* We have some initial padding bytes.
10383                 */
10384                 padcnt = od-offset;
10385                 if (padcnt > bc)
10386                         padcnt = bc;
10387                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10388                 COUNT_BYTES(padcnt);
10389         }
10390         if(dc){
10391                 CHECK_BYTE_COUNT(dc);
10392                 switch(si->cmd){
10393
10394                 case SMB_COM_TRANSACTION2:
10395                         /* TRANSACTION2 data*/
10396                         offset = dissect_transaction2_request_data(tvb, pinfo,
10397                             tree, offset, subcmd, dc);
10398                         bc -= dc;
10399                         break;
10400
10401                 case SMB_COM_TRANSACTION:
10402                         /* TRANSACTION data processed below */
10403                         COUNT_BYTES(dc);
10404                         break;
10405                 }
10406         }
10407
10408         /*TRANSACTION request parameters */
10409         if(si->cmd==SMB_COM_TRANSACTION){
10410                 /*XXX replace this block with a function and use that one 
10411                      for both requests/responses*/
10412                 if(dd==0){
10413                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
10414                         tvbuff_t *sp_tvb, *pd_tvb;
10415
10416                         if(pc>0){
10417                                 if(pc>tvb_length_remaining(tvb, po)){
10418                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
10419                                 } else {
10420                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
10421                                 }
10422                         } else {
10423                                 p_tvb = NULL;
10424                         }
10425                         if(dc>0){
10426                                 if(dc>tvb_length_remaining(tvb, od)){
10427                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
10428                                 } else {
10429                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
10430                                 }
10431                         } else {
10432                                 d_tvb = NULL;
10433                         }
10434                         if(sl){
10435                                 if(sl>tvb_length_remaining(tvb, so)){
10436                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
10437                                 } else {
10438                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
10439                                 }
10440                         } else {
10441                                 s_tvb = NULL;
10442                         }
10443
10444                         if (!si->unidir) {
10445                                 if(!pinfo->fd->flags.visited){
10446                                         /* 
10447                                          * Allocate a new smb_transact_info_t
10448                                          * structure.
10449                                          */
10450                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
10451                                         tri->subcmd = -1;
10452                                         tri->trans_subcmd = -1;
10453                                         tri->function = -1;
10454                                         tri->fid = -1;
10455                                         tri->lanman_cmd = 0;
10456                                         tri->param_descrip = NULL;
10457                                         tri->data_descrip = NULL;
10458                                         tri->aux_data_descrip = NULL;
10459                                         tri->info_level = -1;
10460                                         si->sip->extra_info = tri;
10461                                 } else {
10462                                         /*
10463                                          * We already filled the structure
10464                                          * in; don't bother doing so again.
10465                                          */
10466                                         tri = NULL;
10467                                 }
10468                         } else {
10469                                 /*
10470                                  * This is a unidirectional message, for
10471                                  * which there will be no reply; don't
10472                                  * bother allocating an "smb_transact_info_t"
10473                                  * structure for it.
10474                                  */
10475                                 tri = NULL;
10476                         }
10477                         dissected_trans = FALSE;
10478                         if(strncmp("\\PIPE\\", an, 6) == 0){
10479                                 if (tri != NULL)
10480                                         tri->subcmd=TRANSACTION_PIPE;
10481
10482                                 /*
10483                                  * A tvbuff containing the setup words and
10484                                  * the pipe path.
10485                                  */
10486                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10487
10488                                 /*
10489                                  * A tvbuff containing the parameters and the
10490                                  * data.
10491                                  */
10492                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
10493
10494                                 dissected_trans = dissect_pipe_smb(sp_tvb,
10495                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
10496                                     top_tree);
10497                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
10498                                 if (tri != NULL)
10499                                         tri->subcmd=TRANSACTION_MAILSLOT;
10500
10501                                 /*
10502                                  * A tvbuff containing the setup words and
10503                                  * the mailslot path.
10504                                  */
10505                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10506                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
10507                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
10508                         }
10509                         if (!dissected_trans) {
10510                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
10511                                     pinfo, tree);
10512                         }
10513                 } else {
10514                         if(check_col(pinfo->cinfo, COL_INFO)){
10515                                 col_append_str(pinfo->cinfo, COL_INFO,
10516                                         "[transact continuation]");
10517                         }
10518                 }
10519         }
10520
10521         END_OF_SMB
10522
10523         return offset;
10524 }
10525
10526  
10527
10528 static int
10529 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10530     int offset, guint16 *bcp, gboolean *trunc)
10531 {
10532         int fn_len;
10533         const char *fn;
10534         int old_offset = offset;
10535         proto_item *item = NULL;
10536         proto_tree *tree = NULL;
10537         smb_info_t *si;
10538
10539         si = (smb_info_t *)pinfo->private_data;
10540
10541         if(parent_tree){
10542                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10543                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10544                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10545         }
10546
10547         /* create time */
10548         CHECK_BYTE_COUNT_SUBR(4);
10549         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10550                 hf_smb_create_time,
10551                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10552         *bcp -= 4;
10553
10554         /* access time */
10555         CHECK_BYTE_COUNT_SUBR(4);
10556         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10557                 hf_smb_access_time,
10558                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10559         *bcp -= 4;
10560
10561         /* last write time */
10562         CHECK_BYTE_COUNT_SUBR(4);
10563         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10564                 hf_smb_last_write_time,
10565                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10566         *bcp -= 4;
10567
10568         /* data size */
10569         CHECK_BYTE_COUNT_SUBR(4);
10570         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10571         COUNT_BYTES_SUBR(4);
10572
10573         /* allocation size */
10574         CHECK_BYTE_COUNT_SUBR(4);
10575         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10576         COUNT_BYTES_SUBR(4);
10577
10578         /* File Attributes */
10579         CHECK_BYTE_COUNT_SUBR(2);
10580         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10581         *bcp -= 2;
10582
10583         /* file name len */
10584         CHECK_BYTE_COUNT_SUBR(1);
10585         fn_len = tvb_get_guint8(tvb, offset);
10586         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10587         COUNT_BYTES_SUBR(1);
10588
10589         /* file name */
10590         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10591         CHECK_STRING_SUBR(fn);
10592         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10593                 fn);
10594         COUNT_BYTES_SUBR(fn_len);
10595
10596         if (check_col(pinfo->cinfo, COL_INFO)) {
10597                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10598                 fn);
10599         }
10600  
10601         proto_item_append_text(item, " File: %s", fn);
10602         proto_item_set_len(item, offset-old_offset);
10603
10604         *trunc = FALSE;
10605         return offset;
10606 }
10607
10608 static int
10609 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10610     int offset, guint16 *bcp, gboolean *trunc)
10611 {
10612         int fn_len;
10613         const char *fn;
10614         int old_offset = offset;
10615         proto_item *item = NULL;
10616         proto_tree *tree = NULL;
10617         smb_info_t *si;
10618
10619         si = (smb_info_t *)pinfo->private_data;
10620
10621         if(parent_tree){
10622                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10623                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10624                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10625         }
10626  
10627         /* create time */
10628         CHECK_BYTE_COUNT_SUBR(4);
10629         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10630                 hf_smb_create_time,
10631                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10632         *bcp -= 4;
10633
10634         /* access time */
10635         CHECK_BYTE_COUNT_SUBR(4);
10636         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10637                 hf_smb_access_time,
10638                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10639         *bcp -= 4;
10640
10641         /* last write time */
10642         CHECK_BYTE_COUNT_SUBR(4);
10643         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10644                 hf_smb_last_write_time,
10645                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10646         *bcp -= 4;
10647
10648         /* data size */
10649         CHECK_BYTE_COUNT_SUBR(4);
10650         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10651         COUNT_BYTES_SUBR(4);
10652
10653         /* allocation size */
10654         CHECK_BYTE_COUNT_SUBR(4);
10655         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10656         COUNT_BYTES_SUBR(4);
10657
10658         /* File Attributes */
10659         CHECK_BYTE_COUNT_SUBR(2);
10660         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10661         *bcp -= 2;
10662
10663         /* ea size */
10664         CHECK_BYTE_COUNT_SUBR(4);
10665         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10666         COUNT_BYTES_SUBR(4);
10667
10668         /* file name len */
10669         CHECK_BYTE_COUNT_SUBR(1);
10670         fn_len = tvb_get_guint8(tvb, offset);
10671         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10672         COUNT_BYTES_SUBR(1);
10673
10674         /* file name */
10675         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10676         CHECK_STRING_SUBR(fn);
10677         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10678                 fn);
10679         COUNT_BYTES_SUBR(fn_len);
10680
10681         if (check_col(pinfo->cinfo, COL_INFO)) {
10682                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10683                 fn);
10684         }
10685
10686         proto_item_append_text(item, " File: %s", fn);
10687         proto_item_set_len(item, offset-old_offset);
10688
10689         *trunc = FALSE;
10690         return offset;
10691 }
10692
10693 static int
10694 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10695     int offset, guint16 *bcp, gboolean *trunc)
10696 {
10697         int fn_len;
10698         const char *fn;
10699         int old_offset = offset;
10700         proto_item *item = NULL;
10701         proto_tree *tree = NULL;
10702         smb_info_t *si;
10703         guint32 neo;
10704         int padcnt;
10705
10706         si = (smb_info_t *)pinfo->private_data;
10707
10708         if(parent_tree){
10709                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10710                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10711                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10712         }
10713
10714         /* next entry offset */
10715         CHECK_BYTE_COUNT_SUBR(4);
10716         neo = tvb_get_letohl(tvb, offset);
10717         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10718         COUNT_BYTES_SUBR(4);
10719         
10720         /* file index */
10721         CHECK_BYTE_COUNT_SUBR(4);
10722         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10723         COUNT_BYTES_SUBR(4);
10724
10725         /* create time */
10726         CHECK_BYTE_COUNT_SUBR(8);
10727         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10728                 hf_smb_create_time);
10729         *bcp -= 8;
10730         
10731         /* access time */
10732         CHECK_BYTE_COUNT_SUBR(8);
10733         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10734                 hf_smb_access_time);
10735         *bcp -= 8;
10736         
10737         /* last write time */
10738         CHECK_BYTE_COUNT_SUBR(8);
10739         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10740                 hf_smb_last_write_time);
10741         *bcp -= 8;
10742         
10743         /* last change time */
10744         CHECK_BYTE_COUNT_SUBR(8);
10745         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10746                 hf_smb_change_time);
10747         *bcp -= 8;
10748         
10749         /* end of file */
10750         CHECK_BYTE_COUNT_SUBR(8);
10751         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10752         COUNT_BYTES_SUBR(8);
10753
10754         /* allocation size */
10755         CHECK_BYTE_COUNT_SUBR(8);
10756         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10757         COUNT_BYTES_SUBR(8);
10758
10759         /* Extended File Attributes */
10760         CHECK_BYTE_COUNT_SUBR(4);
10761         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10762         *bcp -= 4;
10763
10764         /* file name len */
10765         CHECK_BYTE_COUNT_SUBR(4);
10766         fn_len = tvb_get_letohl(tvb, offset);
10767         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10768         COUNT_BYTES_SUBR(4);
10769
10770         /* file name */
10771         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10772         CHECK_STRING_SUBR(fn);
10773         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10774                 fn);
10775         COUNT_BYTES_SUBR(fn_len);
10776
10777         if (check_col(pinfo->cinfo, COL_INFO)) {
10778                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10779                 fn);
10780         }
10781
10782         /* skip to next structure */
10783         if(neo){
10784                 padcnt = (old_offset + neo) - offset;
10785                 if (padcnt < 0) {
10786                         /*
10787                          * XXX - this is bogus; flag it?
10788                          */
10789                         padcnt = 0;
10790                 }
10791                 if (padcnt != 0) {
10792                         CHECK_BYTE_COUNT_SUBR(padcnt);
10793                         COUNT_BYTES_SUBR(padcnt);
10794                 }
10795         }
10796
10797         proto_item_append_text(item, " File: %s", fn);
10798         proto_item_set_len(item, offset-old_offset);
10799
10800         *trunc = FALSE;
10801         return offset;
10802 }
10803
10804 static int
10805 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10806     int offset, guint16 *bcp, gboolean *trunc)
10807 {
10808         int fn_len;
10809         const char *fn;
10810         int old_offset = offset;
10811         proto_item *item = NULL;
10812         proto_tree *tree = NULL;
10813         smb_info_t *si;
10814         guint32 neo;
10815         int padcnt;
10816
10817         si = (smb_info_t *)pinfo->private_data;
10818
10819         if(parent_tree){
10820                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10821                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10822                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10823         }
10824
10825         /* next entry offset */
10826         CHECK_BYTE_COUNT_SUBR(4);
10827         neo = tvb_get_letohl(tvb, offset);
10828         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10829         COUNT_BYTES_SUBR(4);
10830         
10831         /* file index */
10832         CHECK_BYTE_COUNT_SUBR(4);
10833         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10834         COUNT_BYTES_SUBR(4);
10835
10836         /* create time */
10837         CHECK_BYTE_COUNT_SUBR(8);
10838         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10839                 hf_smb_create_time);
10840         *bcp -= 8;
10841         
10842         /* access time */
10843         CHECK_BYTE_COUNT_SUBR(8);
10844         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10845                 hf_smb_access_time);
10846         *bcp -= 8;
10847         
10848         /* last write time */
10849         CHECK_BYTE_COUNT_SUBR(8);
10850         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10851                 hf_smb_last_write_time);
10852         *bcp -= 8;
10853         
10854         /* last change time */
10855         CHECK_BYTE_COUNT_SUBR(8);
10856         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10857                 hf_smb_change_time);
10858         *bcp -= 8;
10859         
10860         /* end of file */
10861         CHECK_BYTE_COUNT_SUBR(8);
10862         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10863         COUNT_BYTES_SUBR(8);
10864
10865         /* allocation size */
10866         CHECK_BYTE_COUNT_SUBR(8);
10867         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10868         COUNT_BYTES_SUBR(8);
10869
10870         /* Extended File Attributes */
10871         CHECK_BYTE_COUNT_SUBR(4);
10872         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10873         *bcp -= 4;
10874
10875         /* file name len */
10876         CHECK_BYTE_COUNT_SUBR(4);
10877         fn_len = tvb_get_letohl(tvb, offset);
10878         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10879         COUNT_BYTES_SUBR(4);
10880
10881         /* ea size */
10882         CHECK_BYTE_COUNT_SUBR(4);
10883         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10884         COUNT_BYTES_SUBR(4);
10885
10886         /* file name */
10887         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10888         CHECK_STRING_SUBR(fn);
10889         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10890                 fn);
10891         COUNT_BYTES_SUBR(fn_len);
10892
10893         if (check_col(pinfo->cinfo, COL_INFO)) {
10894                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10895                 fn);
10896         }
10897
10898         /* skip to next structure */
10899         if(neo){
10900                 padcnt = (old_offset + neo) - offset;
10901                 if (padcnt < 0) {
10902                         /*
10903                          * XXX - this is bogus; flag it?
10904                          */
10905                         padcnt = 0;
10906                 }
10907                 if (padcnt != 0) {
10908                         CHECK_BYTE_COUNT_SUBR(padcnt);
10909                         COUNT_BYTES_SUBR(padcnt);
10910                 }
10911         }
10912
10913         proto_item_append_text(item, " File: %s", fn);
10914         proto_item_set_len(item, offset-old_offset);
10915
10916         *trunc = FALSE;
10917         return offset;
10918 }
10919
10920 static int
10921 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10922     int offset, guint16 *bcp, gboolean *trunc)
10923 {
10924         int fn_len, sfn_len;
10925         const char *fn, *sfn;
10926         int old_offset = offset;
10927         proto_item *item = NULL;
10928         proto_tree *tree = NULL;
10929         smb_info_t *si;
10930         guint32 neo;
10931         int padcnt;
10932
10933         si = (smb_info_t *)pinfo->private_data;
10934
10935         if(parent_tree){
10936                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10937                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10938                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10939         }
10940
10941         /* next entry offset */
10942         CHECK_BYTE_COUNT_SUBR(4);
10943         neo = tvb_get_letohl(tvb, offset);
10944         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10945         COUNT_BYTES_SUBR(4);
10946         
10947         /* file index */
10948         CHECK_BYTE_COUNT_SUBR(4);
10949         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10950         COUNT_BYTES_SUBR(4);
10951
10952         /* create time */
10953         CHECK_BYTE_COUNT_SUBR(8);
10954         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10955                 hf_smb_create_time);
10956         *bcp -= 8;
10957         
10958         /* access time */
10959         CHECK_BYTE_COUNT_SUBR(8);
10960         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10961                 hf_smb_access_time);
10962         *bcp -= 8;
10963         
10964         /* last write time */
10965         CHECK_BYTE_COUNT_SUBR(8);
10966         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10967                 hf_smb_last_write_time);
10968         *bcp -= 8;
10969         
10970         /* last change time */
10971         CHECK_BYTE_COUNT_SUBR(8);
10972         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10973                 hf_smb_change_time);
10974         *bcp -= 8;
10975         
10976         /* end of file */
10977         CHECK_BYTE_COUNT_SUBR(8);
10978         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10979         COUNT_BYTES_SUBR(8);
10980
10981         /* allocation size */
10982         CHECK_BYTE_COUNT_SUBR(8);
10983         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10984         COUNT_BYTES_SUBR(8);
10985
10986         /* Extended File Attributes */
10987         CHECK_BYTE_COUNT_SUBR(4);
10988         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10989         *bcp -= 4;
10990
10991         /* file name len */
10992         CHECK_BYTE_COUNT_SUBR(4);
10993         fn_len = tvb_get_letohl(tvb, offset);
10994         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10995         COUNT_BYTES_SUBR(4);
10996
10997         /* ea size */
10998         CHECK_BYTE_COUNT_SUBR(4);
10999         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11000         COUNT_BYTES_SUBR(4);
11001
11002         /* short file name len */
11003         CHECK_BYTE_COUNT_SUBR(1);
11004         sfn_len = tvb_get_guint8(tvb, offset);
11005         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11006         COUNT_BYTES_SUBR(1);
11007
11008         /* reserved byte */
11009         CHECK_BYTE_COUNT_SUBR(1);
11010         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11011         COUNT_BYTES_SUBR(1);
11012  
11013         /* short file name */
11014         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
11015         CHECK_STRING_SUBR(sfn);
11016         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11017                 sfn);
11018         COUNT_BYTES_SUBR(24);
11019
11020         /* file name */
11021         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11022         CHECK_STRING_SUBR(fn);
11023         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11024                 fn);
11025         COUNT_BYTES_SUBR(fn_len);
11026
11027         if (check_col(pinfo->cinfo, COL_INFO)) {
11028                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11029                 fn);
11030         }
11031
11032         /* skip to next structure */
11033         if(neo){
11034                 padcnt = (old_offset + neo) - offset;
11035                 if (padcnt < 0) {
11036                         /*
11037                          * XXX - this is bogus; flag it?
11038                          */
11039                         padcnt = 0;
11040                 }
11041                 if (padcnt != 0) {
11042                         CHECK_BYTE_COUNT_SUBR(padcnt);
11043                         COUNT_BYTES_SUBR(padcnt);
11044                 }
11045         }
11046
11047         proto_item_append_text(item, " File: %s", fn);
11048         proto_item_set_len(item, offset-old_offset);
11049
11050         *trunc = FALSE;
11051         return offset;
11052 }
11053
11054 static int
11055 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11056     int offset, guint16 *bcp, gboolean *trunc)
11057 {
11058         int fn_len;
11059         const char *fn;
11060         int old_offset = offset;
11061         proto_item *item = NULL;
11062         proto_tree *tree = NULL;
11063         smb_info_t *si;
11064         guint32 neo;
11065         int padcnt;
11066
11067         si = (smb_info_t *)pinfo->private_data;
11068
11069         if(parent_tree){
11070                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11071                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11072                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11073         }
11074  
11075         /* next entry offset */
11076         CHECK_BYTE_COUNT_SUBR(4);
11077         neo = tvb_get_letohl(tvb, offset);
11078         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11079         COUNT_BYTES_SUBR(4);
11080         
11081         /* file index */
11082         CHECK_BYTE_COUNT_SUBR(4);
11083         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11084         COUNT_BYTES_SUBR(4);
11085
11086         /* file name len */
11087         CHECK_BYTE_COUNT_SUBR(4);
11088         fn_len = tvb_get_letohl(tvb, offset);
11089         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11090         COUNT_BYTES_SUBR(4);
11091
11092         /* file name */
11093         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11094         CHECK_STRING_SUBR(fn);
11095         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11096                 fn);
11097         COUNT_BYTES_SUBR(fn_len);
11098
11099         if (check_col(pinfo->cinfo, COL_INFO)) {
11100                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11101                 fn);
11102         }
11103
11104         /* skip to next structure */
11105         if(neo){
11106                 padcnt = (old_offset + neo) - offset;
11107                 if (padcnt < 0) {
11108                         /*
11109                          * XXX - this is bogus; flag it?
11110                          */
11111                         padcnt = 0;
11112                 }
11113                 if (padcnt != 0) {
11114                         CHECK_BYTE_COUNT_SUBR(padcnt);
11115                         COUNT_BYTES_SUBR(padcnt);
11116                 }
11117         }
11118
11119         proto_item_append_text(item, " File: %s", fn);
11120         proto_item_set_len(item, offset-old_offset);
11121
11122         *trunc = FALSE;
11123         return offset;
11124 }
11125  
11126 static int
11127 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11128     int offset, guint16 *bcp, gboolean *trunc)
11129 {
11130 /*XXX im lazy. i havnt implemented this */
11131         offset += *bcp;
11132         *bcp = 0;
11133         *trunc = FALSE;
11134         return offset;
11135 }
11136
11137 /*dissect the data block for TRANS2_FIND_FIRST2*/
11138 static int
11139 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
11140     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
11141 {
11142         smb_info_t *si;
11143
11144         if(!*bcp){
11145                 return offset;
11146         }
11147         
11148         si = (smb_info_t *)pinfo->private_data;
11149         switch(si->info_level){
11150         case 1:         /*Info Standard*/
11151                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
11152                     trunc);
11153                 break;
11154         case 2:         /*Info Query EA Size*/
11155                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11156                     trunc);
11157                 break;
11158         case 3:         /*Info Query EAs From List same as 
11159                                 InfoQueryEASize*/
11160                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11161                     trunc);
11162                 break;
11163         case 0x0101:    /*Find File Directory Info*/
11164                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
11165                     trunc);
11166                 break;
11167         case 0x0102:    /*Find File Full Directory Info*/
11168                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
11169                     trunc);
11170                 break;
11171         case 0x0103:    /*Find File Names Info*/
11172                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
11173                     trunc);
11174                 break;
11175         case 0x0104:    /*Find File Both Directory Info*/
11176                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
11177                     trunc);
11178                 break;
11179         case 0x0202:    /*Find File UNIX*/
11180                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
11181                     trunc);
11182                 break;
11183         default:        /* unknown info level */
11184                 *trunc = FALSE;
11185                 break;
11186         }
11187         return offset;
11188 }
11189
11190
11191 static int
11192 dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11193 {
11194         guint32 mask;
11195         proto_item *item = NULL;
11196         proto_tree *tree = NULL;
11197
11198         mask = tvb_get_letohl(tvb, offset);
11199
11200         if(parent_tree){
11201                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11202                         "FS Attributes: 0x%08x", mask);
11203                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
11204         }
11205
11206         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
11207                 tvb, offset, 4, mask);
11208         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
11209                 tvb, offset, 4, mask);
11210         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
11211                 tvb, offset, 4, mask);
11212         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
11213                 tvb, offset, 4, mask);
11214         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
11215                 tvb, offset, 4, mask);
11216         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
11217                 tvb, offset, 4, mask);
11218         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
11219                 tvb, offset, 4, mask);
11220
11221         offset += 4;
11222         return offset;
11223 }
11224  
11225
11226 static int
11227 dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11228 {
11229         guint32 mask;
11230         proto_item *item = NULL;
11231         proto_tree *tree = NULL;
11232
11233         mask = tvb_get_letohl(tvb, offset);
11234
11235         if(parent_tree){
11236                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11237                         "Device Characteristics: 0x%08x", mask);
11238                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
11239         }
11240
11241         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
11242                 tvb, offset, 4, mask);
11243         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
11244                 tvb, offset, 4, mask);
11245         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
11246                 tvb, offset, 4, mask);
11247         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
11248                 tvb, offset, 4, mask);
11249         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
11250                 tvb, offset, 4, mask);
11251         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
11252                 tvb, offset, 4, mask);
11253         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
11254                 tvb, offset, 4, mask);
11255
11256         offset += 4;
11257         return offset;
11258 }
11259
11260 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
11261 static int
11262 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11263     int offset, guint16 *bcp)
11264 {
11265         smb_info_t *si;
11266         int fn_len, vll, fnl;
11267         const char *fn;
11268
11269         if(!*bcp){
11270                 return offset;
11271         }
11272         
11273         si = (smb_info_t *)pinfo->private_data;
11274         switch(si->info_level){
11275         case 1:         /* SMB_INFO_ALLOCATION */
11276                 /* filesystem id */
11277                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11278                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
11279                 COUNT_BYTES_TRANS_SUBR(4);
11280
11281                 /* sectors per unit */
11282                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11283                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11284                 COUNT_BYTES_TRANS_SUBR(4);
11285
11286                 /* units */
11287                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11288                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
11289                 COUNT_BYTES_TRANS_SUBR(4);
11290
11291                 /* avail units */
11292                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11293                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
11294                 COUNT_BYTES_TRANS_SUBR(4);
11295
11296                 /* bytes per sector, only 16bit integer here */
11297                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11298                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11299                 COUNT_BYTES_TRANS_SUBR(2);
11300
11301                 break;
11302         case 2:         /* SMB_INFO_VOLUME */
11303                 /* volume serial number */
11304                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11305                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11306                 COUNT_BYTES_TRANS_SUBR(4);
11307
11308                 /* volume label length, only one byte here */
11309                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
11310                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11311                 COUNT_BYTES_TRANS_SUBR(1);
11312
11313                 /* label */
11314                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
11315                 CHECK_STRING_TRANS_SUBR(fn);
11316                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11317                         fn);
11318                 COUNT_BYTES_TRANS_SUBR(fn_len);
11319
11320                 break;
11321         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
11322                 /* create time */
11323                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11324                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11325                         hf_smb_create_time);
11326                 *bcp -= 8;
11327         
11328                 /* volume serial number */
11329                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11330                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11331                 COUNT_BYTES_TRANS_SUBR(4);
11332
11333                 /* volume label length */
11334                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11335                 vll = tvb_get_letohl(tvb, offset);
11336                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
11337                 COUNT_BYTES_TRANS_SUBR(4);
11338
11339                 /* 2 reserved bytes */
11340                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11341                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11342                 COUNT_BYTES_TRANS_SUBR(2);
11343
11344                 /* label */
11345                 fn_len = vll;
11346                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11347                 CHECK_STRING_TRANS_SUBR(fn);
11348                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11349                         fn);
11350                 COUNT_BYTES_TRANS_SUBR(fn_len);
11351
11352                 break;
11353         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
11354                 /* allocation size */
11355                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11356                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11357                 COUNT_BYTES_TRANS_SUBR(8);
11358
11359                 /* free allocation units */
11360                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11361                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
11362                 COUNT_BYTES_TRANS_SUBR(8);
11363
11364                 /* sectors per unit */
11365                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11366                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11367                 COUNT_BYTES_TRANS_SUBR(4);
11368
11369                 /* bytes per sector */
11370                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11371                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
11372                 COUNT_BYTES_TRANS_SUBR(4);
11373
11374                 break;
11375         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
11376                 /* device type */
11377                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11378                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
11379                 COUNT_BYTES_TRANS_SUBR(4);
11380  
11381                 /* device characteristics */
11382                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11383                 offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
11384                 *bcp -= 4;
11385         
11386                 break;
11387         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
11388                 /* FS attributes */
11389                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11390                 offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
11391                 *bcp -= 4;
11392         
11393                 /* max name len */
11394                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11395                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
11396                 COUNT_BYTES_TRANS_SUBR(4);
11397
11398                 /* fs name length */
11399                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11400                 fnl = tvb_get_letohl(tvb, offset);
11401                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
11402                 COUNT_BYTES_TRANS_SUBR(4);
11403
11404                 /* label */
11405                 fn_len = fnl;
11406                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11407                 CHECK_STRING_TRANS_SUBR(fn);
11408                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
11409                         fn);
11410                 COUNT_BYTES_TRANS_SUBR(fn_len);
11411
11412                 break;
11413         case 1006:      /* QUERY_FS_QUOTA_INFO */
11414                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, bcp);
11415         }
11416  
11417         return offset;
11418 }
11419  
11420 static int
11421 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
11422     proto_tree *parent_tree)
11423 {
11424         proto_item *item = NULL;
11425         proto_tree *tree = NULL;
11426         smb_info_t *si;
11427         smb_transact2_info_t *t2i;
11428         int count;
11429         gboolean trunc;
11430         int offset = 0;
11431         guint16 dc;
11432
11433         dc = tvb_reported_length(tvb);
11434
11435         si = (smb_info_t *)pinfo->private_data;
11436         if (si->sip != NULL)
11437                 t2i = si->sip->extra_info;
11438         else
11439                 t2i = NULL;
11440
11441         if(parent_tree){
11442                 if (t2i != NULL && t2i->subcmd != -1) {
11443                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11444                                 "%s Data",
11445                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11446                                         "Unknown (0x%02x)"));
11447                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11448                 } else {
11449                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11450                                 "Unknown Transaction2 Data");
11451                 }
11452         }
11453
11454         if (t2i == NULL) {
11455                 offset += dc;
11456                 return offset;
11457         }
11458         switch(t2i->subcmd){
11459         case 0x00:      /*TRANS2_OPEN2*/
11460                 /* XXX not implemented yet. See SNIA doc */
11461                 break;
11462         case 0x01:      /*TRANS2_FIND_FIRST2*/
11463                 /* returned data */
11464                 count = si->info_count;
11465
11466                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11467                         col_append_fstr(pinfo->cinfo, COL_INFO,
11468                         ", Files:");
11469                 }
11470
11471                 while(count--){
11472                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11473                                 offset, &dc, &trunc);
11474                         if (trunc)
11475                                 break;
11476                 }
11477                 break;
11478         case 0x02:      /*TRANS2_FIND_NEXT2*/
11479                 /* returned data */
11480                 count = si->info_count;
11481
11482                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11483                         col_append_fstr(pinfo->cinfo, COL_INFO,
11484                         ", Files:");
11485                 }
11486
11487                 while(count--){
11488                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11489                                 offset, &dc, &trunc);
11490                         if (trunc)
11491                                 break;
11492                 }
11493                 break;
11494         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11495                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
11496                 break;
11497         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11498                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11499                 break;
11500         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11501                 /* no data in this response */
11502                 break;
11503         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11504                 /* identical to QUERY_PATH_INFO */
11505                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11506                 break;
11507         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11508                 /* no data in this response */
11509                 break;
11510         case 0x09:      /*TRANS2_FSCTL*/
11511                 /* XXX dont know how to dissect this one (yet)*/
11512                 break;
11513         case 0x0a:      /*TRANS2_IOCTL2*/
11514                 /* XXX dont know how to dissect this one (yet)*/
11515                 break;
11516         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11517                 /* XXX dont know how to dissect this one (yet)*/
11518                 break;
11519         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11520                 /* XXX dont know how to dissect this one (yet)*/
11521                 break;
11522         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11523                 /* no data in this response */
11524                 break;
11525         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11526                 /* XXX dont know how to dissect this one (yet)*/
11527                 break;
11528         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11529                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
11530                 break;
11531         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11532                 /* the SNIA spec appears to say the response has no data */
11533                 break;
11534         case -1:
11535                 /*
11536                  * We don't know what the matching request was; don't
11537                  * bother putting anything else into the tree for the data.
11538                  */
11539                 offset += dc;
11540                 dc = 0;
11541                 break;
11542         }
11543
11544         /* ooops there were data we didnt know how to process */
11545         if(dc != 0){
11546                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11547                 offset += dc;
11548         }
11549
11550         return offset;
11551 }
11552
11553
11554 static void
11555 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
11556 {
11557         proto_item *item = NULL;
11558         proto_tree *tree = NULL;
11559         smb_info_t *si;
11560         smb_transact2_info_t *t2i;
11561         guint16 fid;
11562         int lno;
11563         int offset = 0;
11564         int pc;
11565
11566         pc = tvb_reported_length(tvb);
11567
11568         si = (smb_info_t *)pinfo->private_data;
11569         if (si->sip != NULL)
11570                 t2i = si->sip->extra_info;
11571         else
11572                 t2i = NULL;
11573
11574         if(parent_tree){
11575                 if (t2i != NULL && t2i->subcmd != -1) {
11576                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11577                                 "%s Parameters",
11578                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11579                                                 "Unknown (0x%02x)"));
11580                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
11581                 } else {
11582                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11583                                 "Unknown Transaction2 Parameters");
11584                 }
11585         }
11586
11587         if (t2i == NULL) {
11588                 offset += pc;
11589                 return;
11590         }
11591         switch(t2i->subcmd){
11592         case 0x00:      /*TRANS2_OPEN2*/
11593                 /* fid */
11594                 fid = tvb_get_letohs(tvb, offset);
11595                 add_fid(tvb, pinfo, tree, offset, 2, fid);
11596                 offset += 2;
11597
11598                 /* File Attributes */
11599                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
11600
11601                 /* create time */
11602                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
11603                         hf_smb_create_time, 
11604                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
11605
11606                 /* data size */
11607                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11608                 offset += 4;
11609
11610                 /* granted access */
11611                 offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
11612
11613                 /* File Type */
11614                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
11615                 offset += 2;
11616
11617                 /* IPC State */
11618                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
11619
11620                 /* open_action */
11621                 offset = dissect_open_action(tvb, pinfo, tree, offset);
11622
11623                 /* 4 reserved bytes */
11624                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
11625                 offset += 4;
11626
11627                 /* ea error offset, only a 16 bit integer here */
11628                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11629                 offset += 2;
11630
11631                 /* ea length */
11632                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
11633                 offset += 4;
11634
11635                 break;
11636         case 0x01:      /*TRANS2_FIND_FIRST2*/
11637                 /* Find First2 information level */
11638                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
11639
11640                 /* sid */
11641                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
11642                 offset += 2;
11643
11644                 /* search count */
11645                 si->info_count = tvb_get_letohs(tvb, offset);
11646                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11647                 offset += 2;
11648
11649                 /* end of search */
11650                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11651                 offset += 2;
11652
11653                 /* ea error offset, only a 16 bit integer here */
11654                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11655                 offset += 2;
11656
11657                 /* last name offset */
11658                 lno = tvb_get_letohs(tvb, offset);
11659                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11660                 offset += 2;
11661
11662                 break;
11663         case 0x02:      /*TRANS2_FIND_NEXT2*/
11664                 /* search count */
11665                 si->info_count = tvb_get_letohs(tvb, offset);
11666                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11667                 offset += 2;
11668
11669                 /* end of search */
11670                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11671                 offset += 2;
11672
11673                 /* ea error offset , only a 16 bit integer here*/
11674                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11675                 offset += 2;
11676
11677                 /* last name offset */
11678                 lno = tvb_get_letohs(tvb, offset);
11679                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11680                 offset += 2;
11681
11682                 break;
11683         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11684                 /* no parameter block here */
11685                 break;
11686         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11687                 /* no parameter block here */
11688                 break;
11689         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11690                 /* no parameter block here */
11691                 break;
11692         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11693                 /* no parameter block here */
11694                 break;
11695         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11696                 /* no parameter block here */
11697                 break;
11698         case 0x09:      /*TRANS2_FSCTL*/
11699                 /* XXX dont know how to dissect this one (yet)*/
11700                 break;
11701         case 0x0a:      /*TRANS2_IOCTL2*/
11702                 /* XXX dont know how to dissect this one (yet)*/
11703                 break;
11704         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11705                 /* XXX dont know how to dissect this one (yet)*/
11706                 break;
11707         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11708                 /* XXX dont know how to dissect this one (yet)*/
11709                 break;
11710         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11711                 /* ea error offset, only a 16 bit integer here */
11712                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11713                 offset += 2;
11714
11715                 break;
11716         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11717                 /* XXX dont know how to dissect this one (yet)*/
11718                 break;
11719         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11720                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11721                 break;
11722         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11723                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11724                 break;
11725         case -1:
11726                 /*
11727                  * We don't know what the matching request was; don't
11728                  * bother putting anything else into the tree for the data.
11729                  */
11730                 offset += pc;
11731                 break;
11732         }
11733
11734         /* ooops there were data we didnt know how to process */
11735         if(offset<pc){
11736                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
11737                 offset += pc-offset;
11738         }
11739 }
11740
11741
11742 static int
11743 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
11744 {
11745         guint8 sc, wc;
11746         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
11747         gboolean reassembled = FALSE;
11748         smb_info_t *si;
11749         smb_transact2_info_t *t2i = NULL;
11750         guint16 bc;
11751         int padcnt;
11752         gboolean dissected_trans;
11753         fragment_data *r_fd = NULL;
11754         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
11755         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
11756         gboolean save_fragmented;
11757
11758         si = (smb_info_t *)pinfo->private_data;
11759
11760         switch(si->cmd){
11761         case SMB_COM_TRANSACTION2:
11762                 /* transaction2 */
11763                 if (si->sip != NULL) {
11764                         t2i = si->sip->extra_info;
11765                 } else
11766                         t2i = NULL;
11767                 if (t2i == NULL) {
11768                         /*
11769                          * We didn't see the matching request, so we don't
11770                          * know what type of transaction this is.
11771                          */
11772                         proto_tree_add_text(tree, tvb, 0, 0,
11773                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
11774                         if (check_col(pinfo->cinfo, COL_INFO)) {
11775                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11776                         }
11777                 } else {
11778                         si->info_level = t2i->info_level;
11779                         if (t2i->subcmd == -1) {
11780                                 /*
11781                                  * We didn't manage to extract the subcommand
11782                                  * from the matching request (perhaps because
11783                                  * the frame was short), so we don't know what
11784                                  * type of transaction this is.
11785                                  */
11786                                 proto_tree_add_text(tree, tvb, 0, 0,
11787                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
11788                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11789                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11790                                 }
11791                         } else {
11792                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
11793                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11794                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11795                                                 val_to_str(t2i->subcmd,
11796                                                         trans2_cmd_vals, 
11797                                                         "<unknown (0x%02x)>"));
11798                                 }
11799                         }
11800                 }
11801                 break;
11802         }
11803
11804         WORD_COUNT;
11805
11806         /* total param count, only a 16bit integer here */
11807         tp = tvb_get_letohs(tvb, offset);
11808         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
11809         offset += 2;
11810
11811         /* total data count, only a 16 bit integer here */
11812         td = tvb_get_letohs(tvb, offset);
11813         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
11814         offset += 2;
11815
11816         /* 2 reserved bytes */
11817         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11818         offset += 2;
11819
11820         /* param count */
11821         pc = tvb_get_letohs(tvb, offset);
11822         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11823         offset += 2;
11824
11825         /* param offset */
11826         po = tvb_get_letohs(tvb, offset);
11827         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11828         offset += 2;
11829
11830         /* param disp */
11831         pd = tvb_get_letohs(tvb, offset);
11832         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11833         offset += 2;
11834
11835         /* data count */
11836         dc = tvb_get_letohs(tvb, offset);
11837         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11838         offset += 2;
11839
11840         /* data offset */
11841         od = tvb_get_letohs(tvb, offset);
11842         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11843         offset += 2;
11844
11845         /* data disp */
11846         dd = tvb_get_letohs(tvb, offset);
11847         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11848         offset += 2;
11849
11850         /* setup count */
11851         sc = tvb_get_guint8(tvb, offset);
11852         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11853         offset += 1;
11854
11855         /* reserved byte */
11856         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11857         offset += 1;
11858
11859
11860         /* if there were any setup bytes, put them in a tvb for later */
11861         if(sc){
11862                 if((2*sc)>tvb_length_remaining(tvb, offset)){
11863                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
11864                 } else {
11865                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
11866                 }
11867                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
11868         } else {
11869                 s_tvb = NULL;
11870                 sp_tvb=NULL;
11871         }
11872         offset += 2*sc;
11873
11874
11875         BYTE_COUNT;
11876
11877
11878         /* reassembly of SMB Transaction data payload.
11879            In this section we do reassembly of both the data and parameters
11880            blocks of the SMB transaction command.
11881         */
11882         save_fragmented = pinfo->fragmented;
11883         /* do we need reassembly? */
11884         if( (td!=dc) || (tp!=pc) ){
11885                 /* oh yeah, either data or parameter section needs 
11886                    reassembly
11887                 */
11888                 pinfo->fragmented = TRUE;
11889                 if(smb_trans_reassembly){
11890                         /* ...and we were told to do reassembly */
11891                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
11892                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11893                                                              po, pc, pd, td+tp);
11894                                 
11895                         }
11896                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
11897                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11898                                                              od, dc, dd+tp, td+tp);
11899                         }
11900                 }
11901         }
11902
11903         /* if we got a reassembled fd structure from the reassembly routine we must
11904            create pd_tvb from it 
11905         */
11906         if(r_fd){
11907                 proto_tree *tr;
11908                 proto_item *it;
11909                 fragment_data *fd;
11910
11911                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
11912                                              r_fd->datalen);
11913                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
11914                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
11915                 pinfo->fragmented = FALSE;
11916
11917                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
11918                 tr = proto_item_add_subtree(it, ett_smb_segments);
11919                 for(fd=r_fd->next;fd;fd=fd->next){
11920                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
11921                                             "Frame:%u Data:%u-%u",
11922                                             fd->frame, fd->offset,
11923                                             fd->offset+fd->len-1);
11924                 }
11925         }
11926
11927
11928         if(pd_tvb){
11929                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
11930                 if(tp){
11931                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
11932                 }
11933                 if(td){
11934                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
11935                 }
11936         } else {
11937                 /* It was not reassembled. Do as best as we can.
11938                  * in this case we always try to dissect the stuff if 
11939                  * data and param displacement is 0. i.e. for the first
11940                  * (and maybe only) packet.
11941                  */
11942                 if( (pd==0) && (dd==0) ){
11943                         int min;
11944                         int reported_min;
11945                         min = MIN(pc,tvb_length_remaining(tvb,po));
11946                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
11947                         if(min && reported_min) {
11948                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
11949                         }
11950                         min = MIN(dc,tvb_length_remaining(tvb,od));
11951                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
11952                         if(min && reported_min) {
11953                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
11954                         }
11955                         /*
11956                          * A tvbuff containing the parameters
11957                          * and the data.
11958                          * XXX - check pc and dc as well?
11959                          */
11960                         if (tvb_length_remaining(tvb, po)){
11961                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11962                         }
11963                 }
11964         }
11965
11966
11967
11968         /* parameters */
11969         if(po>offset){
11970                 /* We have some padding bytes.
11971                 */
11972                 padcnt = po-offset;
11973                 if (padcnt > bc)
11974                         padcnt = bc;
11975                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11976                 COUNT_BYTES(padcnt);
11977         }
11978         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
11979                 /* TRANSACTION2 parameters*/
11980                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
11981         }
11982         COUNT_BYTES(pc);
11983
11984
11985         /* data */
11986         if(od>offset){
11987                 /* We have some initial padding bytes.
11988                 */
11989                 padcnt = od-offset;
11990                 if (padcnt > bc)
11991                         padcnt = bc;
11992                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11993                 COUNT_BYTES(padcnt);
11994         }
11995         /*
11996          * If the data count is bigger than the count of bytes
11997          * remaining, clamp it so that the count of bytes remaining
11998          * doesn't go negative.
11999          */
12000         if (dc > bc)
12001                 dc = bc;
12002         COUNT_BYTES(dc);
12003
12004
12005
12006         /* from now on, everything is in separate tvbuffs so we dont count
12007            the bytes with COUNT_BYTES any more.
12008            neither do we reference offset any more (which by now points to the
12009            first byte AFTER this PDU */
12010
12011
12012         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
12013                 /* TRANSACTION2 parameters*/
12014                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
12015         }
12016
12017
12018         if(si->cmd==SMB_COM_TRANSACTION){
12019                 smb_transact_info_t *tri;
12020
12021                 dissected_trans = FALSE;
12022                 if (si->sip != NULL)
12023                         tri = si->sip->extra_info;
12024                 else
12025                         tri = NULL;
12026                 if (tri != NULL) {
12027                         switch(tri->subcmd){
12028
12029                         case TRANSACTION_PIPE:
12030                                 /* This function is safe to call for 
12031                                    s_tvb==sp_tvb==NULL, i.e. if we don't
12032                                    know them at this point.
12033                                    It's also safe to call if "p_tvb"
12034                                    or "d_tvb" are null.
12035                                 */
12036                                 if( pd_tvb) {
12037                                         dissected_trans = dissect_pipe_smb(
12038                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
12039                                                 d_tvb, NULL, pinfo, top_tree);
12040                                 }
12041                                 break;
12042                                 
12043                         case TRANSACTION_MAILSLOT:
12044                                 /* This one should be safe to call
12045                                    even if s_tvb and sp_tvb is NULL
12046                                 */
12047                                 if(d_tvb){
12048                                         dissected_trans = dissect_mailslot_smb(
12049                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
12050                                                 top_tree);
12051                                 }
12052                                 break;
12053                         }
12054                 }
12055                 if (!dissected_trans) {
12056                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
12057                         dissect_trans_data(s_tvb, p_tvb, d_tvb,
12058                                            pinfo, tree);
12059                 }
12060         }
12061
12062
12063         if( (p_tvb==0) && (d_tvb==0) ){
12064                 if(check_col(pinfo->cinfo, COL_INFO)){
12065                         col_append_str(pinfo->cinfo, COL_INFO,
12066                                        "[transact continuation]");
12067                 }
12068         }
12069
12070         pinfo->fragmented = save_fragmented;
12071         END_OF_SMB
12072
12073         return offset;
12074 }
12075
12076
12077 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12078    END Transaction/Transaction2 Primary and secondary requests
12079    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12080
12081
12082 static int
12083 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
12084 {
12085         guint8 wc;
12086         guint16 bc;
12087
12088         WORD_COUNT;
12089  
12090         if (wc != 0)
12091                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
12092
12093         BYTE_COUNT;
12094
12095         if (bc != 0)
12096                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
12097
12098         END_OF_SMB
12099
12100         return offset;
12101 }
12102
12103 typedef struct _smb_function {
12104        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12105        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12106 } smb_function;
12107
12108 static smb_function smb_dissector[256] = {
12109   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
12110   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
12111   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
12112   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
12113   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
12114   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
12115   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
12116   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
12117   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
12118   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
12119   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
12120   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
12121   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
12122   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
12123   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
12124   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
12125
12126   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
12127   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
12128   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
12129   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
12130   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
12131   /* 0x15 */  {dissect_unknown, dissect_unknown},
12132   /* 0x16 */  {dissect_unknown, dissect_unknown},
12133   /* 0x17 */  {dissect_unknown, dissect_unknown},
12134   /* 0x18 */  {dissect_unknown, dissect_unknown},
12135   /* 0x19 */  {dissect_unknown, dissect_unknown},
12136   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
12137   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
12138   /* 0x1c */  {dissect_unknown, dissect_unknown},
12139   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
12140   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
12141   /* 0x1f */  {dissect_unknown, dissect_unknown},
12142
12143   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
12144   /* 0x21 */  {dissect_unknown, dissect_unknown},
12145   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
12146   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
12147   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
12148   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
12149   /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12150   /* 0x27 */  {dissect_unknown, dissect_unknown},
12151   /* 0x28 */  {dissect_unknown, dissect_unknown},
12152   /* 0x29 */  {dissect_unknown, dissect_unknown},
12153   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
12154   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
12155   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
12156   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
12157   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
12158   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
12159
12160   /* 0x30 */  {dissect_unknown, dissect_unknown},
12161   /* 0x31 */  {dissect_unknown, dissect_unknown},
12162   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
12163   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12164   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
12165   /* 0x35 */  {dissect_unknown, dissect_unknown},
12166   /* 0x36 */  {dissect_unknown, dissect_unknown},
12167   /* 0x37 */  {dissect_unknown, dissect_unknown},
12168   /* 0x38 */  {dissect_unknown, dissect_unknown},
12169   /* 0x39 */  {dissect_unknown, dissect_unknown},
12170   /* 0x3a */  {dissect_unknown, dissect_unknown},
12171   /* 0x3b */  {dissect_unknown, dissect_unknown},
12172   /* 0x3c */  {dissect_unknown, dissect_unknown},
12173   /* 0x3d */  {dissect_unknown, dissect_unknown},
12174   /* 0x3e */  {dissect_unknown, dissect_unknown},
12175   /* 0x3f */  {dissect_unknown, dissect_unknown},
12176
12177   /* 0x40 */  {dissect_unknown, dissect_unknown},
12178   /* 0x41 */  {dissect_unknown, dissect_unknown},
12179   /* 0x42 */  {dissect_unknown, dissect_unknown},
12180   /* 0x43 */  {dissect_unknown, dissect_unknown},
12181   /* 0x44 */  {dissect_unknown, dissect_unknown},
12182   /* 0x45 */  {dissect_unknown, dissect_unknown},
12183   /* 0x46 */  {dissect_unknown, dissect_unknown},
12184   /* 0x47 */  {dissect_unknown, dissect_unknown},
12185   /* 0x48 */  {dissect_unknown, dissect_unknown},
12186   /* 0x49 */  {dissect_unknown, dissect_unknown},
12187   /* 0x4a */  {dissect_unknown, dissect_unknown},
12188   /* 0x4b */  {dissect_unknown, dissect_unknown},
12189   /* 0x4c */  {dissect_unknown, dissect_unknown},
12190   /* 0x4d */  {dissect_unknown, dissect_unknown},
12191   /* 0x4e */  {dissect_unknown, dissect_unknown},
12192   /* 0x4f */  {dissect_unknown, dissect_unknown},
12193
12194   /* 0x50 */  {dissect_unknown, dissect_unknown},
12195   /* 0x51 */  {dissect_unknown, dissect_unknown},
12196   /* 0x52 */  {dissect_unknown, dissect_unknown},
12197   /* 0x53 */  {dissect_unknown, dissect_unknown},
12198   /* 0x54 */  {dissect_unknown, dissect_unknown},
12199   /* 0x55 */  {dissect_unknown, dissect_unknown},
12200   /* 0x56 */  {dissect_unknown, dissect_unknown},
12201   /* 0x57 */  {dissect_unknown, dissect_unknown},
12202   /* 0x58 */  {dissect_unknown, dissect_unknown},
12203   /* 0x59 */  {dissect_unknown, dissect_unknown},
12204   /* 0x5a */  {dissect_unknown, dissect_unknown},
12205   /* 0x5b */  {dissect_unknown, dissect_unknown},
12206   /* 0x5c */  {dissect_unknown, dissect_unknown},
12207   /* 0x5d */  {dissect_unknown, dissect_unknown},
12208   /* 0x5e */  {dissect_unknown, dissect_unknown},
12209   /* 0x5f */  {dissect_unknown, dissect_unknown},
12210
12211   /* 0x60 */  {dissect_unknown, dissect_unknown},
12212   /* 0x61 */  {dissect_unknown, dissect_unknown},
12213   /* 0x62 */  {dissect_unknown, dissect_unknown},
12214   /* 0x63 */  {dissect_unknown, dissect_unknown},
12215   /* 0x64 */  {dissect_unknown, dissect_unknown},
12216   /* 0x65 */  {dissect_unknown, dissect_unknown},
12217   /* 0x66 */  {dissect_unknown, dissect_unknown},
12218   /* 0x67 */  {dissect_unknown, dissect_unknown},
12219   /* 0x68 */  {dissect_unknown, dissect_unknown},
12220   /* 0x69 */  {dissect_unknown, dissect_unknown},
12221   /* 0x6a */  {dissect_unknown, dissect_unknown},
12222   /* 0x6b */  {dissect_unknown, dissect_unknown},
12223   /* 0x6c */  {dissect_unknown, dissect_unknown},
12224   /* 0x6d */  {dissect_unknown, dissect_unknown},
12225   /* 0x6e */  {dissect_unknown, dissect_unknown},
12226   /* 0x6f */  {dissect_unknown, dissect_unknown},
12227
12228   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
12229   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
12230   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
12231   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
12232   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
12233   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
12234   /* 0x76 */  {dissect_unknown, dissect_unknown},
12235   /* 0x77 */  {dissect_unknown, dissect_unknown},
12236   /* 0x78 */  {dissect_unknown, dissect_unknown},
12237   /* 0x79 */  {dissect_unknown, dissect_unknown},
12238   /* 0x7a */  {dissect_unknown, dissect_unknown},
12239   /* 0x7b */  {dissect_unknown, dissect_unknown},
12240   /* 0x7c */  {dissect_unknown, dissect_unknown},
12241   /* 0x7d */  {dissect_unknown, dissect_unknown},
12242   /* 0x7e */  {dissect_unknown, dissect_unknown},
12243   /* 0x7f */  {dissect_unknown, dissect_unknown},
12244
12245   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
12246   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
12247   /* 0x82 */  {dissect_unknown, dissect_unknown},
12248   /* 0x83 */  {dissect_unknown, dissect_unknown},
12249   /* 0x84 */  {dissect_unknown, dissect_unknown},
12250   /* 0x85 */  {dissect_unknown, dissect_unknown},
12251   /* 0x86 */  {dissect_unknown, dissect_unknown},
12252   /* 0x87 */  {dissect_unknown, dissect_unknown},
12253   /* 0x88 */  {dissect_unknown, dissect_unknown},
12254   /* 0x89 */  {dissect_unknown, dissect_unknown},
12255   /* 0x8a */  {dissect_unknown, dissect_unknown},
12256   /* 0x8b */  {dissect_unknown, dissect_unknown},
12257   /* 0x8c */  {dissect_unknown, dissect_unknown},
12258   /* 0x8d */  {dissect_unknown, dissect_unknown},
12259   /* 0x8e */  {dissect_unknown, dissect_unknown},
12260   /* 0x8f */  {dissect_unknown, dissect_unknown},
12261
12262   /* 0x90 */  {dissect_unknown, dissect_unknown},
12263   /* 0x91 */  {dissect_unknown, dissect_unknown},
12264   /* 0x92 */  {dissect_unknown, dissect_unknown},
12265   /* 0x93 */  {dissect_unknown, dissect_unknown},
12266   /* 0x94 */  {dissect_unknown, dissect_unknown},
12267   /* 0x95 */  {dissect_unknown, dissect_unknown},
12268   /* 0x96 */  {dissect_unknown, dissect_unknown},
12269   /* 0x97 */  {dissect_unknown, dissect_unknown},
12270   /* 0x98 */  {dissect_unknown, dissect_unknown},
12271   /* 0x99 */  {dissect_unknown, dissect_unknown},
12272   /* 0x9a */  {dissect_unknown, dissect_unknown},
12273   /* 0x9b */  {dissect_unknown, dissect_unknown},
12274   /* 0x9c */  {dissect_unknown, dissect_unknown},
12275   /* 0x9d */  {dissect_unknown, dissect_unknown},
12276   /* 0x9e */  {dissect_unknown, dissect_unknown},
12277   /* 0x9f */  {dissect_unknown, dissect_unknown},
12278   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
12279   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
12280   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
12281   /* 0xa3 */  {dissect_unknown, dissect_unknown},
12282   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
12283   /* 0xa5 */  {dissect_unknown, dissect_unknown},
12284   /* 0xa6 */  {dissect_unknown, dissect_unknown},
12285   /* 0xa7 */  {dissect_unknown, dissect_unknown},
12286   /* 0xa8 */  {dissect_unknown, dissect_unknown},
12287   /* 0xa9 */  {dissect_unknown, dissect_unknown},
12288   /* 0xaa */  {dissect_unknown, dissect_unknown},
12289   /* 0xab */  {dissect_unknown, dissect_unknown},
12290   /* 0xac */  {dissect_unknown, dissect_unknown},
12291   /* 0xad */  {dissect_unknown, dissect_unknown},
12292   /* 0xae */  {dissect_unknown, dissect_unknown},
12293   /* 0xaf */  {dissect_unknown, dissect_unknown},
12294
12295   /* 0xb0 */  {dissect_unknown, dissect_unknown},
12296   /* 0xb1 */  {dissect_unknown, dissect_unknown},
12297   /* 0xb2 */  {dissect_unknown, dissect_unknown},
12298   /* 0xb3 */  {dissect_unknown, dissect_unknown},
12299   /* 0xb4 */  {dissect_unknown, dissect_unknown},
12300   /* 0xb5 */  {dissect_unknown, dissect_unknown},
12301   /* 0xb6 */  {dissect_unknown, dissect_unknown},
12302   /* 0xb7 */  {dissect_unknown, dissect_unknown},
12303   /* 0xb8 */  {dissect_unknown, dissect_unknown},
12304   /* 0xb9 */  {dissect_unknown, dissect_unknown},
12305   /* 0xba */  {dissect_unknown, dissect_unknown},
12306   /* 0xbb */  {dissect_unknown, dissect_unknown},
12307   /* 0xbc */  {dissect_unknown, dissect_unknown},
12308   /* 0xbd */  {dissect_unknown, dissect_unknown},
12309   /* 0xbe */  {dissect_unknown, dissect_unknown},
12310   /* 0xbf */  {dissect_unknown, dissect_unknown},
12311   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
12312   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
12313   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
12314   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
12315   /* 0xc4 */  {dissect_unknown, dissect_unknown},
12316   /* 0xc5 */  {dissect_unknown, dissect_unknown},
12317   /* 0xc6 */  {dissect_unknown, dissect_unknown},
12318   /* 0xc7 */  {dissect_unknown, dissect_unknown},
12319   /* 0xc8 */  {dissect_unknown, dissect_unknown},
12320   /* 0xc9 */  {dissect_unknown, dissect_unknown},
12321   /* 0xca */  {dissect_unknown, dissect_unknown},
12322   /* 0xcb */  {dissect_unknown, dissect_unknown},
12323   /* 0xcc */  {dissect_unknown, dissect_unknown},
12324   /* 0xcd */  {dissect_unknown, dissect_unknown},
12325   /* 0xce */  {dissect_unknown, dissect_unknown},
12326   /* 0xcf */  {dissect_unknown, dissect_unknown},
12327
12328   /* 0xd0 */  {dissect_unknown, dissect_unknown},
12329   /* 0xd1 */  {dissect_unknown, dissect_unknown},
12330   /* 0xd2 */  {dissect_unknown, dissect_unknown},
12331   /* 0xd3 */  {dissect_unknown, dissect_unknown},
12332   /* 0xd4 */  {dissect_unknown, dissect_unknown},
12333   /* 0xd5 */  {dissect_unknown, dissect_unknown},
12334   /* 0xd6 */  {dissect_unknown, dissect_unknown},
12335   /* 0xd7 */  {dissect_unknown, dissect_unknown},
12336   /* 0xd8 */  {dissect_unknown, dissect_unknown},
12337   /* 0xd9 */  {dissect_unknown, dissect_unknown},
12338   /* 0xda */  {dissect_unknown, dissect_unknown},
12339   /* 0xdb */  {dissect_unknown, dissect_unknown},
12340   /* 0xdc */  {dissect_unknown, dissect_unknown},
12341   /* 0xdd */  {dissect_unknown, dissect_unknown},
12342   /* 0xde */  {dissect_unknown, dissect_unknown},
12343   /* 0xdf */  {dissect_unknown, dissect_unknown},
12344
12345   /* 0xe0 */  {dissect_unknown, dissect_unknown},
12346   /* 0xe1 */  {dissect_unknown, dissect_unknown},
12347   /* 0xe2 */  {dissect_unknown, dissect_unknown},
12348   /* 0xe3 */  {dissect_unknown, dissect_unknown},
12349   /* 0xe4 */  {dissect_unknown, dissect_unknown},
12350   /* 0xe5 */  {dissect_unknown, dissect_unknown},
12351   /* 0xe6 */  {dissect_unknown, dissect_unknown},
12352   /* 0xe7 */  {dissect_unknown, dissect_unknown},
12353   /* 0xe8 */  {dissect_unknown, dissect_unknown},
12354   /* 0xe9 */  {dissect_unknown, dissect_unknown},
12355   /* 0xea */  {dissect_unknown, dissect_unknown},
12356   /* 0xeb */  {dissect_unknown, dissect_unknown},
12357   /* 0xec */  {dissect_unknown, dissect_unknown},
12358   /* 0xed */  {dissect_unknown, dissect_unknown},
12359   /* 0xee */  {dissect_unknown, dissect_unknown},
12360   /* 0xef */  {dissect_unknown, dissect_unknown},
12361
12362   /* 0xf0 */  {dissect_unknown, dissect_unknown},
12363   /* 0xf1 */  {dissect_unknown, dissect_unknown},
12364   /* 0xf2 */  {dissect_unknown, dissect_unknown},
12365   /* 0xf3 */  {dissect_unknown, dissect_unknown},
12366   /* 0xf4 */  {dissect_unknown, dissect_unknown},
12367   /* 0xf5 */  {dissect_unknown, dissect_unknown},
12368   /* 0xf6 */  {dissect_unknown, dissect_unknown},
12369   /* 0xf7 */  {dissect_unknown, dissect_unknown},
12370   /* 0xf8 */  {dissect_unknown, dissect_unknown},
12371   /* 0xf9 */  {dissect_unknown, dissect_unknown},
12372   /* 0xfa */  {dissect_unknown, dissect_unknown},
12373   /* 0xfb */  {dissect_unknown, dissect_unknown},
12374   /* 0xfc */  {dissect_unknown, dissect_unknown},
12375   /* 0xfd */  {dissect_unknown, dissect_unknown},
12376   /* 0xfe */  {dissect_unknown, dissect_unknown},
12377   /* 0xff */  {dissect_unknown, dissect_unknown},
12378 };
12379
12380 static int
12381 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
12382 {
12383         int old_offset = offset;
12384         smb_info_t *si;
12385  
12386         si = pinfo->private_data;
12387         if(cmd!=0xff){
12388                 proto_item *cmd_item;
12389                 proto_tree *cmd_tree;
12390                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12391
12392                 if (check_col(pinfo->cinfo, COL_INFO)) {
12393                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
12394                                 decode_smb_name(cmd),
12395                                 (si->request)? "Request" : "Response");
12396                 }
12397
12398                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
12399                         "%s %s (0x%02x)",
12400                         decode_smb_name(cmd), 
12401                         (si->request)?"Request":"Response",
12402                         cmd);
12403
12404                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
12405
12406                 dissector = (si->request)?
12407                         smb_dissector[cmd].request:smb_dissector[cmd].response;
12408
12409                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
12410                 proto_item_set_len(cmd_item, offset-old_offset);
12411         }
12412         return offset;
12413 }
12414
12415
12416 /* NOTE: this value_string array will also be used to access data directly by
12417  * index instead of val_to_str() since 
12418  * 1, the array will always span every value from 0x00 to 0xff and
12419  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
12420  * This means that this value_string array MUST always
12421  * 1, contain all entries 0x00 to 0xff
12422  * 2, all entries must be in order.
12423  */
12424 static const value_string smb_cmd_vals[] = {
12425   { 0x00, "Create Directory" },
12426   { 0x01, "Delete Directory" },
12427   { 0x02, "Open" },
12428   { 0x03, "Create" },
12429   { 0x04, "Close" },
12430   { 0x05, "Flush" },
12431   { 0x06, "Delete" },
12432   { 0x07, "Rename" },
12433   { 0x08, "Query Information" },
12434   { 0x09, "Set Information" },
12435   { 0x0A, "Read" },
12436   { 0x0B, "Write" },
12437   { 0x0C, "Lock Byte Range" },
12438   { 0x0D, "Unlock Byte Range" },
12439   { 0x0E, "Create Temp" },
12440   { 0x0F, "Create New" },
12441   { 0x10, "Check Directory" },
12442   { 0x11, "Process Exit" },
12443   { 0x12, "Seek" },
12444   { 0x13, "Lock And Read" },
12445   { 0x14, "Write And Unlock" },
12446   { 0x15, "unknown-0x15" },
12447   { 0x16, "unknown-0x16" },
12448   { 0x17, "unknown-0x17" },
12449   { 0x18, "unknown-0x18" },
12450   { 0x19, "unknown-0x19" },
12451   { 0x1A, "Read Raw" },
12452   { 0x1B, "Read MPX" },
12453   { 0x1C, "Read MPX Secondary" },
12454   { 0x1D, "Write Raw" },
12455   { 0x1E, "Write MPX" },
12456   { 0x1F, "SMBwriteBs" },
12457   { 0x20, "Write Complete" },
12458   { 0x21, "unknown-0x21" },
12459   { 0x22, "Set Information2" },
12460   { 0x23, "Query Information2" },
12461   { 0x24, "Locking AndX" },
12462   { 0x25, "Transaction" },
12463   { 0x26, "Transaction Secondary" },
12464   { 0x27, "IOCTL" },
12465   { 0x28, "IOCTL Secondary" },
12466   { 0x29, "Copy" },
12467   { 0x2A, "Move" },
12468   { 0x2B, "Echo" },
12469   { 0x2C, "Write And Close" },
12470   { 0x2D, "Open AndX" },
12471   { 0x2E, "Read AndX" },
12472   { 0x2F, "Write AndX" },
12473   { 0x30, "unknown-0x30" },
12474   { 0x31, "Close And Tree Discover" },
12475   { 0x32, "Transaction2" },
12476   { 0x33, "Transaction2 Secondary" },
12477   { 0x34, "Find Close2" },
12478   { 0x35, "Find Notify Close" },
12479   { 0x36, "unknown-0x36" },
12480   { 0x37, "unknown-0x37" },
12481   { 0x38, "unknown-0x38" },
12482   { 0x39, "unknown-0x39" },
12483   { 0x3A, "unknown-0x3A" },
12484   { 0x3B, "unknown-0x3B" },
12485   { 0x3C, "unknown-0x3C" },
12486   { 0x3D, "unknown-0x3D" },
12487   { 0x3E, "unknown-0x3E" },
12488   { 0x3F, "unknown-0x3F" },
12489   { 0x40, "unknown-0x40" },
12490   { 0x41, "unknown-0x41" },
12491   { 0x42, "unknown-0x42" },
12492   { 0x43, "unknown-0x43" },
12493   { 0x44, "unknown-0x44" },
12494   { 0x45, "unknown-0x45" },
12495   { 0x46, "unknown-0x46" },
12496   { 0x47, "unknown-0x47" },
12497   { 0x48, "unknown-0x48" },
12498   { 0x49, "unknown-0x49" },
12499   { 0x4A, "unknown-0x4A" },
12500   { 0x4B, "unknown-0x4B" },
12501   { 0x4C, "unknown-0x4C" },
12502   { 0x4D, "unknown-0x4D" },
12503   { 0x4E, "unknown-0x4E" },
12504   { 0x4F, "unknown-0x4F" },
12505   { 0x50, "unknown-0x50" },
12506   { 0x51, "unknown-0x51" },
12507   { 0x52, "unknown-0x52" },
12508   { 0x53, "unknown-0x53" },
12509   { 0x54, "unknown-0x54" },
12510   { 0x55, "unknown-0x55" },
12511   { 0x56, "unknown-0x56" },
12512   { 0x57, "unknown-0x57" },
12513   { 0x58, "unknown-0x58" },
12514   { 0x59, "unknown-0x59" },
12515   { 0x5A, "unknown-0x5A" },
12516   { 0x5B, "unknown-0x5B" },
12517   { 0x5C, "unknown-0x5C" },
12518   { 0x5D, "unknown-0x5D" },
12519   { 0x5E, "unknown-0x5E" },
12520   { 0x5F, "unknown-0x5F" },
12521   { 0x60, "unknown-0x60" },
12522   { 0x61, "unknown-0x61" },
12523   { 0x62, "unknown-0x62" },
12524   { 0x63, "unknown-0x63" },
12525   { 0x64, "unknown-0x64" },
12526   { 0x65, "unknown-0x65" },
12527   { 0x66, "unknown-0x66" },
12528   { 0x67, "unknown-0x67" },
12529   { 0x68, "unknown-0x68" },
12530   { 0x69, "unknown-0x69" },
12531   { 0x6A, "unknown-0x6A" },
12532   { 0x6B, "unknown-0x6B" },
12533   { 0x6C, "unknown-0x6C" },
12534   { 0x6D, "unknown-0x6D" },
12535   { 0x6E, "unknown-0x6E" },
12536   { 0x6F, "unknown-0x6F" },
12537   { 0x70, "Tree Connect" },
12538   { 0x71, "Tree Disconnect" },
12539   { 0x72, "Negotiate Protocol" },
12540   { 0x73, "Session Setup AndX" },
12541   { 0x74, "Logoff AndX" },
12542   { 0x75, "Tree Connect AndX" },
12543   { 0x76, "unknown-0x76" },
12544   { 0x77, "unknown-0x77" },
12545   { 0x78, "unknown-0x78" },
12546   { 0x79, "unknown-0x79" },
12547   { 0x7A, "unknown-0x7A" },
12548   { 0x7B, "unknown-0x7B" },
12549   { 0x7C, "unknown-0x7C" },
12550   { 0x7D, "unknown-0x7D" },
12551   { 0x7E, "unknown-0x7E" },
12552   { 0x7F, "unknown-0x7F" },
12553   { 0x80, "Query Information Disk" },
12554   { 0x81, "Search" },
12555   { 0x82, "Find" },
12556   { 0x83, "Find Unique" },
12557   { 0x84, "SMBfclose" },
12558   { 0x85, "unknown-0x85" },
12559   { 0x86, "unknown-0x86" },
12560   { 0x87, "unknown-0x87" },
12561   { 0x88, "unknown-0x88" },
12562   { 0x89, "unknown-0x89" },
12563   { 0x8A, "unknown-0x8A" },
12564   { 0x8B, "unknown-0x8B" },
12565   { 0x8C, "unknown-0x8C" },
12566   { 0x8D, "unknown-0x8D" },
12567   { 0x8E, "unknown-0x8E" },
12568   { 0x8F, "unknown-0x8F" },
12569   { 0x90, "unknown-0x90" },
12570   { 0x91, "unknown-0x91" },
12571   { 0x92, "unknown-0x92" },
12572   { 0x93, "unknown-0x93" },
12573   { 0x94, "unknown-0x94" },
12574   { 0x95, "unknown-0x95" },
12575   { 0x96, "unknown-0x96" },
12576   { 0x97, "unknown-0x97" },
12577   { 0x98, "unknown-0x98" },
12578   { 0x99, "unknown-0x99" },
12579   { 0x9A, "unknown-0x9A" },
12580   { 0x9B, "unknown-0x9B" },
12581   { 0x9C, "unknown-0x9C" },
12582   { 0x9D, "unknown-0x9D" },
12583   { 0x9E, "unknown-0x9E" },
12584   { 0x9F, "unknown-0x9F" },
12585   { 0xA0, "NT Transact" },
12586   { 0xA1, "NT Transact Secondary" },
12587   { 0xA2, "NT Create AndX" },
12588   { 0xA3, "unknown-0xA3" },
12589   { 0xA4, "NT Cancel" },
12590   { 0xA5, "unknown-0xA5" },
12591   { 0xA6, "unknown-0xA6" },
12592   { 0xA7, "unknown-0xA7" },
12593   { 0xA8, "unknown-0xA8" },
12594   { 0xA9, "unknown-0xA9" },
12595   { 0xAA, "unknown-0xAA" },
12596   { 0xAB, "unknown-0xAB" },
12597   { 0xAC, "unknown-0xAC" },
12598   { 0xAD, "unknown-0xAD" },
12599   { 0xAE, "unknown-0xAE" },
12600   { 0xAF, "unknown-0xAF" },
12601   { 0xB0, "unknown-0xB0" },
12602   { 0xB1, "unknown-0xB1" },
12603   { 0xB2, "unknown-0xB2" },
12604   { 0xB3, "unknown-0xB3" },
12605   { 0xB4, "unknown-0xB4" },
12606   { 0xB5, "unknown-0xB5" },
12607   { 0xB6, "unknown-0xB6" },
12608   { 0xB7, "unknown-0xB7" },
12609   { 0xB8, "unknown-0xB8" },
12610   { 0xB9, "unknown-0xB9" },
12611   { 0xBA, "unknown-0xBA" },
12612   { 0xBB, "unknown-0xBB" },
12613   { 0xBC, "unknown-0xBC" },
12614   { 0xBD, "unknown-0xBD" },
12615   { 0xBE, "unknown-0xBE" },
12616   { 0xBF, "unknown-0xBF" },
12617   { 0xC0, "Open Print File" },
12618   { 0xC1, "Write Print File" },
12619   { 0xC2, "Close Print File" },
12620   { 0xC3, "Get Print Queue" },
12621   { 0xC4, "unknown-0xC4" },
12622   { 0xC5, "unknown-0xC5" },
12623   { 0xC6, "unknown-0xC6" },
12624   { 0xC7, "unknown-0xC7" },
12625   { 0xC8, "unknown-0xC8" },
12626   { 0xC9, "unknown-0xC9" },
12627   { 0xCA, "unknown-0xCA" },
12628   { 0xCB, "unknown-0xCB" },
12629   { 0xCC, "unknown-0xCC" },
12630   { 0xCD, "unknown-0xCD" },
12631   { 0xCE, "unknown-0xCE" },
12632   { 0xCF, "unknown-0xCF" },
12633   { 0xD0, "SMBsends" },
12634   { 0xD1, "SMBsendb" },
12635   { 0xD2, "SMBfwdname" },
12636   { 0xD3, "SMBcancelf" },
12637   { 0xD4, "SMBgetmac" },
12638   { 0xD5, "SMBsendstrt" },
12639   { 0xD6, "SMBsendend" },
12640   { 0xD7, "SMBsendtxt" },
12641   { 0xD8, "SMBreadbulk" },
12642   { 0xD9, "SMBwritebulk" },
12643   { 0xDA, "SMBwritebulkdata" },
12644   { 0xDB, "unknown-0xDB" },
12645   { 0xDC, "unknown-0xDC" },
12646   { 0xDD, "unknown-0xDD" },
12647   { 0xDE, "unknown-0xDE" },
12648   { 0xDF, "unknown-0xDF" },
12649   { 0xE0, "unknown-0xE0" },
12650   { 0xE1, "unknown-0xE1" },
12651   { 0xE2, "unknown-0xE2" },
12652   { 0xE3, "unknown-0xE3" },
12653   { 0xE4, "unknown-0xE4" },
12654   { 0xE5, "unknown-0xE5" },
12655   { 0xE6, "unknown-0xE6" },
12656   { 0xE7, "unknown-0xE7" },
12657   { 0xE8, "unknown-0xE8" },
12658   { 0xE9, "unknown-0xE9" },
12659   { 0xEA, "unknown-0xEA" },
12660   { 0xEB, "unknown-0xEB" },
12661   { 0xEC, "unknown-0xEC" },
12662   { 0xED, "unknown-0xED" },
12663   { 0xEE, "unknown-0xEE" },
12664   { 0xEF, "unknown-0xEF" },
12665   { 0xF0, "unknown-0xF0" },
12666   { 0xF1, "unknown-0xF1" },
12667   { 0xF2, "unknown-0xF2" },
12668   { 0xF3, "unknown-0xF3" },
12669   { 0xF4, "unknown-0xF4" },
12670   { 0xF5, "unknown-0xF5" },
12671   { 0xF6, "unknown-0xF6" },
12672   { 0xF7, "unknown-0xF7" },
12673   { 0xF8, "unknown-0xF8" },
12674   { 0xF9, "unknown-0xF9" },
12675   { 0xFA, "unknown-0xFA" },
12676   { 0xFB, "unknown-0xFB" },
12677   { 0xFC, "unknown-0xFC" },
12678   { 0xFD, "unknown-0xFD" },
12679   { 0xFE, "SMBinvalid" },
12680   { 0xFF, "unknown-0xFF" },
12681   { 0x00, NULL },
12682 };
12683
12684 static char *decode_smb_name(unsigned char cmd)
12685 {
12686   return(smb_cmd_vals[cmd].strptr);
12687 }
12688  
12689
12690
12691 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12692  * Everything TVBUFFIFIED above this line
12693  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12694
12695
12696 static void
12697 free_hash_tables(gpointer ctarg, gpointer user_data)
12698 {
12699         conv_tables_t *ct = ctarg;
12700
12701         if (ct->unmatched)
12702                 g_hash_table_destroy(ct->unmatched);
12703         if (ct->matched)
12704                 g_hash_table_destroy(ct->matched);
12705         if (ct->dcerpc_fid_to_frame)
12706                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
12707         if (ct->tid_service)
12708                 g_hash_table_destroy(ct->tid_service);
12709 }
12710
12711 static void
12712 smb_init_protocol(void)
12713 {
12714         if (smb_saved_info_key_chunk)
12715                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
12716         if (smb_saved_info_chunk)
12717                 g_mem_chunk_destroy(smb_saved_info_chunk);
12718         if (smb_nt_transact_info_chunk)
12719                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
12720         if (smb_transact2_info_chunk)
12721                 g_mem_chunk_destroy(smb_transact2_info_chunk);
12722         if (smb_transact_info_chunk)
12723                 g_mem_chunk_destroy(smb_transact_info_chunk);
12724
12725         /*
12726          * Free the hash tables attached to the conversation table
12727          * structures, and then free the list of conversation table
12728          * data structures (which doesn't free the data structures
12729          * themselves; that's done by destroying the chunk from
12730          * which they were allocated).
12731          */
12732         if (conv_tables) {
12733                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
12734                 g_slist_free(conv_tables);
12735                 conv_tables = NULL;
12736         }
12737
12738         /*
12739          * Now destroy the chunk from which the conversation table
12740          * structures were allocated.
12741          */
12742         if (conv_tables_chunk)
12743                 g_mem_chunk_destroy(conv_tables_chunk);
12744
12745         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
12746             sizeof(smb_saved_info_t),
12747             smb_saved_info_init_count * sizeof(smb_saved_info_t),
12748             G_ALLOC_ONLY);
12749         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
12750             sizeof(smb_saved_info_key_t),
12751             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
12752             G_ALLOC_ONLY);
12753         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
12754             sizeof(smb_nt_transact_info_t),
12755             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
12756             G_ALLOC_ONLY);
12757         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
12758             sizeof(smb_transact2_info_t),
12759             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
12760             G_ALLOC_ONLY);
12761         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
12762             sizeof(smb_transact_info_t),
12763             smb_transact_info_init_count * sizeof(smb_transact_info_t),
12764             G_ALLOC_ONLY);
12765         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
12766             sizeof(conv_tables_t),
12767             conv_tables_count * sizeof(conv_tables_t),
12768             G_ALLOC_ONLY);
12769 }
12770
12771 /* Max string length for displaying Unicode strings.  */
12772 #define MAX_UNICODE_STR_LEN     256
12773
12774
12775 /* Turn a little-endian Unicode '\0'-terminated string into a string we
12776    can display.
12777    XXX - for now, we just handle the ISO 8859-1 characters.
12778    If exactlen==TRUE then us_lenp contains the exact len of the string in
12779    bytes. It might not be null terminated !
12780    bc specifies the number of bytes in the byte parameters; Windows 2000,
12781    at least, appears, in some cases, to put only 1 byte of 0 at the end
12782    of a Unicode string if the byte count
12783 */
12784 static gchar *
12785 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
12786                    guint16 bc)
12787 {
12788   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12789   static gchar *cur;
12790   gchar        *p;
12791   guint16       uchar;
12792   int           len;
12793   int           us_len;
12794   int           overflow = 0;
12795
12796   if (cur == &str[0][0]) {
12797     cur = &str[1][0];
12798   } else if (cur == &str[1][0]) {  
12799     cur = &str[2][0];
12800   } else {  
12801     cur = &str[0][0];
12802   }
12803   p = cur;
12804   len = MAX_UNICODE_STR_LEN;
12805   us_len = 0;
12806   for (;;) {
12807     if (bc == 0)
12808       break;
12809     if (bc == 1) {
12810       /* XXX - explain this */
12811       if (!exactlen)
12812         us_len += 1;    /* this is a one-byte null terminator */
12813       break;
12814     }
12815     uchar = tvb_get_letohs(tvb, offset);
12816     if (uchar == 0) {
12817       us_len += 2;      /* this is a two-byte null terminator */
12818       break;
12819     }
12820     if (len > 0) {
12821       if ((uchar & 0xFF00) == 0)
12822         *p++ = uchar;   /* ISO 8859-1 */
12823       else
12824         *p++ = '?';     /* not 8859-1 */
12825       len--;
12826     } else
12827       overflow = 1;
12828     offset += 2;
12829     bc -= 2;
12830     us_len += 2;
12831     if(exactlen){
12832       if(us_len>= *us_lenp){
12833         break;
12834       }
12835     }
12836   }
12837   if (overflow) {
12838     /* Note that we're not showing the full string.  */
12839     *p++ = '.';
12840     *p++ = '.';
12841     *p++ = '.';
12842   }
12843   *p = '\0';
12844   *us_lenp = us_len;
12845   return cur;
12846 }
12847  
12848
12849 /* nopad == TRUE : Do not add any padding before this string
12850  * exactlen == TRUE : len contains the exact len of the string in bytes.
12851  * bc: pointer to variable with amount of data left in the byte parameters
12852  *   region
12853  */
12854 static const gchar *
12855 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
12856     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
12857     guint16 *bcp)
12858 {
12859   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12860   static gchar *cur;
12861   const gchar *string;
12862   int string_len;
12863   smb_info_t *si;
12864   unsigned int copylen;
12865
12866   if (*bcp == 0) {
12867     /* Not enough data in buffer */
12868     return NULL;
12869   }
12870   si = pinfo->private_data;
12871   if (si->unicode) {
12872     if ((!nopad) && (*offsetp % 2)) {
12873       /*
12874        * XXX - this should be an offset relative to the beginning of the SMB,
12875        * not an offset relative to the beginning of the frame; if the stuff
12876        * before the SMB has an odd number of bytes, an offset relative to
12877        * the beginning of the frame will give the wrong answer.
12878        */
12879       (*offsetp)++;   /* Looks like a pad byte there sometimes */
12880       (*bcp)--;
12881       if (*bcp == 0) {
12882         /* Not enough data in buffer */
12883         return NULL;
12884       }
12885     }
12886     if(exactlen){
12887       string_len = *len;
12888       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12889     } else {
12890       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12891     }
12892   } else {
12893     if(exactlen){
12894       /*
12895        * The string we return must be null-terminated.
12896        */
12897       if (cur == &str[0][0]) {
12898         cur = &str[1][0];
12899       } else if (cur == &str[1][0]) {  
12900         cur = &str[2][0];
12901       } else {  
12902         cur = &str[0][0];
12903       }
12904       copylen = *len;
12905       if (copylen > MAX_UNICODE_STR_LEN)
12906         copylen = MAX_UNICODE_STR_LEN;
12907       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
12908       cur[copylen] = '\0';
12909       if (copylen > MAX_UNICODE_STR_LEN)
12910         strcat(cur, "...");
12911       string_len = *len;
12912       string = cur;
12913     } else {
12914       string_len = tvb_strsize(tvb, *offsetp);
12915       string = tvb_get_ptr(tvb, *offsetp, string_len);
12916     }
12917   }
12918   *len = string_len;
12919   return string;
12920 }
12921
12922
12923
12924 static const value_string errcls_types[] = {
12925   { SMB_SUCCESS, "Success"},
12926   { SMB_ERRDOS, "DOS Error"},
12927   { SMB_ERRSRV, "Server Error"},
12928   { SMB_ERRHRD, "Hardware Error"},
12929   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
12930   { 0, NULL }
12931 };
12932
12933 const value_string DOS_errors[] = {
12934   {0, "Success"},
12935   {SMBE_insufficientbuffer, "Insufficient buffer"},
12936   {SMBE_badfunc, "Invalid function (or system call)"},
12937   {SMBE_badfile, "File not found (pathname error)"},
12938   {SMBE_badpath, "Directory not found"},
12939   {SMBE_nofids, "Too many open files"},
12940   {SMBE_noaccess, "Access denied"},
12941   {SMBE_badfid, "Invalid fid"},
12942   {SMBE_nomem,  "Out of memory"},
12943   {SMBE_badmem, "Invalid memory block address"},
12944   {SMBE_badenv, "Invalid environment"},
12945   {SMBE_badaccess, "Invalid open mode"},
12946   {SMBE_baddata, "Invalid data (only from ioctl call)"},
12947   {SMBE_res, "Reserved error code?"}, 
12948   {SMBE_baddrive, "Invalid drive"},
12949   {SMBE_remcd, "Attempt to delete current directory"},
12950   {SMBE_diffdevice, "Rename/move across different filesystems"},
12951   {SMBE_nofiles, "No more files found in file search"},
12952   {SMBE_badshare, "Share mode on file conflict with open mode"},
12953   {SMBE_lock, "Lock request conflicts with existing lock"},
12954   {SMBE_unsup, "Request unsupported, returned by Win 95"},
12955   {SMBE_nosuchshare, "Requested share does not exist"},
12956   {SMBE_filexists, "File in operation already exists"},
12957   {SMBE_cannotopen, "Cannot open the file specified"},
12958   {SMBE_unknownlevel, "Unknown info level"},
12959   {SMBE_invalidname, "Invalid name"},
12960   {SMBE_badpipe, "Named pipe invalid"},
12961   {SMBE_pipebusy, "All instances of pipe are busy"},
12962   {SMBE_pipeclosing, "Named pipe close in progress"},
12963   {SMBE_notconnected, "No process on other end of named pipe"},
12964   {SMBE_moredata, "More data to be returned"},
12965   {SMBE_baddirectory,  "Invalid directory name in a path."},
12966   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
12967   {SMBE_eas_nsup, "Extended attributes not supported"},
12968   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
12969   {SMBE_unknownipc, "Unknown IPC Operation"},
12970   {SMBE_noipc, "Don't support ipc"},
12971   {SMBE_alreadyexists, "File already exists"},
12972   {SMBE_unknownprinterdriver, "Unknown printer driver"},
12973   {SMBE_invalidprintername, "Invalid printer name"},
12974   {SMBE_printeralreadyexists, "Printer already exists"},
12975   {SMBE_invaliddatatype, "Invalid data type"},
12976   {SMBE_invalidenvironment, "Invalid environment"},
12977   {SMBE_printerdriverinuse, "Printer driver in use"},
12978   {SMBE_invalidparam, "Invalid parameter"},
12979   {SMBE_invalidformsize, "Invalid form size"},
12980   {0, NULL}
12981   };
12982
12983 /* Error codes for the ERRSRV class */
12984
12985 static const value_string SRV_errors[] = {
12986   {SMBE_error, "Non specific error code"},
12987   {SMBE_badpw, "Bad password"},
12988   {SMBE_badtype, "Reserved"},
12989   {SMBE_access, "No permissions to perform the requested operation"},
12990   {SMBE_invnid, "TID invalid"},
12991   {SMBE_invnetname, "Invalid network name. Service not found"},
12992   {SMBE_invdevice, "Invalid device"},
12993   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
12994   {SMBE_qfull, "Print queue full"},
12995   {SMBE_qtoobig, "Queued item too big"},
12996   {SMBE_qeof, "EOF on print queue dump"},
12997   {SMBE_invpfid, "Invalid print file in smb_fid"},
12998   {SMBE_smbcmd, "Unrecognised command"},
12999   {SMBE_srverror, "SMB server internal error"},
13000   {SMBE_filespecs, "Fid and pathname invalid combination"},
13001   {SMBE_badlink, "Bad link in request ???"},
13002   {SMBE_badpermits, "Access specified for a file is not valid"},
13003   {SMBE_badpid, "Bad process id in request"},
13004   {SMBE_setattrmode, "Attribute mode invalid"},
13005   {SMBE_paused, "Message server paused"},
13006   {SMBE_msgoff, "Not receiving messages"},
13007   {SMBE_noroom, "No room for message"},
13008   {SMBE_rmuns, "Too many remote usernames"},
13009   {SMBE_timeout, "Operation timed out"},
13010   {SMBE_noresource, "No resources currently available for request."},
13011   {SMBE_toomanyuids, "Too many userids"},
13012   {SMBE_baduid, "Bad userid"},
13013   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
13014   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
13015   {SMBE_contMPX, "Resume MPX mode"},
13016   {SMBE_badPW, "Bad Password???"},
13017   {SMBE_nosupport, "Operation not supported"},
13018   { 0, NULL}
13019 };
13020
13021 /* Error codes for the ERRHRD class */
13022
13023 static const value_string HRD_errors[] = {
13024   {SMBE_nowrite, "Read only media"},
13025   {SMBE_badunit, "Unknown device"},
13026   {SMBE_notready, "Drive not ready"},
13027   {SMBE_badcmd, "Unknown command"},
13028   {SMBE_data, "Data (CRC) error"},
13029   {SMBE_badreq, "Bad request structure length"},
13030   {SMBE_seek, "Seek error???"},
13031   {SMBE_badmedia, "Bad media???"},
13032   {SMBE_badsector, "Bad sector???"},
13033   {SMBE_nopaper, "No paper in printer???"},
13034   {SMBE_write, "Write error???"},
13035   {SMBE_read, "Read error???"},
13036   {SMBE_general, "General error???"},
13037   {SMBE_badshare, "A open conflicts with an existing open"},
13038   {SMBE_lock, "Lock/unlock error"},
13039   {SMBE_wrongdisk,  "Wrong disk???"},
13040   {SMBE_FCBunavail, "FCB unavailable???"},
13041   {SMBE_sharebufexc, "Share buffer excluded???"},
13042   {SMBE_diskfull, "Disk full???"},
13043   {0, NULL}
13044 };
13045
13046 static char *decode_smb_error(guint8 errcls, guint16 errcode)
13047 {
13048
13049   switch (errcls) {
13050
13051   case SMB_SUCCESS:
13052
13053     return("No Error");   /* No error ??? */
13054     break;
13055
13056   case SMB_ERRDOS:
13057
13058     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
13059     break;
13060
13061   case SMB_ERRSRV:
13062
13063     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
13064     break;
13065
13066   case SMB_ERRHRD:
13067
13068     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
13069     break;
13070
13071   default:
13072
13073     return("Unknown error class!");
13074
13075   }
13076
13077 }
13078
13079
13080 /* These are the MS country codes from
13081
13082         http://www.unicode.org/unicode/onlinedat/countries.html
13083
13084    For countries that share the same number, I choose to use only the
13085    name of the largest country. Apologies for this. If this offends you,
13086    here is the table to change that.
13087
13088    This also includes the code of 0 for "Default", which isn't in
13089    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
13090    header file.  Presumably it means "don't override the setting
13091    on the user's machine".
13092
13093    Future versions of Microsoft's "winnls.h" header file might include
13094    additional codes; the current version matches the Unicode Consortium's
13095    table.
13096 */
13097 const value_string ms_country_codes[] = {
13098         {  0,   "Default"},
13099         {  1,   "USA"},
13100         {  2,   "Canada"},
13101         {  7,   "Russia"},
13102         { 20,   "Egypt"},
13103         { 27,   "South Africa"},
13104         { 30,   "Greece"},
13105         { 31,   "Netherlands"},
13106         { 32,   "Belgium"},
13107         { 33,   "France"},
13108         { 34,   "Spain"},
13109         { 36,   "Hungary"},
13110         { 39,   "Italy"},
13111         { 40,   "Romania"},
13112         { 41,   "Switzerland"},
13113         { 43,   "Austria"},
13114         { 44,   "United Kingdom"},
13115         { 45,   "Denmark"},
13116         { 46,   "Sweden"},
13117         { 47,   "Norway"},
13118         { 48,   "Poland"},
13119         { 49,   "Germany"},
13120         { 51,   "Peru"},
13121         { 52,   "Mexico"},
13122         { 54,   "Argentina"},
13123         { 55,   "Brazil"},
13124         { 56,   "Chile"},
13125         { 57,   "Colombia"},
13126         { 58,   "Venezuela"},
13127         { 60,   "Malaysia"},
13128         { 61,   "Australia"},
13129         { 62,   "Indonesia"},
13130         { 63,   "Philippines"},
13131         { 64,   "New Zealand"},
13132         { 65,   "Singapore"},
13133         { 66,   "Thailand"},
13134         { 81,   "Japan"},
13135         { 82,   "South Korea"},
13136         { 84,   "Viet Nam"},
13137         { 86,   "China"},
13138         { 90,   "Turkey"},
13139         { 91,   "India"},
13140         { 92,   "Pakistan"},
13141         {212,   "Morocco"},
13142         {213,   "Algeria"},
13143         {216,   "Tunisia"},
13144         {218,   "Libya"},
13145         {254,   "Kenya"},
13146         {263,   "Zimbabwe"},
13147         {298,   "Faroe Islands"},
13148         {351,   "Portugal"},
13149         {352,   "Luxembourg"},
13150         {353,   "Ireland"},
13151         {354,   "Iceland"},
13152         {355,   "Albania"},
13153         {358,   "Finland"},
13154         {359,   "Bulgaria"},
13155         {370,   "Lithuania"},
13156         {371,   "Latvia"},
13157         {372,   "Estonia"},
13158         {374,   "Armenia"},
13159         {375,   "Belarus"},
13160         {380,   "Ukraine"},
13161         {381,   "Serbia"},
13162         {385,   "Croatia"},
13163         {386,   "Slovenia"},
13164         {389,   "Macedonia"},
13165         {420,   "Czech Republic"},
13166         {421,   "Slovak Republic"},
13167         {501,   "Belize"},
13168         {502,   "Guatemala"},
13169         {503,   "El Salvador"},
13170         {504,   "Honduras"},
13171         {505,   "Nicaragua"},
13172         {506,   "Costa Rica"},
13173         {507,   "Panama"},
13174         {591,   "Bolivia"},
13175         {593,   "Ecuador"},
13176         {595,   "Paraguay"},
13177         {598,   "Uruguay"},
13178         {673,   "Brunei Darussalam"},
13179         {852,   "Hong Kong"},
13180         {853,   "Macau"},
13181         {886,   "Taiwan"},
13182         {960,   "Maldives"},
13183         {961,   "Lebanon"},
13184         {962,   "Jordan"},
13185         {963,   "Syria"},
13186         {964,   "Iraq"},
13187         {965,   "Kuwait"},
13188         {966,   "Saudi Arabia"},
13189         {967,   "Yemen"},
13190         {968,   "Oman"},
13191         {971,   "United Arab Emirates"},
13192         {972,   "Israel"},
13193         {973,   "Bahrain"},
13194         {974,   "Qatar"},
13195         {976,   "Mongolia"},
13196         {981,   "Iran"},
13197         {994,   "Azerbaijan"},
13198         {995,   "Georgia"},
13199         {996,   "Kyrgyzstan"},
13200
13201         {0,     NULL}
13202 };
13203
13204 /*
13205  * NT error codes.
13206  *
13207  * From
13208  *
13209  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
13210  */
13211 const value_string NT_errors[] = {
13212   { 0x00000000, "STATUS_SUCCESS" },
13213   { 0x00000000, "STATUS_WAIT_0" },
13214   { 0x00000001, "STATUS_WAIT_1" },
13215   { 0x00000002, "STATUS_WAIT_2" },
13216   { 0x00000003, "STATUS_WAIT_3" },
13217   { 0x0000003F, "STATUS_WAIT_63" },
13218   { 0x00000080, "STATUS_ABANDONED" },
13219   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
13220   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
13221   { 0x000000C0, "STATUS_USER_APC" },
13222   { 0x00000100, "STATUS_KERNEL_APC" },
13223   { 0x00000101, "STATUS_ALERTED" },
13224   { 0x00000102, "STATUS_TIMEOUT" },
13225   { 0x00000103, "STATUS_PENDING" },
13226   { 0x00000104, "STATUS_REPARSE" },
13227   { 0x00000105, "STATUS_MORE_ENTRIES" },
13228   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
13229   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
13230   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
13231   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
13232   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
13233   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
13234   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
13235   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
13236   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
13237   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
13238   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
13239   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
13240   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
13241   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
13242   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
13243   { 0x00000116, "STATUS_CRASH_DUMP" },
13244   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
13245   { 0x00000118, "STATUS_REPARSE_OBJECT" },
13246   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
13247   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
13248   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
13249   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
13250   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
13251   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
13252   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
13253   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
13254   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
13255   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
13256   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
13257   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
13258   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
13259   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
13260   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
13261   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
13262   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
13263   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
13264   { 0x40000012, "STATUS_EVENT_DONE" },
13265   { 0x40000013, "STATUS_EVENT_PENDING" },
13266   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
13267   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
13268   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
13269   { 0x40000017, "STATUS_WAS_UNLOCKED" },
13270   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
13271   { 0x40000019, "STATUS_WAS_LOCKED" },
13272   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
13273   { 0x4000001B, "STATUS_ALREADY_WIN32" },
13274   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
13275   { 0x4000001D, "STATUS_WX86_CONTINUE" },
13276   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
13277   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
13278   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
13279   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
13280   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
13281   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
13282   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
13283   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
13284   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
13285   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
13286   { 0x80000003, "STATUS_BREAKPOINT" },
13287   { 0x80000004, "STATUS_SINGLE_STEP" },
13288   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
13289   { 0x80000006, "STATUS_NO_MORE_FILES" },
13290   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
13291   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
13292   { 0x8000000B, "STATUS_NO_INHERITANCE" },
13293   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
13294   { 0x8000000D, "STATUS_PARTIAL_COPY" },
13295   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
13296   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
13297   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
13298   { 0x80000011, "STATUS_DEVICE_BUSY" },
13299   { 0x80000012, "STATUS_NO_MORE_EAS" },
13300   { 0x80000013, "STATUS_INVALID_EA_NAME" },
13301   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
13302   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
13303   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
13304   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
13305   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
13306   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
13307   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
13308   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
13309   { 0x8000001D, "STATUS_BUS_RESET" },
13310   { 0x8000001E, "STATUS_END_OF_MEDIA" },
13311   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
13312   { 0x80000020, "STATUS_MEDIA_CHECK" },
13313   { 0x80000021, "STATUS_SETMARK_DETECTED" },
13314   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
13315   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
13316   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
13317   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
13318   { 0x80000026, "STATUS_LONGJUMP" },
13319   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
13320   { 0x80090301, "SEC_E_INVALID_HANDLE" },
13321   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
13322   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
13323   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
13324   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
13325   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
13326   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
13327   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
13328   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
13329   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
13330   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
13331   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
13332   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
13333   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
13334   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
13335   { 0xC0000008, "STATUS_INVALID_HANDLE" },
13336   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
13337   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
13338   { 0xC000000B, "STATUS_INVALID_CID" },
13339   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
13340   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
13341   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
13342   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
13343   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
13344   { 0xC0000011, "STATUS_END_OF_FILE" },
13345   { 0xC0000012, "STATUS_WRONG_VOLUME" },
13346   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
13347   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
13348   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
13349   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
13350   { 0xC0000017, "STATUS_NO_MEMORY" },
13351   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
13352   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
13353   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
13354   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
13355   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
13356   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
13357   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
13358   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
13359   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
13360   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
13361   { 0xC0000022, "STATUS_ACCESS_DENIED" },
13362   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
13363   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
13364   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
13365   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
13366   { 0xC0000027, "STATUS_UNWIND" },
13367   { 0xC0000028, "STATUS_BAD_STACK" },
13368   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
13369   { 0xC000002A, "STATUS_NOT_LOCKED" },
13370   { 0xC000002B, "STATUS_PARITY_ERROR" },
13371   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
13372   { 0xC000002D, "STATUS_NOT_COMMITTED" },
13373   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
13374   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
13375   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
13376   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
13377   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
13378   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
13379   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
13380   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
13381   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
13382   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
13383   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
13384   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
13385   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
13386   { 0xC000003C, "STATUS_DATA_OVERRUN" },
13387   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
13388   { 0xC000003E, "STATUS_DATA_ERROR" },
13389   { 0xC000003F, "STATUS_CRC_ERROR" },
13390   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
13391   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
13392   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
13393   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
13394   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
13395   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
13396   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
13397   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
13398   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
13399   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
13400   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
13401   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
13402   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
13403   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
13404   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
13405   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
13406   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
13407   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
13408   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
13409   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
13410   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
13411   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
13412   { 0xC0000056, "STATUS_DELETE_PENDING" },
13413   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
13414   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
13415   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
13416   { 0xC000005A, "STATUS_INVALID_OWNER" },
13417   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
13418   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
13419   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
13420   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
13421   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
13422   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
13423   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
13424   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
13425   { 0xC0000063, "STATUS_USER_EXISTS" },
13426   { 0xC0000064, "STATUS_NO_SUCH_USER" },
13427   { 0xC0000065, "STATUS_GROUP_EXISTS" },
13428   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
13429   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
13430   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
13431   { 0xC0000069, "STATUS_LAST_ADMIN" },
13432   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
13433   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
13434   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
13435   { 0xC000006D, "STATUS_LOGON_FAILURE" },
13436   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
13437   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
13438   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
13439   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
13440   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
13441   { 0xC0000073, "STATUS_NONE_MAPPED" },
13442   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
13443   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
13444   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
13445   { 0xC0000077, "STATUS_INVALID_ACL" },
13446   { 0xC0000078, "STATUS_INVALID_SID" },
13447   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
13448   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
13449   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
13450   { 0xC000007C, "STATUS_NO_TOKEN" },
13451   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
13452   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
13453   { 0xC000007F, "STATUS_DISK_FULL" },
13454   { 0xC0000080, "STATUS_SERVER_DISABLED" },
13455   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
13456   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
13457   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
13458   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
13459   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
13460   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
13461   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
13462   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
13463   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
13464   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
13465   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
13466   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
13467   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
13468   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
13469   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
13470   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
13471   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
13472   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
13473   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
13474   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
13475   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
13476   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
13477   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
13478   { 0xC0000098, "STATUS_FILE_INVALID" },
13479   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
13480   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
13481   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
13482   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
13483   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
13484   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
13485   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
13486   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
13487   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
13488   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
13489   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
13490   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
13491   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
13492   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
13493   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
13494   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
13495   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
13496   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
13497   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
13498   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
13499   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
13500   { 0xC00000AE, "STATUS_PIPE_BUSY" },
13501   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
13502   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
13503   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
13504   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
13505   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
13506   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
13507   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
13508   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
13509   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
13510   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
13511   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
13512   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
13513   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
13514   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
13515   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
13516   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
13517   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
13518   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
13519   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
13520   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
13521   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
13522   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
13523   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
13524   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
13525   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
13526   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
13527   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
13528   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
13529   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
13530   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
13531   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
13532   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
13533   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
13534   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
13535   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
13536   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
13537   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
13538   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
13539   { 0xC00000D5, "STATUS_FILE_RENAMED" },
13540   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
13541   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
13542   { 0xC00000D8, "STATUS_CANT_WAIT" },
13543   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
13544   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
13545   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
13546   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
13547   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
13548   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
13549   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
13550   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
13551   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
13552   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
13553   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
13554   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
13555   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
13556   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
13557   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
13558   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
13559   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
13560   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
13561   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
13562   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
13563   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
13564   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
13565   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
13566   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
13567   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
13568   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
13569   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
13570   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
13571   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
13572   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
13573   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
13574   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
13575   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
13576   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
13577   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
13578   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
13579   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
13580   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
13581   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
13582   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
13583   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
13584   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
13585   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
13586   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
13587   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
13588   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
13589   { 0xC0000107, "STATUS_FILES_OPEN" },
13590   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
13591   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
13592   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
13593   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
13594   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
13595   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
13596   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
13597   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
13598   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
13599   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
13600   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
13601   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
13602   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
13603   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
13604   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
13605   { 0xC0000117, "STATUS_NO_LDT" },
13606   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
13607   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
13608   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
13609   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
13610   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
13611   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
13612   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
13613   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
13614   { 0xC0000120, "STATUS_CANCELLED" },
13615   { 0xC0000121, "STATUS_CANNOT_DELETE" },
13616   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
13617   { 0xC0000123, "STATUS_FILE_DELETED" },
13618   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
13619   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
13620   { 0xC0000126, "STATUS_SPECIAL_USER" },
13621   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
13622   { 0xC0000128, "STATUS_FILE_CLOSED" },
13623   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
13624   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
13625   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
13626   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
13627   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
13628   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
13629   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
13630   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
13631   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
13632   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
13633   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
13634   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
13635   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
13636   { 0xC0000136, "STATUS_OPEN_FAILED" },
13637   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
13638   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
13639   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
13640   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
13641   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
13642   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
13643   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
13644   { 0xC000013E, "STATUS_LINK_FAILED" },
13645   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
13646   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
13647   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
13648   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
13649   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
13650   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
13651   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
13652   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
13653   { 0xC0000147, "STATUS_NO_PAGEFILE" },
13654   { 0xC0000148, "STATUS_INVALID_LEVEL" },
13655   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
13656   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
13657   { 0xC000014B, "STATUS_PIPE_BROKEN" },
13658   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
13659   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
13660   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
13661   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
13662   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
13663   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
13664   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
13665   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
13666   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
13667   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
13668   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
13669   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
13670   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
13671   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
13672   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
13673   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
13674   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
13675   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
13676   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
13677   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
13678   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
13679   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
13680   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
13681   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
13682   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
13683   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
13684   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
13685   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
13686   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
13687   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
13688   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
13689   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
13690   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
13691   { 0xC000016D, "STATUS_FT_ORPHANING" },
13692   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
13693   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
13694   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
13695   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
13696   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
13697   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
13698   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
13699   { 0xC0000178, "STATUS_NO_MEDIA" },
13700   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
13701   { 0xC000017B, "STATUS_INVALID_MEMBER" },
13702   { 0xC000017C, "STATUS_KEY_DELETED" },
13703   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
13704   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
13705   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
13706   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
13707   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
13708   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
13709   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
13710   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
13711   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
13712   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
13713   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
13714   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
13715   { 0xC0000189, "STATUS_TOO_LATE" },
13716   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
13717   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
13718   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
13719   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
13720   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
13721   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
13722   { 0xC0000190, "STATUS_TRUST_FAILURE" },
13723   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
13724   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
13725   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
13726   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
13727   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
13728   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
13729   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
13730   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
13731   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
13732   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
13733   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
13734   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
13735   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
13736   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
13737   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
13738   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
13739   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
13740   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
13741   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
13742   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
13743   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
13744   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
13745   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
13746   { 0xC000020D, "STATUS_CONNECTION_RESET" },
13747   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
13748   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
13749   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
13750   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
13751   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
13752   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
13753   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
13754   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
13755   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
13756   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
13757   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
13758   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
13759   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
13760   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
13761   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
13762   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
13763   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
13764   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
13765   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
13766   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
13767   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
13768   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
13769   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
13770   { 0xC0000225, "STATUS_NOT_FOUND" },
13771   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
13772   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
13773   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
13774   { 0xC0000229, "STATUS_FAIL_CHECK" },
13775   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
13776   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
13777   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
13778   { 0xC000022D, "STATUS_RETRY" },
13779   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
13780   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
13781   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
13782   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
13783   { 0xC0000232, "STATUS_INVALID_VARIANT" },
13784   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
13785   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
13786   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
13787   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
13788   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
13789   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
13790   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
13791   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
13792   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
13793   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
13794   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
13795   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
13796   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
13797   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
13798   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
13799   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
13800   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
13801   { 0xC0000244, "STATUS_AUDIT_FAILED" },
13802   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
13803   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
13804   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
13805   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
13806   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
13807   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
13808   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
13809   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
13810   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
13811   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
13812   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
13813   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
13814   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
13815   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
13816   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
13817   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
13818   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
13819   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
13820   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
13821   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
13822   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
13823   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
13824   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
13825   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
13826   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
13827   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
13828   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
13829   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
13830   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
13831   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
13832   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
13833   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
13834   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
13835   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
13836   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
13837   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
13838   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
13839   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
13840   { 0xC0000272, "STATUS_NO_MATCH" },
13841   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
13842   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
13843   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
13844   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
13845   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
13846   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
13847   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
13848   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
13849   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
13850   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
13851   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
13852   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
13853   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
13854   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
13855   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
13856   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
13857   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
13858   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
13859   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
13860   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
13861   { 0xC000028E, "STATUS_NO_EFS" },
13862   { 0xC000028F, "STATUS_WRONG_EFS" },
13863   { 0xC0000290, "STATUS_NO_USER_KEYS" },
13864   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
13865   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
13866   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
13867   { 0x40000294, "STATUS_WAKE_SYSTEM" },
13868   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
13869   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
13870   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
13871   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
13872   { 0xC0000299, "STATUS_SHARED_POLICY" },
13873   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
13874   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
13875   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
13876   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
13877   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
13878   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
13879   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
13880   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
13881   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
13882   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
13883   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
13884   { 0xC00002A5, "STATUS_DS_BUSY" },
13885   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
13886   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
13887   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
13888   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
13889   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
13890   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
13891   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
13892   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
13893   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
13894   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
13895   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
13896   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
13897   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
13898   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
13899   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
13900   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
13901   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
13902   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
13903   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
13904   { 0xC00002B9, "STATUS_NOINTERFACE" },
13905   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
13906   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
13907   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
13908   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
13909   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
13910   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
13911   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
13912   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
13913   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
13914   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
13915   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
13916   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
13917   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
13918   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
13919   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
13920   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
13921   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
13922   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
13923   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
13924   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
13925   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
13926   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
13927   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
13928   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
13929   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
13930   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
13931   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
13932   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
13933   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
13934   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
13935   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
13936   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
13937   { 0xC00002E1, "STATUS_DS_CANT_START" },
13938   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
13939   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
13940   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
13941   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
13942   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
13943   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
13944   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
13945   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
13946   { 0xC0009898, "STATUS_WOW_ASSERTION" },
13947   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
13948   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
13949   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
13950   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
13951   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
13952   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
13953   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
13954   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
13955   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
13956   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
13957   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
13958   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
13959   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
13960   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
13961   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
13962   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
13963   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
13964   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
13965   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
13966   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
13967   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
13968   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
13969   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
13970   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
13971   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
13972   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
13973   { 0xC002001B, "RPC_NT_CALL_FAILED" },
13974   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
13975   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
13976   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
13977   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
13978   { 0xC0020022, "RPC_NT_INVALID_TAG" },
13979   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
13980   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
13981   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
13982   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
13983   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
13984   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
13985   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
13986   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
13987   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
13988   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
13989   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
13990   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
13991   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
13992   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
13993   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
13994   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
13995   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
13996   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
13997   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
13998   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
13999   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
14000   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
14001   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
14002   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
14003   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
14004   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
14005   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
14006   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
14007   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
14008   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
14009   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
14010   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
14011   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
14012   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
14013   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
14014   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
14015   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
14016   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
14017   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
14018   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
14019   { 0xC002100A, "RPC_P_SEND_FAILED" },
14020   { 0xC002100B, "RPC_P_TIMEOUT" },
14021   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
14022   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
14023   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
14024   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
14025   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
14026   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
14027   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
14028   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
14029   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
14030   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
14031   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
14032   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
14033   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
14034   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
14035   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
14036   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
14037   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
14038   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
14039   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
14040   { 0xC002004C, "EPT_NT_CANT_CREATE" },
14041   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
14042   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
14043   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
14044   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
14045   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
14046   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
14047   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
14048   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
14049   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
14050   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
14051   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
14052   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
14053   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
14054   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
14055   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
14056   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
14057   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
14058   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
14059   { 0,          NULL }
14060 };
14061
14062
14063
14064 static const true_false_string tfs_smb_flags_lock = {
14065         "Lock&Read, Write&Unlock are supported",
14066         "Lock&Read, Write&Unlock are not supported"
14067 };
14068 static const true_false_string tfs_smb_flags_receive_buffer = {
14069         "Receive buffer has been posted",
14070         "Receive buffer has not been posted"
14071 };
14072 static const true_false_string tfs_smb_flags_caseless = {
14073         "Path names are caseless",
14074         "Path names are case sensitive"
14075 };
14076 static const true_false_string tfs_smb_flags_canon = {
14077         "Pathnames are canonicalized",
14078         "Pathnames are not canonicalized"
14079 };
14080 static const true_false_string tfs_smb_flags_oplock = {
14081         "OpLock requested/granted",
14082         "OpLock not requested/granted"
14083 };
14084 static const true_false_string tfs_smb_flags_notify = {
14085         "Notify client on all modifications",
14086         "Notify client only on open"
14087 };
14088 static const true_false_string tfs_smb_flags_response = {
14089         "Message is a response to the client/redirector",
14090         "Message is a request to the server"
14091 };
14092
14093 static int
14094 dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14095 {
14096         guint8 mask;
14097         proto_item *item = NULL;
14098         proto_tree *tree = NULL;
14099
14100         mask = tvb_get_guint8(tvb, offset);
14101
14102         if(parent_tree){
14103                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
14104                         "Flags: 0x%02x", mask);
14105                 tree = proto_item_add_subtree(item, ett_smb_flags);
14106         }
14107         proto_tree_add_boolean(tree, hf_smb_flags_response,
14108                 tvb, offset, 1, mask);
14109         proto_tree_add_boolean(tree, hf_smb_flags_notify,
14110                 tvb, offset, 1, mask);
14111         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
14112                 tvb, offset, 1, mask);
14113         proto_tree_add_boolean(tree, hf_smb_flags_canon,
14114                 tvb, offset, 1, mask);
14115         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
14116                 tvb, offset, 1, mask);
14117         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
14118                 tvb, offset, 1, mask);
14119         proto_tree_add_boolean(tree, hf_smb_flags_lock,
14120                 tvb, offset, 1, mask);
14121         offset += 1;
14122         return offset;
14123 }
14124
14125
14126  
14127 static const true_false_string tfs_smb_flags2_long_names_allowed = {
14128         "Long file names are allowed in the response",
14129         "Long file names are not allowed in the response"
14130 };
14131 static const true_false_string tfs_smb_flags2_ea = {
14132         "Extended attributes are supported",
14133         "Extended attributes are not supported"
14134 };
14135 static const true_false_string tfs_smb_flags2_sec_sig = {
14136         "Security signatures are supported",
14137         "Security signatures are not supported"
14138 };
14139 static const true_false_string tfs_smb_flags2_long_names_used = {
14140         "Path names in request are long file names",
14141         "Path names in request are not long file names"
14142 };
14143 static const true_false_string tfs_smb_flags2_esn = {
14144         "Extended security negotiation is supported",
14145         "Extended security negotiation is not supported"
14146 };
14147 static const true_false_string tfs_smb_flags2_dfs = {
14148         "Resolve pathnames with Dfs",
14149         "Don't resolve pathnames with Dfs"
14150 };
14151 static const true_false_string tfs_smb_flags2_roe = {
14152         "Permit reads if execute-only",
14153         "Don't permit reads if execute-only"
14154 };
14155 static const true_false_string tfs_smb_flags2_nt_error = {
14156         "Error codes are NT error codes",
14157         "Error codes are DOS error codes"
14158 };
14159 static const true_false_string tfs_smb_flags2_string = {
14160         "Strings are Unicode",
14161         "Strings are ASCII"
14162 };
14163 static int
14164 dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14165 {
14166         guint16 mask;
14167         proto_item *item = NULL;
14168         proto_tree *tree = NULL;
14169
14170         mask = tvb_get_letohs(tvb, offset);
14171
14172         if(parent_tree){
14173                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
14174                         "Flags2: 0x%04x", mask);
14175                 tree = proto_item_add_subtree(item, ett_smb_flags2);
14176         }
14177
14178         proto_tree_add_boolean(tree, hf_smb_flags2_string,
14179                 tvb, offset, 2, mask);
14180         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
14181                 tvb, offset, 2, mask);
14182         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
14183                 tvb, offset, 2, mask);
14184         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
14185                 tvb, offset, 2, mask);
14186         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
14187                 tvb, offset, 2, mask);
14188         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
14189                 tvb, offset, 2, mask);
14190         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
14191                 tvb, offset, 2, mask);
14192         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
14193                 tvb, offset, 2, mask);
14194         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
14195                 tvb, offset, 2, mask);
14196
14197         offset += 2;
14198         return offset;
14199 }
14200
14201
14202
14203 #define SMB_FLAGS_DIRN 0x80
14204
14205
14206 static gboolean
14207 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14208 {
14209         int offset = 0;
14210         proto_item *item = NULL, *hitem = NULL;
14211         proto_tree *tree = NULL, *htree = NULL;
14212         guint8          flags;
14213         guint16         flags2;
14214         smb_info_t      si;
14215         smb_saved_info_t *sip = NULL;
14216         smb_saved_info_key_t key;
14217         smb_saved_info_key_t *new_key;
14218         guint32 nt_status = 0;
14219         guint8 errclass = 0;
14220         guint16 errcode = 0;
14221         guint32 pid_mid;
14222         conversation_t *conversation;
14223
14224         top_tree=parent_tree;
14225
14226         /* must check that this really is a smb packet */
14227         if (!tvb_bytes_exist(tvb, 0, 4))
14228                 return FALSE;
14229
14230         if( (tvb_get_guint8(tvb, 0) != 0xff)
14231             || (tvb_get_guint8(tvb, 1) != 'S')
14232             || (tvb_get_guint8(tvb, 2) != 'M')
14233             || (tvb_get_guint8(tvb, 3) != 'B') ){
14234                 return FALSE;
14235         }
14236          
14237         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
14238                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
14239         }
14240         if (check_col(pinfo->cinfo, COL_INFO)){
14241                 col_clear(pinfo->cinfo, COL_INFO);
14242         }
14243
14244         /* start off using the local variable, we will allocate a new one if we
14245            need to*/
14246         si.cmd = tvb_get_guint8(tvb, offset+4);
14247         flags = tvb_get_guint8(tvb, offset+9);
14248         si.request = !(flags&SMB_FLAGS_DIRN);
14249         flags2 = tvb_get_letohs(tvb, offset+10);
14250         if(flags2 & 0x8000){
14251                 si.unicode = TRUE; /* Mark them as Unicode */
14252         } else {
14253                 si.unicode = FALSE;
14254         }
14255         si.tid = tvb_get_letohs(tvb, offset+24);
14256         si.pid = tvb_get_letohs(tvb, offset+26);
14257         si.uid = tvb_get_letohs(tvb, offset+28);
14258         si.mid = tvb_get_letohs(tvb, offset+30);
14259         pid_mid = (si.pid << 16) | si.mid;
14260         si.info_level = -1;
14261         si.info_count = -1;
14262
14263         if (parent_tree) {
14264                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
14265                         -1, FALSE);
14266                 tree = proto_item_add_subtree(item, ett_smb);
14267
14268                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
14269                         "SMB Header");
14270
14271                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
14272         }
14273
14274         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
14275         offset += 4;  /* Skip the marker */
14276
14277         /* find which conversation we are part of and get the tables for that 
14278            conversation*/
14279         conversation = find_conversation(&pinfo->src, &pinfo->dst,
14280                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
14281         if(conversation){
14282                 si.ct=conversation_get_proto_data(conversation, proto_smb);
14283         } else {
14284                 /* OK this is a new conversation, we must create it
14285                    and attach appropriate data (matched and unmatched 
14286                    table for this conversation)
14287                 */
14288                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
14289                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
14290                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
14291                 conv_tables = g_slist_prepend(conv_tables, si.ct);
14292                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
14293                         smb_saved_info_equal_matched);
14294                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
14295                         smb_saved_info_equal_unmatched);
14296                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
14297                         smb_saved_info_hash_unmatched, 
14298                         smb_saved_info_equal_unmatched);
14299                 si.ct->tid_service=g_hash_table_new(
14300                         smb_saved_info_hash_unmatched, 
14301                         smb_saved_info_equal_unmatched);
14302                 conversation_add_proto_data(conversation, proto_smb, si.ct);
14303         }
14304
14305         if( (si.request)
14306             &&  (si.mid==0)
14307             &&  (si.uid==0)
14308             &&  (si.pid==0)
14309             &&  (si.tid==0) ){
14310                 /* this is a broadcast SMB packet, there will not be a reply.
14311                    We dont need to do anything 
14312                 */
14313                 si.unidir = TRUE;
14314         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
14315                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
14316                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
14317                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
14318                 /* Ok, we got a special request type. This request is either
14319                    an NT Cancel or a continuation relative to a real request
14320                    in an earlier packet.  In either case, we don't expect any
14321                    responses to this packet.  For continuations, any later
14322                    responses we see really just belong to the original request.
14323                    Anyway, we want to remember this packet somehow and
14324                    remember which original request it is associated with so
14325                    we can say nice things such as "This is a Cancellation to
14326                    the request in frame x", but we don't want the
14327                    request/response matching to get messed up.
14328
14329                    The only thing we do in this case is trying to find which original
14330                    request we match with and insert an entry for this "special" 
14331                    request for later reference. We continue to reference the original
14332                    requests smb_saved_info_t but we dont touch it or change anything
14333                    in it.
14334                 */
14335
14336                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
14337
14338                 if(!pinfo->fd->flags.visited){
14339                         /* try to find which original call we match and if we 
14340                            find it add us to the matched table. Dont touch
14341                            anything else since we dont want this one to mess
14342                            up the request/response matching. We still consider
14343                            the initial call the real request and this is only
14344                            some sort of continuation.
14345                         */
14346                         /* we only check the unmatched table and assume that the
14347                            last seen MID matching ours is the right one.
14348                            This can fail but is better than nothing
14349                         */
14350                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14351                         if(sip!=NULL){
14352                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14353                                 new_key->frame = pinfo->fd->num;
14354                                 new_key->pid_mid = pid_mid;
14355                                 g_hash_table_insert(si.ct->matched, new_key,
14356                                     sip);
14357                         }
14358                 } else {
14359                         /* we have seen this packet before; check the
14360                            matching table
14361                         */
14362                         key.frame = pinfo->fd->num;
14363                         key.pid_mid = pid_mid;
14364                         sip=g_hash_table_lookup(si.ct->matched, &key);
14365                         if(sip==NULL){
14366                         /*
14367                           We didn't find it.
14368                           Too bad, unfortunately there is not really much we can
14369                           do now since this means that we never saw the initial
14370                           request.
14371                          */
14372                         }
14373                 }
14374
14375
14376                 if(sip && sip->frame_req){
14377                         switch(si.cmd){
14378                         case SMB_COM_NT_CANCEL:
14379                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
14380                                                     tvb, 0, 0, sip->frame_req);
14381                                 break;
14382                         case SMB_COM_TRANSACTION_SECONDARY:
14383                         case SMB_COM_TRANSACTION2_SECONDARY:
14384                         case SMB_COM_NT_TRANSACT_SECONDARY:
14385                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
14386                                                     tvb, 0, 0, sip->frame_req);
14387                                 break;
14388                         }
14389                 } else {
14390                         switch(si.cmd){
14391                         case SMB_COM_NT_CANCEL:
14392                                 proto_tree_add_text(htree, tvb, 0, 0,
14393                                                     "Cancellation to: <unknown frame>");
14394                                 break;
14395                         case SMB_COM_TRANSACTION_SECONDARY:
14396                         case SMB_COM_TRANSACTION2_SECONDARY:
14397                         case SMB_COM_NT_TRANSACT_SECONDARY:
14398                                 proto_tree_add_text(htree, tvb, 0, 0,
14399                                                     "Continuation to: <unknown frame>");
14400                                 break;
14401                         }
14402                 }
14403         } else { /* normal bidirectional request or response */
14404                 si.unidir = FALSE;
14405
14406                 if(!pinfo->fd->flags.visited){
14407                         /* first see if we find an unmatched smb "equal" to 
14408                            the current one 
14409                         */
14410                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14411                         if(sip!=NULL){
14412                                 gboolean cmd_match=FALSE;
14413
14414                                 /*
14415                                  * Make sure the SMB we found was the
14416                                  * same command, or a different command
14417                                  * that's another valid type of reply
14418                                  * to that command.
14419                                  */
14420                                 if(si.cmd==sip->cmd){
14421                                         cmd_match=TRUE;
14422                                 }
14423                                 else if(si.cmd==SMB_COM_NT_CANCEL){
14424                                         cmd_match=TRUE;
14425                                 }
14426                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
14427                                      && (sip->cmd==SMB_COM_TRANSACTION)){
14428                                         cmd_match=TRUE;
14429                                 }
14430                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
14431                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
14432                                         cmd_match=TRUE;
14433                                 }
14434                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
14435                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
14436                                         cmd_match=TRUE;
14437                                 }
14438
14439                                 if( (si.request) || (!cmd_match) ) {
14440                                         /* If we are processing an SMB request but there was already
14441                                            another "identical" smb resuest we had not matched yet.
14442                                            This must mean that either we have a retransmission or that the
14443                                            response to the previous one was lost and the client has reused
14444                                            the MID for this conversation. In either case it's not much more
14445                                            we can do than forget the old request and concentrate on the 
14446                                            present one instead.
14447
14448                                            We also do this cleanup if we see that the cmd in the original
14449                                            request in sip->cmd is not compatible with the current cmd.
14450                                            This is to prevent matching errors such as if there were two
14451                                            SMBs of different cmds but with identical MID and PID values and
14452                                            if ethereal lost the first reply and the second request.
14453                                         */
14454                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
14455                                         sip=NULL; /* XXX should free it as well */
14456                                 } else {
14457                                         /* we have found a response to some request we have seen earlier.
14458                                            What we do now depends on whether this is the first response
14459                                            to that request we see (id frame_res==0) or not. 
14460                                         */
14461                                         if(sip->frame_res==0){
14462                                                 /* ok it is the first response we have seen to this packet */
14463                                                 sip->frame_res = pinfo->fd->num;
14464                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14465                                                 new_key->frame = sip->frame_req;
14466                                                 new_key->pid_mid = pid_mid;
14467                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14468                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14469                                                 new_key->frame = sip->frame_res;
14470                                                 new_key->pid_mid = pid_mid;
14471                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14472                                         } else {
14473                                                 /* we have already seen another response to this one, but
14474                                                    register it anyway so we see which request it matches 
14475                                                 */
14476                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14477                                                 new_key->frame = pinfo->fd->num;
14478                                                 new_key->pid_mid = pid_mid;
14479                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14480                                         }
14481                                 }
14482                         }
14483                         if(si.request){
14484                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
14485                                 sip->frame_req = pinfo->fd->num;
14486                                 sip->frame_res = 0;
14487                                 sip->flags = 0;
14488                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
14489                                     == (void *)TID_IPC) {
14490                                         sip->flags |= SMB_SIF_TID_IS_IPC;
14491                                 }
14492                                 sip->cmd = si.cmd;
14493                                 sip->extra_info = NULL;
14494                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
14495                         }
14496                 } else {
14497                         /* we have seen this packet before; check the
14498                            matching table.
14499                            If we haven't yet seen the reply, we won't
14500                            find the info for it; we don't need it, as
14501                            we only use it to save information, and, as
14502                            we've seen this packet before, we've already
14503                            saved the information.
14504                         */
14505                         key.frame = pinfo->fd->num;
14506                         key.pid_mid = pid_mid;
14507                         sip=g_hash_table_lookup(si.ct->matched, &key);
14508                 }
14509         }
14510
14511         /*
14512          * Pass the "sip" on to subdissectors through "si".
14513          */
14514         si.sip = sip;
14515
14516         if (sip != NULL) {
14517                 /*
14518                  * Put in fields for the frame number of the frame to which
14519                  * this is a response or the frame with the response to this
14520                  * frame - if we know the frame number (i.e., it's not 0).
14521                  */
14522                 if(si.request){
14523                         if (sip->frame_res != 0)
14524                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
14525                 } else {
14526                         if (sip->frame_req != 0)
14527                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
14528                 }
14529         }
14530
14531         /* smb command */
14532         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);
14533         offset += 1;
14534
14535         if(flags2 & 0x4000){
14536                 /* handle NT 32 bit error code */
14537
14538                 nt_status = tvb_get_letohl(tvb, offset);
14539
14540                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
14541                         TRUE);
14542                 offset += 4;
14543
14544         } else {
14545                 /* handle DOS error code & class */
14546                 errclass = tvb_get_guint8(tvb, offset);
14547                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
14548                         errclass);
14549                 offset += 1;
14550
14551                 /* reserved byte */
14552                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
14553                 offset += 1;
14554
14555                 /* error code */
14556                 /* XXX - the type of this field depends on the value of
14557                  * "errcls", so there is isn't a single value_string array
14558                  * fo it, so there can't be a single field for it.
14559                  */
14560                 errcode = tvb_get_letohs(tvb, offset);
14561                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
14562                         offset, 2, errcode, "Error Code: %s",
14563                         decode_smb_error(errclass, errcode));
14564                 offset += 2;
14565         }
14566
14567         /* flags */
14568         offset = dissect_smb_flags(tvb, pinfo, htree, offset);
14569
14570         /* flags2 */
14571         offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
14572
14573         /*
14574          * The document at
14575          *
14576          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
14577          *
14578          * (a text version of "Microsoft Networks SMB FILE SHARING
14579          * PROTOCOL, Document Version 6.0p") says that:
14580          *
14581          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
14582          *      the "High Part of PID";
14583          *
14584          *      the next four bytes are reserved;
14585          *
14586          *      the next four bytes are, for SMB-over-IPX (with no
14587          *      NetBIOS involved) two bytes of Session ID and two bytes
14588          *      of SequenceNumber.
14589          *
14590          * If we ever implement SMB-over-IPX (which I suspect goes over
14591          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
14592          * document in question), we'd probably want to have some way
14593          * to determine whether this is SMB-over-IPX or not (which could
14594          * be done by adding a PT_IPXSOCKET port type, having the
14595          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
14596          * and having the SMB dissector check for a port type of
14597          * PT_IPXSOCKET and for "pinfo->match_port" being either
14598          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
14599          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
14600          */
14601
14602         /* 12 reserved bytes */
14603         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
14604         offset += 12;
14605
14606         /* TID */
14607         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
14608         offset += 2;
14609
14610         /* PID */
14611         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
14612         offset += 2;
14613
14614         /* UID */
14615         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
14616         offset += 2;
14617
14618         /* MID */
14619         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
14620         offset += 2;
14621
14622         pinfo->private_data = &si;
14623         dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
14624
14625         /* Append error info from this packet to info string. */
14626         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
14627                 if (flags2 & 0x4000) {
14628                         /*
14629                          * The status is an NT status code; was there
14630                          * an error?
14631                          */
14632                         if (nt_status != 0) {
14633                                 /*
14634                                  * Yes.
14635                                  */
14636                                 col_append_fstr(
14637                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14638                                         val_to_str(nt_status, NT_errors,
14639                                             "Unknown (0x%08X)"));
14640                         }
14641                 } else {
14642                         /*
14643                          * The status is a DOS error class and code; was
14644                          * there an error?
14645                          */
14646                         if (errclass != SMB_SUCCESS) {
14647                                 /*
14648                                  * Yes.
14649                                  */
14650                                 col_append_fstr(
14651                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14652                                         decode_smb_error(errclass, errcode));
14653                         }
14654                 }
14655         }
14656
14657         return TRUE;
14658 }
14659
14660 void
14661 proto_register_smb(void)
14662 {
14663         static hf_register_info hf[] = {
14664         { &hf_smb_cmd,
14665                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
14666                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
14667
14668         { &hf_smb_word_count,
14669                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
14670                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
14671
14672         { &hf_smb_byte_count,
14673                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
14674                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
14675
14676         { &hf_smb_response_to,
14677                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
14678                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
14679
14680         { &hf_smb_response_in,
14681                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
14682                 NULL, 0, "The response to this packet is in this packet", HFILL }},
14683
14684         { &hf_smb_continuation_to,
14685                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
14686                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
14687
14688         { &hf_smb_nt_status,
14689                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
14690                 VALS(NT_errors), 0, "NT Status code", HFILL }},
14691
14692         { &hf_smb_error_class,
14693                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
14694                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
14695
14696         { &hf_smb_error_code,
14697                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
14698                 NULL, 0, "DOS Error Code", HFILL }},
14699
14700         { &hf_smb_reserved,
14701                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
14702                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
14703
14704         { &hf_smb_pid,
14705                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
14706                 NULL, 0, "Process ID", HFILL }},
14707
14708         { &hf_smb_tid,
14709                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
14710                 NULL, 0, "Tree ID", HFILL }},
14711
14712         { &hf_smb_uid,
14713                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
14714                 NULL, 0, "User ID", HFILL }},
14715
14716         { &hf_smb_mid,
14717                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
14718                 NULL, 0, "Multiplex ID", HFILL }},
14719
14720         { &hf_smb_flags_lock,
14721                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
14722                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
14723
14724         { &hf_smb_flags_receive_buffer,
14725                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
14726                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
14727
14728         { &hf_smb_flags_caseless,
14729                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
14730                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
14731
14732         { &hf_smb_flags_canon,
14733                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
14734                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
14735
14736         { &hf_smb_flags_oplock,
14737                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
14738                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
14739
14740         { &hf_smb_flags_notify,
14741                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
14742                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
14743
14744         { &hf_smb_flags_response,
14745                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
14746                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
14747
14748         { &hf_smb_flags2_long_names_allowed,
14749                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
14750                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
14751
14752         { &hf_smb_flags2_ea,
14753                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
14754                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
14755
14756         { &hf_smb_flags2_sec_sig,
14757                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
14758                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
14759
14760         { &hf_smb_flags2_long_names_used,
14761                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
14762                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
14763
14764         { &hf_smb_flags2_esn,
14765                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
14766                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
14767
14768         { &hf_smb_flags2_dfs,
14769                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
14770                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
14771
14772         { &hf_smb_flags2_roe,
14773                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
14774                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
14775
14776         { &hf_smb_flags2_nt_error,
14777                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
14778                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
14779
14780         { &hf_smb_flags2_string,
14781                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
14782                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
14783
14784         { &hf_smb_buffer_format,
14785                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
14786                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
14787
14788         { &hf_smb_dialect_name,
14789                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
14790                 NULL, 0, "Name of dialect", HFILL }},
14791
14792         { &hf_smb_dialect_index,
14793                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
14794                 NULL, 0, "Index of selected dialect", HFILL }},
14795
14796         { &hf_smb_max_trans_buf_size,
14797                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
14798                 NULL, 0, "Maximum transmit buffer size", HFILL }},
14799
14800         { &hf_smb_max_mpx_count,
14801                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
14802                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
14803
14804         { &hf_smb_max_vcs_num,
14805                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
14806                 NULL, 0, "Maximum VCs between client and server", HFILL }},
14807
14808         { &hf_smb_session_key,
14809                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
14810                 NULL, 0, "Unique token identifying this session", HFILL }},
14811
14812         { &hf_smb_server_timezone,
14813                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
14814                 NULL, 0, "Current timezone at server.", HFILL }},
14815
14816         { &hf_smb_encryption_key_length,
14817                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
14818                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
14819
14820         { &hf_smb_encryption_key,
14821                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
14822                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
14823
14824         { &hf_smb_primary_domain,
14825                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
14826                 NULL, 0, "The server's primary domain", HFILL }},
14827
14828         { &hf_smb_max_raw_buf_size,
14829                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
14830                 NULL, 0, "Maximum raw buffer size", HFILL }},
14831
14832         { &hf_smb_server_guid,
14833                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
14834                 NULL, 0, "Globally unique identifier for this server", HFILL }},
14835
14836         { &hf_smb_security_blob_len,
14837                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
14838                 NULL, 0, "Security blob length", HFILL }},
14839
14840         { &hf_smb_security_blob,
14841                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
14842                 NULL, 0, "Security blob", HFILL }},
14843
14844         { &hf_smb_sm_mode16,
14845                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
14846                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14847
14848         { &hf_smb_sm_password16,
14849                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
14850                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14851
14852         { &hf_smb_sm_mode,
14853                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
14854                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14855
14856         { &hf_smb_sm_password,
14857                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
14858                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14859
14860         { &hf_smb_sm_signatures,
14861                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
14862                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
14863
14864         { &hf_smb_sm_sig_required,
14865                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
14866                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
14867
14868         { &hf_smb_rm_read,
14869                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
14870                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
14871
14872         { &hf_smb_rm_write,
14873                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
14874                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
14875
14876         { &hf_smb_server_date_time,
14877                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
14878                 NULL, 0, "Current date and time at server", HFILL }},
14879
14880         { &hf_smb_server_smb_date,
14881                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
14882                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
14883
14884         { &hf_smb_server_smb_time,
14885                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
14886                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
14887
14888         { &hf_smb_server_cap_raw_mode,
14889                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
14890                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
14891
14892         { &hf_smb_server_cap_mpx_mode,
14893                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
14894                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
14895
14896         { &hf_smb_server_cap_unicode,
14897                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
14898                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
14899
14900         { &hf_smb_server_cap_large_files,
14901                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
14902                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
14903
14904         { &hf_smb_server_cap_nt_smbs,
14905                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
14906                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
14907
14908         { &hf_smb_server_cap_rpc_remote_apis,
14909                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
14910                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
14911
14912         { &hf_smb_server_cap_nt_status,
14913                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
14914                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
14915
14916         { &hf_smb_server_cap_level_ii_oplocks,
14917                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
14918                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
14919
14920         { &hf_smb_server_cap_lock_and_read,
14921                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
14922                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
14923
14924         { &hf_smb_server_cap_nt_find,
14925                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
14926                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
14927
14928         { &hf_smb_server_cap_dfs,
14929                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
14930                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
14931
14932         { &hf_smb_server_cap_infolevel_passthru,
14933                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
14934                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
14935
14936         { &hf_smb_server_cap_large_readx,
14937                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
14938                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
14939
14940         { &hf_smb_server_cap_large_writex,
14941                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
14942                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
14943
14944         { &hf_smb_server_cap_unix,
14945                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
14946                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
14947
14948         { &hf_smb_server_cap_reserved,
14949                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
14950                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
14951
14952         { &hf_smb_server_cap_bulk_transfer,
14953                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
14954                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
14955
14956         { &hf_smb_server_cap_compressed_data,
14957                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
14958                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
14959
14960         { &hf_smb_server_cap_extended_security,
14961                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
14962                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
14963
14964         { &hf_smb_system_time,
14965                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
14966                 NULL, 0, "System Time", HFILL }},
14967
14968         { &hf_smb_unknown,
14969                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
14970                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
14971
14972         { &hf_smb_dir_name,
14973                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
14974                 NULL, 0, "SMB Directory Name", HFILL }},
14975
14976         { &hf_smb_echo_count,
14977                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
14978                 NULL, 0, "Number of times to echo data back", HFILL }},
14979
14980         { &hf_smb_echo_data,
14981                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
14982                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
14983
14984         { &hf_smb_echo_seq_num,
14985                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
14986                 NULL, 0, "Sequence number for this echo response", HFILL }},
14987
14988         { &hf_smb_max_buf_size,
14989                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
14990                 NULL, 0, "Max client buffer size", HFILL }},
14991
14992         { &hf_smb_path,
14993                 { "Path", "smb.path", FT_STRING, BASE_NONE,
14994                 NULL, 0, "Path. Server name and share name", HFILL }},
14995
14996         { &hf_smb_service,
14997                 { "Service", "smb.service", FT_STRING, BASE_NONE,
14998                 NULL, 0, "Service name", HFILL }},
14999
15000         { &hf_smb_password,
15001                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15002                 NULL, 0, "Password", HFILL }},
15003
15004         { &hf_smb_ansi_password,
15005                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15006                 NULL, 0, "ANSI Password", HFILL }},
15007
15008         { &hf_smb_unicode_password,
15009                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15010                 NULL, 0, "Unicode Password", HFILL }},
15011
15012         { &hf_smb_move_flags_file,
15013                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15014                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15015
15016         { &hf_smb_move_flags_dir,
15017                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15018                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15019
15020         { &hf_smb_move_flags_verify,
15021                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15022                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15023
15024         { &hf_smb_move_files_moved,
15025                 { "Files Moved", "smb.move.files_moved", FT_UINT16, BASE_DEC,
15026                 NULL, 0, "Number of files moved", HFILL }},
15027
15028         { &hf_smb_count,
15029                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
15030                 NULL, 0, "Count number of items/bytes", HFILL }},
15031
15032         { &hf_smb_file_name,
15033                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
15034                 NULL, 0, "File Name", HFILL }},
15035
15036         { &hf_smb_open_function_create,
15037                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
15038                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
15039
15040         { &hf_smb_open_function_open,
15041                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
15042                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
15043
15044         { &hf_smb_fid,
15045                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
15046                 NULL, 0, "FID: File ID", HFILL }},
15047
15048         { &hf_smb_file_attr_read_only_16bit,
15049                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
15050                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15051
15052         { &hf_smb_file_attr_read_only_8bit,
15053                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
15054                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15055
15056         { &hf_smb_file_attr_hidden_16bit,
15057                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
15058                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15059
15060         { &hf_smb_file_attr_hidden_8bit,
15061                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
15062                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15063
15064         { &hf_smb_file_attr_system_16bit,
15065                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
15066                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15067
15068         { &hf_smb_file_attr_system_8bit,
15069                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
15070                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15071
15072         { &hf_smb_file_attr_volume_16bit,
15073                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
15074                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15075
15076         { &hf_smb_file_attr_volume_8bit,
15077                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
15078                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
15079
15080         { &hf_smb_file_attr_directory_16bit,
15081                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
15082                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15083
15084         { &hf_smb_file_attr_directory_8bit,
15085                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
15086                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15087
15088         { &hf_smb_file_attr_archive_16bit,
15089                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
15090                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15091
15092         { &hf_smb_file_attr_archive_8bit,
15093                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
15094                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15095
15096         { &hf_smb_file_attr_device,
15097                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
15098                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15099
15100         { &hf_smb_file_attr_normal,
15101                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
15102                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15103
15104         { &hf_smb_file_attr_temporary,
15105                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
15106                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15107
15108         { &hf_smb_file_attr_sparse,
15109                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
15110                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15111
15112         { &hf_smb_file_attr_reparse,
15113                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
15114                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15115
15116         { &hf_smb_file_attr_compressed,
15117                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
15118                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15119
15120         { &hf_smb_file_attr_offline,
15121                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
15122                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15123
15124         { &hf_smb_file_attr_not_content_indexed,
15125                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
15126                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15127
15128         { &hf_smb_file_attr_encrypted,
15129                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
15130                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15131
15132         { &hf_smb_file_size,
15133                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
15134                 NULL, 0, "File Size", HFILL }},
15135
15136         { &hf_smb_search_attribute_read_only,
15137                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
15138                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
15139
15140         { &hf_smb_search_attribute_hidden,
15141                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
15142                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
15143
15144         { &hf_smb_search_attribute_system,
15145                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
15146                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
15147
15148         { &hf_smb_search_attribute_volume,
15149                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
15150                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
15151
15152         { &hf_smb_search_attribute_directory,
15153                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
15154                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
15155
15156         { &hf_smb_search_attribute_archive,
15157                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
15158                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
15159
15160         { &hf_smb_access_mode,
15161                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
15162                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
15163
15164         { &hf_smb_access_sharing,
15165                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
15166                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
15167
15168         { &hf_smb_access_locality,
15169                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
15170                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
15171
15172         { &hf_smb_access_caching,
15173                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
15174                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
15175
15176         { &hf_smb_access_writetru,
15177                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
15178                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
15179
15180         { &hf_smb_create_time,
15181                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
15182                 NULL, 0, "Creation Time", HFILL }},
15183
15184         { &hf_smb_create_dos_date,
15185                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
15186                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
15187
15188         { &hf_smb_create_dos_time,
15189                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
15190                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
15191
15192         { &hf_smb_last_write_time,
15193                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
15194                 NULL, 0, "Time this file was last written to", HFILL }},
15195
15196         { &hf_smb_last_write_dos_date,
15197                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
15198                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
15199
15200         { &hf_smb_last_write_dos_time,
15201                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
15202                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
15203
15204         { &hf_smb_old_file_name,
15205                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
15206                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
15207
15208         { &hf_smb_offset,
15209                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
15210                 NULL, 0, "Offset in file", HFILL }},
15211
15212         { &hf_smb_remaining,
15213                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
15214                 NULL, 0, "Remaining number of bytes", HFILL }},
15215
15216         { &hf_smb_padding,
15217                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
15218                 NULL, 0, "Padding or unknown data", HFILL }},
15219
15220         { &hf_smb_file_data,
15221                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
15222                 NULL, 0, "Data read/written to the file", HFILL }},
15223
15224         { &hf_smb_total_data_len,
15225                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
15226                 NULL, 0, "Total length of data", HFILL }},
15227
15228         { &hf_smb_data_len,
15229                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
15230                 NULL, 0, "Length of data", HFILL }},
15231
15232         { &hf_smb_seek_mode,
15233                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
15234                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
15235
15236         { &hf_smb_access_time,
15237                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
15238                 NULL, 0, "Last Access Time", HFILL }},
15239
15240         { &hf_smb_access_dos_date,
15241                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
15242                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
15243
15244         { &hf_smb_access_dos_time,
15245                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
15246                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
15247
15248         { &hf_smb_data_size,
15249                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
15250                 NULL, 0, "Data Size", HFILL }},
15251
15252         { &hf_smb_alloc_size,
15253                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
15254                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15255
15256         { &hf_smb_max_count,
15257                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
15258                 NULL, 0, "Maximum Count", HFILL }},
15259
15260         { &hf_smb_min_count,
15261                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
15262                 NULL, 0, "Minimum Count", HFILL }},
15263
15264         { &hf_smb_timeout,
15265                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
15266                 NULL, 0, "Timeout in miliseconds", HFILL }},
15267
15268         { &hf_smb_high_offset,
15269                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
15270                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
15271
15272         { &hf_smb_units,
15273                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
15274                 NULL, 0, "Total number of units at server", HFILL }},
15275
15276         { &hf_smb_bpu,
15277                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
15278                 NULL, 0, "Blocks per unit at server", HFILL }},
15279
15280         { &hf_smb_blocksize,
15281                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
15282                 NULL, 0, "Block size (in bytes) at server", HFILL }},
15283
15284         { &hf_smb_freeunits,
15285                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
15286                 NULL, 0, "Number of free units at server", HFILL }},
15287
15288         { &hf_smb_data_offset,
15289                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15290                 NULL, 0, "Data Offset", HFILL }},
15291
15292         { &hf_smb_dcm,
15293                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
15294                 NULL, 0, "Data Compaction Mode", HFILL }},
15295
15296         { &hf_smb_request_mask,
15297                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
15298                 NULL, 0, "Connectionless mode mask", HFILL }},
15299
15300         { &hf_smb_response_mask,
15301                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
15302                 NULL, 0, "Connectionless mode mask", HFILL }},
15303
15304         { &hf_smb_sid,
15305                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
15306                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
15307
15308         { &hf_smb_write_mode_write_through,
15309                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
15310                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
15311
15312         { &hf_smb_write_mode_return_remaining,
15313                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
15314                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
15315
15316         { &hf_smb_write_mode_raw,
15317                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
15318                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
15319
15320         { &hf_smb_write_mode_message_start,
15321                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
15322                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
15323
15324         { &hf_smb_write_mode_connectionless,
15325                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
15326                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
15327
15328         { &hf_smb_resume_key_len,
15329                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
15330                 NULL, 0, "Resume Key length", HFILL }},
15331
15332         { &hf_smb_resume_server_cookie,
15333                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
15334                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
15335
15336         { &hf_smb_resume_client_cookie,
15337                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
15338                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
15339
15340         { &hf_smb_andxoffset,
15341                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
15342                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
15343
15344         { &hf_smb_lock_type_large,
15345                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
15346                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
15347
15348         { &hf_smb_lock_type_cancel,
15349                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
15350                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
15351
15352         { &hf_smb_lock_type_change,
15353                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
15354                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
15355
15356         { &hf_smb_lock_type_oplock,
15357                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
15358                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
15359
15360         { &hf_smb_lock_type_shared,
15361                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
15362                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
15363
15364         { &hf_smb_locking_ol,
15365                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
15366                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
15367
15368         { &hf_smb_number_of_locks,
15369                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
15370                 NULL, 0, "Number of lock requests in this request", HFILL }},
15371
15372         { &hf_smb_number_of_unlocks,
15373                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
15374                 NULL, 0, "Number of unlock requests in this request", HFILL }},
15375
15376         { &hf_smb_lock_long_length,
15377                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
15378                 NULL, 0, "Length of lock/unlock region", HFILL }},
15379
15380         { &hf_smb_lock_long_offset,
15381                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
15382                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
15383
15384         { &hf_smb_file_type,
15385                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
15386                 VALS(filetype_vals), 0, "Type of file", HFILL }},
15387
15388         { &hf_smb_ipc_state_nonblocking,
15389                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
15390                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
15391
15392         { &hf_smb_ipc_state_endpoint,
15393                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
15394                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
15395
15396         { &hf_smb_ipc_state_pipe_type,
15397                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
15398                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
15399
15400         { &hf_smb_ipc_state_read_mode,
15401                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
15402                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
15403
15404         { &hf_smb_ipc_state_icount,
15405                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
15406                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
15407
15408         { &hf_smb_server_fid,
15409                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
15410                 NULL, 0, "Server unique File ID", HFILL }},
15411
15412         { &hf_smb_open_flags_add_info,
15413                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
15414                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
15415
15416         { &hf_smb_open_flags_ex_oplock,
15417                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
15418                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
15419
15420         { &hf_smb_open_flags_batch_oplock,
15421                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
15422                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
15423
15424         { &hf_smb_open_flags_ealen,
15425                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
15426                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
15427
15428         { &hf_smb_open_action_open,
15429                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
15430                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
15431
15432         { &hf_smb_open_action_lock,
15433                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
15434                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
15435
15436         { &hf_smb_vc_num,
15437                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
15438                 NULL, 0, "VC Number", HFILL }},
15439
15440         { &hf_smb_password_len,
15441                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
15442                 NULL, 0, "Length of password", HFILL }},
15443
15444         { &hf_smb_ansi_password_len,
15445                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
15446                 NULL, 0, "Length of ANSI password", HFILL }},
15447
15448         { &hf_smb_unicode_password_len,
15449                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
15450                 NULL, 0, "Length of Unicode password", HFILL }},
15451
15452         { &hf_smb_account,
15453                 { "Account", "smb.account", FT_STRING, BASE_NONE,
15454                 NULL, 0, "Account, username", HFILL }},
15455
15456         { &hf_smb_os,
15457                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
15458                 NULL, 0, "Which OS we are running", HFILL }},
15459
15460         { &hf_smb_lanman,
15461                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
15462                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
15463
15464         { &hf_smb_setup_action_guest,
15465                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
15466                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
15467
15468         { &hf_smb_fs,
15469                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
15470                 NULL, 0, "Native File System", HFILL }},
15471
15472         { &hf_smb_connect_flags_dtid,
15473                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
15474                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
15475
15476         { &hf_smb_connect_support_search,
15477                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
15478                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
15479
15480         { &hf_smb_connect_support_in_dfs,
15481                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
15482                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
15483
15484         { &hf_smb_max_setup_count,
15485                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
15486                 NULL, 0, "Maximum number of setup words to return", HFILL }},
15487
15488         { &hf_smb_total_param_count,
15489                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
15490                 NULL, 0, "Total number of parameter bytes", HFILL }},
15491
15492         { &hf_smb_total_data_count,
15493                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
15494                 NULL, 0, "Total number of data bytes", HFILL }},
15495
15496         { &hf_smb_max_param_count,
15497                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
15498                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
15499
15500         { &hf_smb_max_data_count,
15501                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
15502                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
15503
15504         { &hf_smb_param_disp16,
15505                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
15506                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15507
15508         { &hf_smb_param_count16,
15509                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
15510                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15511
15512         { &hf_smb_param_offset16,
15513                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
15514                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15515
15516         { &hf_smb_param_disp32,
15517                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
15518                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15519
15520         { &hf_smb_param_count32,
15521                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
15522                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15523
15524         { &hf_smb_param_offset32,
15525                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
15526                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15527
15528         { &hf_smb_data_count16,
15529                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
15530                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15531
15532         { &hf_smb_data_disp16,
15533                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
15534                 NULL, 0, "Data Displacement", HFILL }},
15535
15536         { &hf_smb_data_offset16,
15537                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15538                 NULL, 0, "Data Offset", HFILL }},
15539
15540         { &hf_smb_data_count32,
15541                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
15542                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15543
15544         { &hf_smb_data_disp32,
15545                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
15546                 NULL, 0, "Data Displacement", HFILL }},
15547
15548         { &hf_smb_data_offset32,
15549                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
15550                 NULL, 0, "Data Offset", HFILL }},
15551
15552         { &hf_smb_setup_count,
15553                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
15554                 NULL, 0, "Number of setup words in this buffer", HFILL }},
15555
15556         { &hf_smb_nt_trans_subcmd,
15557                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
15558                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
15559
15560         { &hf_smb_nt_ioctl_function_code,
15561                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
15562                 NULL, 0, "NT IOCTL function code", HFILL }},
15563
15564         { &hf_smb_nt_ioctl_isfsctl,
15565                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
15566                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
15567
15568         { &hf_smb_nt_ioctl_flags_root_handle,
15569                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
15570                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
15571
15572         { &hf_smb_nt_ioctl_data,
15573                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
15574                 NULL, 0, "Data for the IOCTL call", HFILL }},
15575
15576         { &hf_smb_nt_notify_action,
15577                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
15578                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
15579
15580         { &hf_smb_nt_notify_watch_tree,
15581                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
15582                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
15583
15584         { &hf_smb_nt_notify_stream_write,
15585                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
15586                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
15587
15588         { &hf_smb_nt_notify_stream_size,
15589                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
15590                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
15591
15592         { &hf_smb_nt_notify_stream_name,
15593                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
15594                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
15595
15596         { &hf_smb_nt_notify_security,
15597                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
15598                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
15599
15600         { &hf_smb_nt_notify_ea,
15601                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
15602                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
15603
15604         { &hf_smb_nt_notify_creation,
15605                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
15606                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
15607
15608         { &hf_smb_nt_notify_last_access,
15609                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
15610                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
15611
15612         { &hf_smb_nt_notify_last_write,
15613                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
15614                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
15615
15616         { &hf_smb_nt_notify_size,
15617                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
15618                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
15619
15620         { &hf_smb_nt_notify_attributes,
15621                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
15622                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
15623
15624         { &hf_smb_nt_notify_dir_name,
15625                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
15626                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
15627
15628         { &hf_smb_nt_notify_file_name,
15629                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
15630                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
15631
15632         { &hf_smb_root_dir_fid,
15633                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
15634                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
15635
15636         { &hf_smb_alloc_size64,
15637                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
15638                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15639
15640         { &hf_smb_nt_create_disposition,
15641                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
15642                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
15643
15644         { &hf_smb_sd_length,
15645                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
15646                 NULL, 0, "Total length of security descriptor", HFILL }},
15647
15648         { &hf_smb_ea_length,
15649                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
15650                 NULL, 0, "Total EA length for opened file", HFILL }},
15651
15652         { &hf_smb_file_name_len,
15653                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
15654                 NULL, 0, "Length of File Name", HFILL }},
15655
15656         { &hf_smb_nt_impersonation_level,
15657                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
15658                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
15659
15660         { &hf_smb_nt_security_flags_context_tracking,
15661                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
15662                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
15663
15664         { &hf_smb_nt_security_flags_effective_only,
15665                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
15666                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
15667
15668         { &hf_smb_nt_access_mask_generic_read,
15669                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
15670                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
15671
15672         { &hf_smb_nt_access_mask_generic_write,
15673                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
15674                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
15675
15676         { &hf_smb_nt_access_mask_generic_execute,
15677                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
15678                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
15679
15680         { &hf_smb_nt_access_mask_generic_all,
15681                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
15682                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
15683
15684         { &hf_smb_nt_access_mask_maximum_allowed,
15685                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
15686                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
15687
15688         { &hf_smb_nt_access_mask_system_security,
15689                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
15690                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
15691
15692         { &hf_smb_nt_access_mask_synchronize,
15693                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
15694                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
15695
15696         { &hf_smb_nt_access_mask_write_owner,
15697                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
15698                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
15699
15700         { &hf_smb_nt_access_mask_write_dac,
15701                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
15702                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
15703
15704         { &hf_smb_nt_access_mask_read_control,
15705                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
15706                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
15707
15708         { &hf_smb_nt_access_mask_delete,
15709                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
15710                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
15711
15712         { &hf_smb_nt_access_mask_write_attributes,
15713                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
15714                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
15715
15716         { &hf_smb_nt_access_mask_read_attributes,
15717                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
15718                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
15719
15720         { &hf_smb_nt_access_mask_delete_child,
15721                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
15722                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
15723
15724         /*
15725          * "Execute" for files, "traverse" for directories.
15726          */
15727         { &hf_smb_nt_access_mask_execute,
15728                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
15729                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
15730
15731         { &hf_smb_nt_access_mask_write_ea,
15732                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
15733                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
15734
15735         { &hf_smb_nt_access_mask_read_ea,
15736                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
15737                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
15738
15739         /*
15740          * "Append data" for files, "add subdirectory" for directories,
15741          * "create pipe instance" for named pipes.
15742          */
15743         { &hf_smb_nt_access_mask_append,
15744                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
15745                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
15746
15747         /*
15748          * "Write data" for files and pipes, "add file" for directory.
15749          */
15750         { &hf_smb_nt_access_mask_write,
15751                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
15752                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
15753
15754         /*
15755          * "Read data" for files and pipes, "list directory" for directory.
15756          */
15757         { &hf_smb_nt_access_mask_read,
15758                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
15759                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
15760
15761         { &hf_smb_nt_create_bits_oplock,
15762                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
15763                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
15764
15765         { &hf_smb_nt_create_bits_boplock,
15766                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
15767                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
15768
15769         { &hf_smb_nt_create_bits_dir,
15770                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
15771                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
15772
15773         { &hf_smb_nt_create_options_directory_file,
15774                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
15775                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
15776
15777         { &hf_smb_nt_create_options_write_through,
15778                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
15779                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
15780
15781         { &hf_smb_nt_create_options_sequential_only,
15782                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
15783                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
15784
15785         { &hf_smb_nt_create_options_sync_io_alert,
15786                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
15787                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
15788
15789         { &hf_smb_nt_create_options_sync_io_nonalert,
15790                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
15791                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
15792
15793         { &hf_smb_nt_create_options_non_directory_file,
15794                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
15795                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
15796
15797         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
15798            and "NtOpenFile()"; is that sent over the wire?  Network
15799            Monitor thinks so, but its author may just have grabbed
15800            the flag bits from a system header file. */
15801
15802         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
15803            and "NtOpenFile()"; is that sent over the wire?  NetMon
15804            thinks so, but see previous comment. */
15805
15806         { &hf_smb_nt_create_options_no_ea_knowledge,
15807                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
15808                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
15809
15810         { &hf_smb_nt_create_options_eight_dot_three_only,
15811                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
15812                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
15813
15814         { &hf_smb_nt_create_options_random_access,
15815                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
15816                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
15817
15818         { &hf_smb_nt_create_options_delete_on_close,
15819                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
15820                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
15821
15822         /* 0x00002000 is "open by FID", or something such as that (which
15823            I suspect is like "open by inumber" on UNIX), at least in
15824            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
15825            wire?  NetMon thinks so, but see previous comment. */
15826
15827         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
15828            and "NtOpenFile()"; is that sent over the wire?  NetMon
15829            thinks so, but see previous comment. */
15830
15831         { &hf_smb_nt_share_access_read,
15832                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
15833                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
15834
15835         { &hf_smb_nt_share_access_write,
15836                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
15837                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
15838
15839         { &hf_smb_nt_share_access_delete,
15840                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
15841                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
15842
15843         { &hf_smb_file_eattr_read_only,
15844                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
15845                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15846
15847         { &hf_smb_file_eattr_hidden,
15848                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
15849                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15850
15851         { &hf_smb_file_eattr_system,
15852                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
15853                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15854
15855         { &hf_smb_file_eattr_volume,
15856                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
15857                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15858
15859         { &hf_smb_file_eattr_directory,
15860                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
15861                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15862
15863         { &hf_smb_file_eattr_archive,
15864                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
15865                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15866
15867         { &hf_smb_file_eattr_device,
15868                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
15869                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15870
15871         { &hf_smb_file_eattr_normal,
15872                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
15873                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15874
15875         { &hf_smb_file_eattr_temporary,
15876                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
15877                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15878
15879         { &hf_smb_file_eattr_sparse,
15880                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
15881                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15882
15883         { &hf_smb_file_eattr_reparse,
15884                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
15885                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15886
15887         { &hf_smb_file_eattr_compressed,
15888                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
15889                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15890
15891         { &hf_smb_file_eattr_offline,
15892                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
15893                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15894
15895         { &hf_smb_file_eattr_not_content_indexed,
15896                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
15897                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15898
15899         { &hf_smb_file_eattr_encrypted,
15900                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
15901                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15902
15903         { &hf_smb_file_eattr_write_through,
15904                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
15905                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
15906
15907         { &hf_smb_file_eattr_no_buffering,
15908                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
15909                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
15910
15911         { &hf_smb_file_eattr_random_access,
15912                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
15913                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
15914
15915         { &hf_smb_file_eattr_sequential_scan,
15916                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
15917                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
15918
15919         { &hf_smb_file_eattr_delete_on_close,
15920                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
15921                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
15922
15923         { &hf_smb_file_eattr_backup_semantics,
15924                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
15925                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
15926
15927         { &hf_smb_file_eattr_posix_semantics,
15928                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
15929                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
15930
15931         { &hf_smb_sec_desc_len,
15932                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
15933                 NULL, 0, "Security Descriptor Length", HFILL }},
15934
15935         { &hf_smb_nt_qsd_owner,
15936                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
15937                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
15938
15939         { &hf_smb_nt_qsd_group,
15940                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
15941                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
15942
15943         { &hf_smb_nt_qsd_dacl,
15944                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
15945                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
15946
15947         { &hf_smb_nt_qsd_sacl,
15948                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
15949                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
15950
15951         { &hf_smb_extended_attributes,
15952                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
15953                 NULL, 0, "Extended Attributes", HFILL }},
15954
15955         { &hf_smb_oplock_level,
15956                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
15957                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
15958
15959         { &hf_smb_create_action,
15960                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
15961                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
15962
15963         { &hf_smb_ea_error_offset,
15964                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
15965                 NULL, 0, "Offset into EA list if EA error", HFILL }},
15966
15967         { &hf_smb_end_of_file,
15968                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
15969                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
15970
15971         { &hf_smb_device_type,
15972                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
15973                 VALS(device_type_vals), 0, "Type of device", HFILL }},
15974
15975         { &hf_smb_is_directory,
15976                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
15977                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
15978
15979         { &hf_smb_next_entry_offset,
15980                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
15981                 NULL, 0, "Offset to next entry", HFILL }},
15982
15983         { &hf_smb_change_time,
15984                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
15985                 NULL, 0, "Last Change Time", HFILL }},
15986
15987         { &hf_smb_setup_len,
15988                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
15989                 NULL, 0, "Length of prionter setup data", HFILL }},
15990
15991         { &hf_smb_print_mode,
15992                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
15993                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
15994
15995         { &hf_smb_print_identifier,
15996                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
15997                 NULL, 0, "Identifier string for this print job", HFILL }},
15998
15999         { &hf_smb_restart_index,
16000                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16001                 NULL, 0, "Index of entry after last returned", HFILL }},
16002
16003         { &hf_smb_print_queue_date,
16004                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16005                 NULL, 0, "Date when this entry was queued", HFILL }},
16006
16007         { &hf_smb_print_queue_dos_date,
16008                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16009                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16010
16011         { &hf_smb_print_queue_dos_time,
16012                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
16013                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
16014
16015         { &hf_smb_print_status,
16016                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
16017                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
16018
16019         { &hf_smb_print_spool_file_number,
16020                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
16021                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
16022
16023         { &hf_smb_print_spool_file_size,
16024                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
16025                 NULL, 0, "Number of bytes in spool file", HFILL }},
16026
16027         { &hf_smb_print_spool_file_name,
16028                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
16029                 NULL, 0, "Name of client that submitted this job", HFILL }},
16030
16031         { &hf_smb_start_index,
16032                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
16033                 NULL, 0, "First queue entry to return", HFILL }},
16034
16035         { &hf_smb_cancel_to,
16036                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
16037                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
16038
16039         { &hf_smb_trans2_subcmd,
16040                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16041                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16042
16043         { &hf_smb_trans_name,
16044                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
16045                 NULL, 0, "Name of transaction", HFILL }},
16046
16047         { &hf_smb_transaction_flags_dtid,
16048                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
16049                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
16050
16051         { &hf_smb_transaction_flags_owt,
16052                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
16053                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
16054
16055         { &hf_smb_search_count,
16056                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
16057                 NULL, 0, "Maximum number of search entries to return", HFILL }},
16058
16059         { &hf_smb_search_pattern,
16060                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
16061                 NULL, 0, "Search Pattern", HFILL }},
16062
16063         { &hf_smb_ff2_backup,
16064                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
16065                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
16066
16067         { &hf_smb_ff2_continue,
16068                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
16069                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
16070
16071         { &hf_smb_ff2_resume,
16072                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
16073                 TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
16074
16075         { &hf_smb_ff2_close_eos,
16076                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
16077                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
16078
16079         { &hf_smb_ff2_close,
16080                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
16081                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
16082
16083         { &hf_smb_ff2_information_level,
16084                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
16085                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
16086
16087         { &hf_smb_qpi_loi,
16088                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
16089                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
16090
16091         { &hf_smb_storage_type,
16092                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
16093                 NULL, 0, "Type of storage", HFILL }},
16094
16095         { &hf_smb_resume,
16096                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
16097                 NULL, 0, "Resume Key", HFILL }},
16098
16099         { &hf_smb_max_referral_level,
16100                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
16101                 NULL, 0, "Latest referral version number understood", HFILL }},
16102
16103         { &hf_smb_qfsi_information_level,
16104                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
16105                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
16106
16107         { &hf_smb_ea_size,
16108                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
16109                 NULL, 0, "Size of file's EA information", HFILL }},
16110
16111         { &hf_smb_list_length,
16112                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
16113                 NULL, 0, "Length of the remaining data", HFILL }},
16114
16115         { &hf_smb_number_of_links,
16116                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
16117                 NULL, 0, "Number of hard links to the file", HFILL }},
16118
16119         { &hf_smb_delete_pending,
16120                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
16121                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
16122
16123         { &hf_smb_index_number,
16124                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
16125                 NULL, 0, "File system unique identifier", HFILL }},
16126
16127         { &hf_smb_current_offset,
16128                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
16129                 NULL, 0, "Current offset in the file", HFILL }},
16130
16131         { &hf_smb_t2_alignment,
16132                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
16133                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
16134
16135         { &hf_smb_t2_stream_name_length,
16136                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
16137                 NULL, 0, "Length of stream name", HFILL }},
16138
16139         { &hf_smb_t2_stream_size,
16140                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
16141                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16142
16143         { &hf_smb_t2_stream_name,
16144                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
16145                 NULL, 0, "Name of the stream", HFILL }},
16146
16147         { &hf_smb_t2_compressed_file_size,
16148                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
16149                 NULL, 0, "Size of the compressed file", HFILL }},
16150
16151         { &hf_smb_t2_compressed_format,
16152                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
16153                 NULL, 0, "Compression algorithm used", HFILL }},
16154
16155         { &hf_smb_t2_compressed_unit_shift,
16156                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
16157                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16158
16159         { &hf_smb_t2_compressed_chunk_shift,
16160                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
16161                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16162
16163         { &hf_smb_t2_compressed_cluster_shift,
16164                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
16165                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16166
16167         { &hf_smb_dfs_path_consumed,
16168                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
16169                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
16170
16171         { &hf_smb_dfs_num_referrals,
16172                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
16173                 NULL, 0, "Number of referrals in this pdu", HFILL }},
16174
16175         { &hf_smb_get_dfs_server_hold_storage,
16176                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
16177                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
16178
16179         { &hf_smb_get_dfs_fielding,
16180                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
16181                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
16182
16183         { &hf_smb_dfs_referral_version,
16184                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
16185                 NULL, 0, "Version of referral element", HFILL }},
16186
16187         { &hf_smb_dfs_referral_size,
16188                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
16189                 NULL, 0, "Size of referral element", HFILL }},
16190
16191         { &hf_smb_dfs_referral_server_type,
16192                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
16193                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
16194
16195         { &hf_smb_dfs_referral_flags_strip,
16196                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
16197                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
16198
16199         { &hf_smb_dfs_referral_node_offset,
16200                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
16201                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
16202
16203         { &hf_smb_dfs_referral_node,
16204                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
16205                 NULL, 0, "Name of entity to visit next", HFILL }},
16206
16207         { &hf_smb_dfs_referral_proximity,
16208                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
16209                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
16210
16211         { &hf_smb_dfs_referral_ttl,
16212                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
16213                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
16214
16215         { &hf_smb_dfs_referral_path_offset,
16216                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
16217                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
16218
16219         { &hf_smb_dfs_referral_path,
16220                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
16221                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
16222
16223         { &hf_smb_dfs_referral_alt_path_offset,
16224                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
16225                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
16226
16227         { &hf_smb_dfs_referral_alt_path,
16228                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
16229                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
16230
16231         { &hf_smb_end_of_search,
16232                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
16233                 NULL, 0, "Was last entry returned?", HFILL }},
16234
16235         { &hf_smb_last_name_offset,
16236                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
16237                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
16238
16239         { &hf_smb_file_index,
16240                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
16241                 NULL, 0, "File index", HFILL }},
16242
16243         { &hf_smb_short_file_name,
16244                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
16245                 NULL, 0, "Short (8.3) File Name", HFILL }},
16246
16247         { &hf_smb_short_file_name_len,
16248                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
16249                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
16250
16251         { &hf_smb_fs_id,
16252                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
16253                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
16254
16255         { &hf_smb_sector_unit,
16256                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
16257                 NULL, 0, "Sectors per allocation unit", HFILL }},
16258
16259         { &hf_smb_fs_units,
16260                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
16261                 NULL, 0, "Total number of units on this filesystem", HFILL }},
16262
16263         { &hf_smb_fs_sector,
16264                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
16265                 NULL, 0, "Bytes per sector", HFILL }},
16266
16267         { &hf_smb_avail_units,
16268                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
16269                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
16270
16271         { &hf_smb_volume_serial_num,
16272                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
16273                 NULL, 0, "Volume serial number", HFILL }},
16274
16275         { &hf_smb_volume_label_len,
16276                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
16277                 NULL, 0, "Length of volume label", HFILL }},
16278
16279         { &hf_smb_volume_label,
16280                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
16281                 NULL, 0, "Volume label", HFILL }},
16282
16283         { &hf_smb_free_alloc_units64,
16284                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
16285                 NULL, 0, "Number of free allocation units", HFILL }},
16286
16287         { &hf_smb_soft_quota_limit,
16288                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
16289                 NULL, 0, "Soft Quota treshold", HFILL }},
16290
16291         { &hf_smb_hard_quota_limit,
16292                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
16293                 NULL, 0, "Hard Quota limit", HFILL }},
16294
16295         { &hf_smb_user_quota_used,
16296                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
16297                 NULL, 0, "How much Quota is used by this user", HFILL }},
16298
16299         { &hf_smb_max_name_len,
16300                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
16301                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
16302
16303         { &hf_smb_fs_name_len,
16304                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
16305                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
16306
16307         { &hf_smb_fs_name,
16308                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
16309                 NULL, 0, "Name of filesystem", HFILL }},
16310
16311         { &hf_smb_device_char_removable,
16312                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
16313                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
16314
16315         { &hf_smb_device_char_read_only,
16316                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
16317                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
16318
16319         { &hf_smb_device_char_floppy,
16320                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
16321                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
16322
16323         { &hf_smb_device_char_write_once,
16324                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
16325                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
16326
16327         { &hf_smb_device_char_remote,
16328                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
16329                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
16330
16331         { &hf_smb_device_char_mounted,
16332                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
16333                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
16334
16335         { &hf_smb_device_char_virtual,
16336                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
16337                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
16338
16339         { &hf_smb_fs_attr_css,
16340                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
16341                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
16342
16343         { &hf_smb_fs_attr_cpn,
16344                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
16345                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
16346
16347         { &hf_smb_fs_attr_pacls,
16348                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
16349                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
16350
16351         { &hf_smb_fs_attr_fc,
16352                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
16353                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
16354
16355         { &hf_smb_fs_attr_vq,
16356                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
16357                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
16358
16359         { &hf_smb_fs_attr_dim,
16360                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
16361                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
16362
16363         { &hf_smb_fs_attr_vic,
16364                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
16365                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
16366
16367         { &hf_smb_sec_desc_revision,
16368                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
16369                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
16370
16371         { &hf_smb_sid_revision,
16372                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
16373                 NULL, 0, "Version of SID structure", HFILL }},
16374
16375         { &hf_smb_sid_num_auth,
16376                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
16377                 NULL, 0, "Number of authorities for this SID", HFILL }},
16378
16379         { &hf_smb_acl_revision,
16380                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
16381                 NULL, 0, "Version of NT ACL structure", HFILL }},
16382
16383         { &hf_smb_acl_size,
16384                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
16385                 NULL, 0, "Size of NT ACL structure", HFILL }},
16386
16387         { &hf_smb_acl_num_aces,
16388                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
16389                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
16390
16391         { &hf_smb_user_quota_offset,
16392                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
16393                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
16394
16395         { &hf_smb_ace_type,
16396                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
16397                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
16398
16399         { &hf_smb_ace_size,
16400                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
16401                 NULL, 0, "Size of this ACE", HFILL }},
16402
16403         { &hf_smb_ace_flags_object_inherit,
16404                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
16405                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
16406
16407         { &hf_smb_ace_flags_container_inherit,
16408                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
16409                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
16410
16411         { &hf_smb_ace_flags_non_propagate_inherit,
16412                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
16413                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
16414
16415         { &hf_smb_ace_flags_inherit_only,
16416                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
16417                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
16418
16419         { &hf_smb_ace_flags_inherited_ace,
16420                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
16421                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
16422
16423         { &hf_smb_ace_flags_successful_access,
16424                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
16425                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
16426
16427         { &hf_smb_ace_flags_failed_access,
16428                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
16429                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
16430
16431         { &hf_smb_sec_desc_type_owner_defaulted,
16432                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
16433                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
16434
16435         { &hf_smb_sec_desc_type_group_defaulted,
16436                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
16437                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
16438
16439         { &hf_smb_sec_desc_type_dacl_present,
16440                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
16441                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
16442
16443         { &hf_smb_sec_desc_type_dacl_defaulted,
16444                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
16445                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
16446
16447         { &hf_smb_sec_desc_type_sacl_present,
16448                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
16449                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
16450
16451         { &hf_smb_sec_desc_type_sacl_defaulted,
16452                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
16453                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
16454
16455         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
16456                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
16457                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
16458
16459         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
16460                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
16461                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
16462
16463         { &hf_smb_sec_desc_type_dacl_auto_inherited,
16464                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
16465                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
16466
16467         { &hf_smb_sec_desc_type_sacl_auto_inherited,
16468                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
16469                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
16470
16471         { &hf_smb_sec_desc_type_dacl_protected,
16472                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
16473                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
16474
16475         { &hf_smb_sec_desc_type_sacl_protected,
16476                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
16477                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
16478
16479         { &hf_smb_sec_desc_type_self_relative,
16480                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
16481                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
16482
16483         { &hf_smb_quota_flags_deny_disk,
16484                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
16485                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
16486
16487         { &hf_smb_quota_flags_log_limit,
16488                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
16489                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
16490
16491         { &hf_smb_quota_flags_log_warning,
16492                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
16493                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
16494
16495         { &hf_smb_quota_flags_enabled,
16496                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
16497                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
16498
16499         };
16500         static gint *ett[] = {
16501                 &ett_smb,
16502                 &ett_smb_hdr,
16503                 &ett_smb_command,
16504                 &ett_smb_fileattributes,
16505                 &ett_smb_capabilities,
16506                 &ett_smb_aflags,
16507                 &ett_smb_dialect,
16508                 &ett_smb_dialects,
16509                 &ett_smb_mode,
16510                 &ett_smb_rawmode,
16511                 &ett_smb_flags,
16512                 &ett_smb_flags2,
16513                 &ett_smb_desiredaccess,
16514                 &ett_smb_search,
16515                 &ett_smb_file,
16516                 &ett_smb_openfunction,
16517                 &ett_smb_filetype,
16518                 &ett_smb_openaction,
16519                 &ett_smb_writemode,
16520                 &ett_smb_lock_type,
16521                 &ett_smb_ssetupandxaction,
16522                 &ett_smb_optionsup,
16523                 &ett_smb_time_date,
16524                 &ett_smb_move_flags,
16525                 &ett_smb_file_attributes,
16526                 &ett_smb_search_resume_key,
16527                 &ett_smb_search_dir_info,
16528                 &ett_smb_unlocks,
16529                 &ett_smb_unlock,
16530                 &ett_smb_locks,
16531                 &ett_smb_lock,
16532                 &ett_smb_open_flags,
16533                 &ett_smb_ipc_state,
16534                 &ett_smb_open_action,
16535                 &ett_smb_setup_action,
16536                 &ett_smb_connect_flags,
16537                 &ett_smb_connect_support_bits,
16538                 &ett_smb_nt_access_mask,
16539                 &ett_smb_nt_create_bits,
16540                 &ett_smb_nt_create_options,
16541                 &ett_smb_nt_share_access,
16542                 &ett_smb_nt_security_flags,
16543                 &ett_smb_nt_trans_setup,
16544                 &ett_smb_nt_trans_data,
16545                 &ett_smb_nt_trans_param,
16546                 &ett_smb_nt_notify_completion_filter,
16547                 &ett_smb_nt_ioctl_flags,
16548                 &ett_smb_security_information_mask,
16549                 &ett_smb_print_queue_entry,
16550                 &ett_smb_transaction_flags,
16551                 &ett_smb_transaction_params,
16552                 &ett_smb_find_first2_flags,
16553                 &ett_smb_transaction_data,
16554                 &ett_smb_stream_info,
16555                 &ett_smb_dfs_referrals,
16556                 &ett_smb_dfs_referral,
16557                 &ett_smb_dfs_referral_flags,
16558                 &ett_smb_get_dfs_flags,
16559                 &ett_smb_ff2_data,
16560                 &ett_smb_device_characteristics,
16561                 &ett_smb_fs_attributes,
16562                 &ett_smb_segments,
16563                 &ett_smb_sec_desc,
16564                 &ett_smb_sid,
16565                 &ett_smb_acl,
16566                 &ett_smb_ace,
16567                 &ett_smb_ace_flags,
16568                 &ett_smb_sec_desc_type,
16569                 &ett_smb_quotaflags,
16570         };
16571         module_t *smb_module;
16572
16573         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
16574             "SMB", "smb");
16575         proto_register_subtree_array(ett, array_length(ett));
16576         proto_register_field_array(proto_smb, hf, array_length(hf));
16577         register_init_routine(&smb_init_protocol);
16578         smb_module = prefs_register_protocol(proto_smb, NULL);
16579         prefs_register_bool_preference(smb_module, "trans_reassembly",
16580                 "Reassemble SMB Transaction payload",
16581                 "Whether the dissector should do reassembly the payload of SMB Transaction commands spanning multiple SMB PDUs",
16582                 &smb_trans_reassembly);
16583         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
16584                 "Reassemble DCERPC over SMB",
16585                 "Whether the dissector should do reassembly of DCERPC over SMB commands",
16586                 &smb_dcerpc_reassembly);
16587         register_init_routine(smb_trans_reassembly_init);
16588         register_init_routine(smb_dcerpc_reassembly_init);
16589 }
16590
16591 void
16592 proto_reg_handoff_smb(void)
16593 {
16594         heur_dissector_add("netbios", dissect_smb, proto_smb);
16595 }