79e914f87b8f2250809371d497c9b7b61c18dc41
[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  *
5  * $Id: packet-smb.c,v 1.122 2001/10/20 19:29:21 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
40 #endif
41
42 #include <time.h>
43 #include <string.h>
44 #include <glib.h>
45 #include <ctype.h>
46 #include "packet.h"
47 #include "conversation.h"
48 #include "smb.h"
49 #include "alignment.h"
50 #include "strutil.h"
51
52 #include "packet-smb-mailslot.h"
53 #include "packet-smb-pipe.h"
54
55 static int proto_smb = -1;
56
57 static int hf_smb_cmd = -1;
58 static int hf_smb_status = -1;
59 static int hf_smb_errcls = -1;
60 static int hf_smb_flags = -1;
61 static int hf_smb_flags2 = -1;
62 static int hf_smb_tid = -1;
63 static int hf_smb_pid = -1;
64 static int hf_smb_uid = -1;
65 static int hf_smb_mid = -1;
66
67 static gint ett_smb = -1;
68 static gint ett_smb_hdr = -1;
69 static gint ett_smb_fileattributes = -1;
70 static gint ett_smb_capabilities = -1;
71 static gint ett_smb_aflags = -1;
72 static gint ett_smb_dialects = -1;
73 static gint ett_smb_mode = -1;
74 static gint ett_smb_rawmode = -1;
75 static gint ett_smb_flags = -1;
76 static gint ett_smb_flags2 = -1;
77 static gint ett_smb_desiredaccess = -1;
78 static gint ett_smb_search = -1;
79 static gint ett_smb_file = -1;
80 static gint ett_smb_openfunction = -1;
81 static gint ett_smb_filetype = -1;
82 static gint ett_smb_openaction = -1;
83 static gint ett_smb_writemode = -1;
84 static gint ett_smb_lock_type = -1;
85 static gint ett_smb_ssetupandxaction = -1;
86 static gint ett_smb_optionsup = -1;
87
88
89 /*
90  * Struct passed to each SMB decode routine of info it may need
91  */
92
93 char *decode_smb_name(unsigned char);
94
95 int smb_packet_init_count = 200;
96
97 /*
98  * This is a hash table matching transaction requests and replies.
99  *
100  * Unfortunately, the MID is not a transaction ID in, say, the ONC RPC
101  * sense; instead, it's a "multiplex ID" used when there's more than one
102  * request *currently* in flight, to distinguish replies.
103  *
104  * This means that the MID and PID don't uniquely identify a request in
105  * a conversation.
106  *
107  * Therefore, we have to use some other value to distinguish between
108  * requests with the same MID and PID.
109  *
110  * On the first pass through the capture, when we first see a request,
111  * we hash it by conversation, MID, and PID.
112  *
113  * When we first see a reply to it, we add it to a new hash table,
114  * hashing it by conversation, MID, PID, and frame number of the reply.
115  *
116  * This works as long as
117  *
118  *      1) a client doesn't screw up and have multiple requests outstanding
119  *         with the same MID and PID
120  *
121  * and
122  *
123  *      2) we don't have, within the same frame, replies to multiple
124  *         requests with the same MID and PID.
125  *
126  * 2) should happen only if the server screws up and puts the wrong MID or
127  * PID into a reply (in which case not only can we not handle this, the
128  * client can't handle it either) or if the client has screwed up as per
129  * 1) and the server's dutifully replied to both of the requests with the
130  * same MID and PID (in which case, again, neither we nor the client can
131  * handle this).
132  *
133  * We don't have to correctly dissect screwups; we just have to keep from
134  * dumping core on them.
135  *
136  * XXX - in addition, we need to keep a hash table of replies, so that we
137  * can associate continuations with the reply to which they're a continuation.
138  */
139 struct smb_request_key {
140   guint32 conversation;
141   guint16 mid;
142   guint16 pid;
143   guint32 frame_num;
144 };
145
146 static GHashTable *smb_request_hash = NULL;
147 static GMemChunk *smb_request_keys = NULL;
148 static GMemChunk *smb_request_vals = NULL;
149
150 /*
151  * This is a hash table matching continued transation replies and their
152  * continuations.
153  *
154  * It works similarly to the request/reply hash table.
155  */
156 static GHashTable *smb_continuation_hash = NULL;
157
158 static GMemChunk *smb_continuation_vals = NULL;
159
160 /* Hash Functions */
161 static gint
162 smb_equal(gconstpointer v, gconstpointer w)
163 {
164   struct smb_request_key *v1 = (struct smb_request_key *)v;
165   struct smb_request_key *v2 = (struct smb_request_key *)w;
166
167 #if defined(DEBUG_SMB_HASH)
168   printf("Comparing %08X:%u:%u:%u\n      and %08X:%u:%u:%u\n",
169          v1 -> conversation, v1 -> mid, v1 -> pid, v1 -> frame_num,
170          v2 -> conversation, v2 -> mid, v2 -> pid, v2 -> frame_num);
171 #endif
172
173   if (v1 -> conversation == v2 -> conversation &&
174       v1 -> mid          == v2 -> mid &&
175       v1 -> pid          == v2 -> pid &&
176       v1 -> frame_num    == v2 -> frame_num) {
177
178     return 1;
179
180   }
181
182   return 0;
183 }
184
185 static guint
186 smb_hash (gconstpointer v)
187 {
188   struct smb_request_key *key = (struct smb_request_key *)v;
189   guint val;
190
191   val = (key -> conversation) + (key -> mid) + (key -> pid) +
192         (key -> frame_num);
193
194 #if defined(DEBUG_SMB_HASH)
195   printf("SMB Hash calculated as %u\n", val);
196 #endif
197
198   return val;
199
200 }
201
202 /*
203  * Free up any state information we've saved, and re-initialize the
204  * tables of state information.
205  */
206
207 /*
208  * For a hash table entry, free the address data to which the key refers
209  * and the fragment data to which the value refers.
210  * (The actual key and value structures get freed by "reassemble_init()".)
211  */
212 static gboolean
213 free_request_val_data(gpointer key, gpointer value, gpointer user_data)
214 {
215   struct smb_request_val *request_val = value;
216
217   if (request_val->last_transact_command != NULL)
218     g_free(request_val->last_transact_command);
219   if (request_val->last_param_descrip != NULL)
220     g_free(request_val->last_param_descrip);
221   if (request_val->last_data_descrip != NULL)
222     g_free(request_val->last_data_descrip);
223   if (request_val->last_aux_data_descrip != NULL)
224     g_free(request_val->last_aux_data_descrip);
225   return TRUE;
226 }
227
228 static struct smb_request_val *
229 do_transaction_hashing(conversation_t *conversation, struct smb_info si,
230                        frame_data *fd)
231 {
232   struct smb_request_key request_key, *new_request_key;
233   struct smb_request_val *request_val = NULL;
234   gpointer               new_request_key_ret, request_val_ret;
235
236   if (si.request) {
237     /*
238      * This is a request.
239      *
240      * If this is the first time the frame has been seen, check for
241      * an entry for the request in the hash table.  If it's not found,
242      * insert an entry for it.
243      *
244      * If it's the first time it's been seen, then we can't have seen
245      * the reply yet, so the reply frame number should be 0, for
246      * "unknown".
247      */
248     if (!fd->flags.visited) {
249       request_key.conversation = conversation->index;
250       request_key.mid          = si.mid;
251       request_key.pid          = si.pid;
252       request_key.frame_num    = 0;
253
254       request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
255
256       if (request_val == NULL) {
257         /*
258          * Not found.
259          */
260         new_request_key = g_mem_chunk_alloc(smb_request_keys);
261         new_request_key -> conversation = conversation->index;
262         new_request_key -> mid          = si.mid;
263         new_request_key -> pid          = si.pid;
264         new_request_key -> frame_num    = 0;
265
266         request_val = g_mem_chunk_alloc(smb_request_vals);
267         request_val -> frame = fd->num;
268         request_val -> last_transact2_command = -1;             /* unknown */
269         request_val -> last_transact_command = NULL;
270         request_val -> last_param_descrip = NULL;
271         request_val -> last_data_descrip = NULL;
272         request_val -> last_aux_data_descrip = NULL;
273
274         g_hash_table_insert(smb_request_hash, new_request_key, request_val);
275       } else {
276         /*
277          * This means that we've seen another request in this conversation
278          * with the same request and reply, and without an intervening
279          * reply to that first request, and thus won't be using this
280          * "request_val" structure for that request (as we'd use it only
281          * for the reply).
282          *
283          * Clean out the structure, and set it to refer to this frame.
284          */
285         request_val -> frame = fd->num;
286         request_val -> last_transact2_command = -1;             /* unknown */
287         if (request_val -> last_transact_command)
288           g_free(request_val -> last_transact_command);
289         request_val -> last_transact_command = NULL;
290         if (request_val -> last_param_descrip)
291           g_free(request_val -> last_param_descrip);
292         request_val -> last_param_descrip = NULL;
293         if (request_val -> last_data_descrip)
294           g_free(request_val -> last_data_descrip);
295         request_val -> last_data_descrip = NULL;
296         if (request_val -> last_aux_data_descrip)
297           g_free(request_val -> last_aux_data_descrip);
298         request_val -> last_aux_data_descrip = NULL;
299       }
300     }
301   } else {
302     /*
303      * This is a reply.
304      */
305     if (!fd->flags.visited) {
306       /*
307        * This is the first time the frame has been seen; check for
308        * an entry for a matching request, with an unknown reply frame
309        * number, in the hash table.
310        *
311        * If we find it, re-hash it with this frame's number as the
312        * reply frame number.
313        */
314       request_key.conversation = conversation->index;
315       request_key.mid          = si.mid;
316       request_key.pid          = si.pid;
317       request_key.frame_num    = 0;
318
319       /*
320        * Look it up - and, if we find it, get pointers to the key and
321        * value structures for it.
322        */
323       if (g_hash_table_lookup_extended(smb_request_hash, &request_key,
324                                        &new_request_key_ret,
325                                        &request_val_ret)) {
326         new_request_key = new_request_key_ret;
327         request_val = request_val_ret;
328
329         /*
330          * We found it.
331          * Remove the old entry.
332          */
333         g_hash_table_remove(smb_request_hash, &request_key);
334
335         /*
336          * Now update the key, and put it back into the hash table with
337          * the new key.
338          */
339         new_request_key->frame_num = fd->num;
340         g_hash_table_insert(smb_request_hash, new_request_key, request_val);
341       }
342     } else {
343       /*
344        * This is not the first time the frame has been seen; check for
345        * an entry for a matching request, with this frame's frame
346        * number as the reply frame number, in the hash table.
347        */
348       request_key.conversation = conversation->index;
349       request_key.mid          = si.mid;
350       request_key.pid          = si.pid;
351       request_key.frame_num    = fd->num;
352
353       request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
354     }
355   }
356
357   return request_val;
358 }
359
360 static struct smb_continuation_val *
361 do_continuation_hashing(conversation_t *conversation, struct smb_info si,
362                        frame_data *fd, guint16 TotalDataCount,
363                        guint16 DataCount, const char **TransactName)
364 {
365   struct smb_request_key request_key, *new_request_key;
366   struct smb_continuation_val *continuation_val, *new_continuation_val;
367   gpointer               new_request_key_ret, continuation_val_ret;
368
369   continuation_val = NULL;
370   if (si.ddisp != 0) {
371     /*
372      * This reply isn't the first in the series; there should be a
373      * reply of which it is a continuation.
374      */
375     if (!fd->flags.visited) {
376       /*
377        * This is the first time the frame has been seen; check for
378        * an entry for a matching continued message, with an unknown
379        * continuation frame number, in the hash table.
380        *
381        * If we find it, re-hash it with this frame's number as the
382        * continuation frame number.
383        */
384       request_key.conversation = conversation->index;
385       request_key.mid          = si.mid;
386       request_key.pid          = si.pid;
387       request_key.frame_num    = 0;
388
389       /*
390        * Look it up - and, if we find it, get pointers to the key and
391        * value structures for it.
392        */
393       if (g_hash_table_lookup_extended(smb_continuation_hash, &request_key,
394                                        &new_request_key_ret,
395                                        &continuation_val_ret)) {
396         new_request_key = new_request_key_ret;
397         continuation_val = continuation_val_ret;
398
399         /*
400          * We found it.
401          * Remove the old entry.
402          */
403         g_hash_table_remove(smb_continuation_hash, &request_key);
404
405         /*
406          * Now update the key, and put it back into the hash table with
407          * the new key.
408          */
409         new_request_key->frame_num = fd->num;
410         g_hash_table_insert(smb_continuation_hash, new_request_key,
411                             continuation_val);
412       }
413     } else {
414       /*
415        * This is not the first time the frame has been seen; check for
416        * an entry for a matching request, with this frame's frame
417        * number as the continuation frame number, in the hash table.
418        */
419       request_key.conversation = conversation->index;
420       request_key.mid          = si.mid;
421       request_key.pid          = si.pid;
422       request_key.frame_num    = fd->num;
423
424       continuation_val = (struct smb_continuation_val *)
425                 g_hash_table_lookup(smb_continuation_hash, &request_key);
426     }
427   }
428
429   /*
430    * If we found the entry for the message of which this is a continuation,
431    * and our caller cares, get the transaction name for that message, as
432    * it's the transaction name for this message as well.
433    */
434   if (continuation_val != NULL && TransactName != NULL)
435     *TransactName = continuation_val -> transact_name;
436
437   if (TotalDataCount > DataCount + si.ddisp) {
438     /*
439      * This reply isn't the last in the series; there should be a
440      * continuation for it later in the capture.
441      *
442      * If this is the first time the frame has been seen, check for
443      * an entry for the reply in the hash table.  If it's not found,
444      * insert an entry for it.
445      *
446      * If it's the first time it's been seen, then we can't have seen
447      * the continuation yet, so the continuation frame number should
448      * be 0, for "unknown".
449      */
450     if (!fd->flags.visited) {
451       request_key.conversation = conversation->index;
452       request_key.mid          = si.mid;
453       request_key.pid          = si.pid;
454       request_key.frame_num    = 0;
455
456       new_continuation_val = (struct smb_continuation_val *)
457                 g_hash_table_lookup(smb_continuation_hash, &request_key);
458
459       if (new_continuation_val == NULL) {
460         /*
461          * Not found.
462          */
463         new_request_key = g_mem_chunk_alloc(smb_request_keys);
464         new_request_key -> conversation = conversation->index;
465         new_request_key -> mid          = si.mid;
466         new_request_key -> pid          = si.pid;
467         new_request_key -> frame_num    = 0;
468
469         new_continuation_val = g_mem_chunk_alloc(smb_continuation_vals);
470         new_continuation_val -> frame = fd->num;
471         if (TransactName != NULL)
472           new_continuation_val -> transact_name = *TransactName;
473         else
474           new_continuation_val -> transact_name = NULL;
475
476         g_hash_table_insert(smb_continuation_hash, new_request_key,
477                             new_continuation_val);
478       } else {
479         /*
480          * This presumably means we never saw the continuation of
481          * the message we found, and this is a reply to a different
482          * request; as we never saw the continuation of that message,
483          * we won't be using this "request_val" structure for that
484          * message (as we'd use it only for the continuation).
485          *
486          * Clean out the structure, and set it to refer to this frame.
487          */
488         new_continuation_val -> frame = fd->num;
489       }
490     }
491   }
492
493   return continuation_val;
494 }
495
496 static void
497 smb_init_protocol(void)
498 {
499 #if defined(DEBUG_SMB_HASH)
500   printf("Initializing SMB hashtable area\n");
501 #endif
502
503   if (smb_request_hash) {
504     /*
505      * Remove all entries from the hash table and free all strings
506      * attached to the keys and values.  (The keys and values
507      * themselves are freed with "g_mem_chunk_destroy()" calls
508      * below.)
509      */
510     g_hash_table_foreach_remove(smb_request_hash, free_request_val_data, NULL);
511     g_hash_table_destroy(smb_request_hash);
512   }
513   if (smb_continuation_hash)
514     g_hash_table_destroy(smb_continuation_hash);
515   if (smb_request_keys)
516     g_mem_chunk_destroy(smb_request_keys);
517   if (smb_request_vals)
518     g_mem_chunk_destroy(smb_request_vals);
519   if (smb_continuation_vals)
520     g_mem_chunk_destroy(smb_continuation_vals);
521
522   smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
523   smb_continuation_hash = g_hash_table_new(smb_hash, smb_equal);
524   smb_request_keys = g_mem_chunk_new("smb_request_keys",
525                                      sizeof(struct smb_request_key),
526                                      smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
527   smb_request_vals = g_mem_chunk_new("smb_request_vals",
528                                      sizeof(struct smb_request_val),
529                                      smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
530   smb_continuation_vals = g_mem_chunk_new("smb_continuation_vals",
531                                      sizeof(struct smb_continuation_val),
532                                      smb_packet_init_count * sizeof(struct smb_continuation_val), G_ALLOC_AND_FREE);
533 }
534
535 static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int);
536
537 static const value_string smb_cmd_vals[] = {
538   { 0x00, "SMBcreatedirectory" },
539   { 0x01, "SMBdeletedirectory" },
540   { 0x02, "SMBopen" },
541   { 0x03, "SMBcreate" },
542   { 0x04, "SMBclose" },
543   { 0x05, "SMBflush" },
544   { 0x06, "SMBunlink" },
545   { 0x07, "SMBmv" },
546   { 0x08, "SMBgetatr" },
547   { 0x09, "SMBsetatr" },
548   { 0x0A, "SMBread" },
549   { 0x0B, "SMBwrite" },
550   { 0x0C, "SMBlock" },
551   { 0x0D, "SMBunlock" },
552   { 0x0E, "SMBctemp" },
553   { 0x0F, "SMBmknew" },
554   { 0x10, "SMBchkpth" },
555   { 0x11, "SMBexit" },
556   { 0x12, "SMBlseek" },
557   { 0x13, "SMBlockread" },
558   { 0x14, "SMBwriteunlock" },
559   { 0x1A, "SMBreadBraw" },
560   { 0x1B, "SMBreadBmpx" },
561   { 0x1C, "SMBreadBs" },
562   { 0x1D, "SMBwriteBraw" },
563   { 0x1E, "SMBwriteBmpx" },
564   { 0x1F, "SMBwriteBs" },
565   { 0x20, "SMBwriteC" },
566   { 0x22, "SMBsetattrE" },
567   { 0x23, "SMBgetattrE" },
568   { 0x24, "SMBlockingX" },
569   { 0x25, "SMBtrans" },
570   { 0x26, "SMBtranss" },
571   { 0x27, "SMBioctl" },
572   { 0x28, "SMBioctls" },
573   { 0x29, "SMBcopy" },
574   { 0x2A, "SMBmove" },
575   { 0x2B, "SMBecho" },
576   { 0x2C, "SMBwriteclose" },
577   { 0x2D, "SMBopenX" },
578   { 0x2E, "SMBreadX" },
579   { 0x2F, "SMBwriteX" },
580   { 0x31, "SMBcloseandtreedisc" },
581   { 0x32, "SMBtrans2" },
582   { 0x33, "SMBtrans2secondary" },
583   { 0x34, "SMBfindclose2" },
584   { 0x35, "SMBfindnotifyclose" },
585   { 0x70, "SMBtcon" },
586   { 0x71, "SMBtdis" },
587   { 0x72, "SMBnegprot" },
588   { 0x73, "SMBsesssetupX" },
589   { 0x74, "SMBlogoffX" },
590   { 0x75, "SMBtconX" },
591   { 0x80, "SMBdskattr" },
592   { 0x81, "SMBsearch" },
593   { 0x82, "SMBffirst" },
594   { 0x83, "SMBfunique" },
595   { 0x84, "SMBfclose" },
596   { 0xA0, "SMBnttransact" },
597   { 0xA1, "SMBnttransactsecondary" },
598   { 0xA2, "SMBntcreateX" },
599   { 0xA4, "SMBntcancel" },
600   { 0xC0, "SMBsplopen" },
601   { 0xC1, "SMBsplwr" },
602   { 0xC2, "SMBsplclose" },
603   { 0xC3, "SMBsplretq" },
604   { 0xD0, "SMBsends" },
605   { 0xD1, "SMBsendb" },
606   { 0xD2, "SMBfwdname" },
607   { 0xD3, "SMBcancelf" },
608   { 0xD4, "SMBgetmac" },
609   { 0xD5, "SMBsendstrt" },
610   { 0xD6, "SMBsendend" },
611   { 0xD7, "SMBsendtxt" },
612   { 0xD8, "SMBreadbulk" },
613   { 0xD9, "SMBwritebulk" },
614   { 0xDA, "SMBwritebulkdata" },
615   { 0xFE, "SMBinvalid" },
616   { 0x00, NULL },
617 };
618
619 char *SMB_names[256] = {
620   "SMBcreatedirectory",
621   "SMBdeletedirectory",
622   "SMBopen",
623   "SMBcreate",
624   "SMBclose",
625   "SMBflush",
626   "SMBunlink",
627   "SMBmv",
628   "SMBgetatr",
629   "SMBsetatr",
630   "SMBread",
631   "SMBwrite",
632   "SMBlock",
633   "SMBunlock",
634   "SMBctemp",
635   "SMBmknew",
636   "SMBchkpth",
637   "SMBexit",
638   "SMBlseek",
639   "SMBlockread",
640   "SMBwriteunlock",
641   "unknown-0x15",
642   "unknown-0x16",
643   "unknown-0x17",
644   "unknown-0x18",
645   "unknown-0x19",
646   "SMBreadBraw",
647   "SMBreadBmpx",
648   "SMBreadBs",
649   "SMBwriteBraw",
650   "SMBwriteBmpx",
651   "SMBwriteBs",
652   "SMBwriteC",
653   "unknown-0x21",
654   "SMBsetattrE",
655   "SMBgetattrE",
656   "SMBlockingX",
657   "SMBtrans",
658   "SMBtranss",
659   "SMBioctl",
660   "SMBioctls",
661   "SMBcopy",
662   "SMBmove",
663   "SMBecho",
664   "SMBwriteclose",
665   "SMBopenX",
666   "SMBreadX",
667   "SMBwriteX",
668   "unknown-0x30",
669   "SMBcloseandtreedisc",
670   "SMBtrans2",
671   "SMBtrans2secondary",
672   "SMBfindclose2",
673   "SMBfindnotifyclose",
674   "unknown-0x36",
675   "unknown-0x37",
676   "unknown-0x38",
677   "unknown-0x39",
678   "unknown-0x3A",
679   "unknown-0x3B",
680   "unknown-0x3C",
681   "unknown-0x3D",
682   "unknown-0x3E",
683   "unknown-0x3F",
684   "unknown-0x40",
685   "unknown-0x41",
686   "unknown-0x42",
687   "unknown-0x43",
688   "unknown-0x44",
689   "unknown-0x45",
690   "unknown-0x46",
691   "unknown-0x47",
692   "unknown-0x48",
693   "unknown-0x49",
694   "unknown-0x4A",
695   "unknown-0x4B",
696   "unknown-0x4C",
697   "unknown-0x4D",
698   "unknown-0x4E",
699   "unknown-0x4F",
700   "unknown-0x50",
701   "unknown-0x51",
702   "unknown-0x52",
703   "unknown-0x53",
704   "unknown-0x54",
705   "unknown-0x55",
706   "unknown-0x56",
707   "unknown-0x57",
708   "unknown-0x58",
709   "unknown-0x59",
710   "unknown-0x5A",
711   "unknown-0x5B",
712   "unknown-0x5C",
713   "unknown-0x5D",
714   "unknown-0x5E",
715   "unknown-0x5F",
716   "unknown-0x60",
717   "unknown-0x61",
718   "unknown-0x62",
719   "unknown-0x63",
720   "unknown-0x64",
721   "unknown-0x65",
722   "unknown-0x66",
723   "unknown-0x67",
724   "unknown-0x68",
725   "unknown-0x69",
726   "unknown-0x6A",
727   "unknown-0x6B",
728   "unknown-0x6C",
729   "unknown-0x6D",
730   "unknown-0x6E",
731   "unknown-0x6F",
732   "SMBtcon",
733   "SMBtdis",
734   "SMBnegprot",
735   "SMBsesssetupX",
736   "SMBlogoffX",
737   "SMBtconX",
738   "unknown-0x76",
739   "unknown-0x77",
740   "unknown-0x78",
741   "unknown-0x79",
742   "unknown-0x7A",
743   "unknown-0x7B",
744   "unknown-0x7C",
745   "unknown-0x7D",
746   "unknown-0x7E",
747   "unknown-0x7F",
748   "SMBdskattr",
749   "SMBsearch",
750   "SMBffirst",
751   "SMBfunique",
752   "SMBfclose",
753   "unknown-0x85",
754   "unknown-0x86",
755   "unknown-0x87",
756   "unknown-0x88",
757   "unknown-0x89",
758   "unknown-0x8A",
759   "unknown-0x8B",
760   "unknown-0x8C",
761   "unknown-0x8D",
762   "unknown-0x8E",
763   "unknown-0x8F",
764   "unknown-0x90",
765   "unknown-0x91",
766   "unknown-0x92",
767   "unknown-0x93",
768   "unknown-0x94",
769   "unknown-0x95",
770   "unknown-0x96",
771   "unknown-0x97",
772   "unknown-0x98",
773   "unknown-0x99",
774   "unknown-0x9A",
775   "unknown-0x9B",
776   "unknown-0x9C",
777   "unknown-0x9D",
778   "unknown-0x9E",
779   "unknown-0x9F",
780   "SMBnttransact",
781   "SMBnttransactsecondary",
782   "SMBntcreateX",
783   "unknown-0xA3",
784   "SMBntcancel",
785   "unknown-0xA5",
786   "unknown-0xA6",
787   "unknown-0xA7",
788   "unknown-0xA8",
789   "unknown-0xA9",
790   "unknown-0xAA",
791   "unknown-0xAB",
792   "unknown-0xAC",
793   "unknown-0xAD",
794   "unknown-0xAE",
795   "unknown-0xAF",
796   "unknown-0xB0",
797   "unknown-0xB1",
798   "unknown-0xB2",
799   "unknown-0xB3",
800   "unknown-0xB4",
801   "unknown-0xB5",
802   "unknown-0xB6",
803   "unknown-0xB7",
804   "unknown-0xB8",
805   "unknown-0xB9",
806   "unknown-0xBA",
807   "unknown-0xBB",
808   "unknown-0xBC",
809   "unknown-0xBD",
810   "unknown-0xBE",
811   "unknown-0xBF",
812   "SMBsplopen",
813   "SMBsplwr",
814   "SMBsplclose",
815   "SMBsplretq",
816   "unknown-0xC4",
817   "unknown-0xC5",
818   "unknown-0xC6",
819   "unknown-0xC7",
820   "unknown-0xC8",
821   "unknown-0xC9",
822   "unknown-0xCA",
823   "unknown-0xCB",
824   "unknown-0xCC",
825   "unknown-0xCD",
826   "unknown-0xCE",
827   "unknown-0xCF",
828   "SMBsends",
829   "SMBsendb",
830   "SMBfwdname",
831   "SMBcancelf",
832   "SMBgetmac",
833   "SMBsendstrt",
834   "SMBsendend",
835   "SMBsendtxt",
836   "SMBreadbulk",
837   "SMBwritebulk",
838   "SMBwritebulkdata",
839   "unknown-0xDB",
840   "unknown-0xDC",
841   "unknown-0xDD",
842   "unknown-0xDE",
843   "unknown-0xDF",
844   "unknown-0xE0",
845   "unknown-0xE1",
846   "unknown-0xE2",
847   "unknown-0xE3",
848   "unknown-0xE4",
849   "unknown-0xE5",
850   "unknown-0xE6",
851   "unknown-0xE7",
852   "unknown-0xE8",
853   "unknown-0xE9",
854   "unknown-0xEA",
855   "unknown-0xEB",
856   "unknown-0xEC",
857   "unknown-0xED",
858   "unknown-0xEE",
859   "unknown-0xEF",
860   "unknown-0xF0",
861   "unknown-0xF1",
862   "unknown-0xF2",
863   "unknown-0xF3",
864   "unknown-0xF4",
865   "unknown-0xF5",
866   "unknown-0xF6",
867   "unknown-0xF7",
868   "unknown-0xF8",
869   "unknown-0xF9",
870   "unknown-0xFA",
871   "unknown-0xFB",
872   "unknown-0xFC",
873   "unknown-0xFD",
874   "SMBinvalid",
875   "unknown-0xFF"
876 };
877
878 void 
879 dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
880 {
881
882   if (tree) {
883
884     proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)", 
885                         END_OF_FRAME); 
886
887   }
888
889 }
890
891 /* 
892  * Dissect a UNIX like date ...
893  */
894
895 struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
896                       conflict with /usr/include/time.h on some NetBSD
897                       systems */
898
899 static char *
900 dissect_smbu_date(guint16 date, guint16 time)
901
902 {
903   static char         datebuf[4+2+2+2+1+10];
904   time_t              ltime = (date << 16) + time;
905
906   _gtime = gmtime(&ltime);
907
908   if (_gtime)
909     sprintf(datebuf, "%04d-%02d-%02d",
910             1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
911   else 
912     sprintf(datebuf, "Bad date format");
913
914   return datebuf;
915
916 }
917
918 /*
919  * Relies on time
920  */
921 static char *
922 dissect_smbu_time(guint16 date, guint16 time)
923
924 {
925   static char timebuf[2+2+2+2+1+10];
926
927   if (_gtime)
928     sprintf(timebuf, "%02d:%02d:%02d",
929             _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
930   else
931     sprintf(timebuf, "Bad time format");
932
933   return timebuf;
934
935 }
936
937 /*
938  * Dissect a DOS-format date.
939  */
940 static char *
941 dissect_dos_date(guint16 date)
942 {
943         static char datebuf[4+2+2+1];
944
945         sprintf(datebuf, "%04d-%02d-%02d",
946             ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
947         return datebuf;
948 }
949
950 /*
951  * Dissect a DOS-format time.
952  */
953 static char *
954 dissect_dos_time(guint16 time)
955 {
956         static char timebuf[2+2+2+1];
957
958         sprintf(timebuf, "%02d:%02d:%02d",
959             (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
960         return timebuf;
961 }
962
963 /* Max string length for displaying Unicode strings.  */
964 #define MAX_UNICODE_STR_LEN     256
965
966 /* Turn a little-endian Unicode '\0'-terminated string into a string we
967    can display.
968    XXX - for now, we just handle the ISO 8859-1 characters. */
969 static gchar *
970 unicode_to_str(const guint8 *us, int *us_lenp) {
971   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
972   static gchar *cur;
973   gchar        *p;
974   int           len;
975   int           us_len;
976   int           overflow = 0;
977
978   if (cur == &str[0][0]) {
979     cur = &str[1][0];
980   } else if (cur == &str[1][0]) {  
981     cur = &str[2][0];
982   } else {  
983     cur = &str[0][0];
984   }
985   p = cur;
986   len = MAX_UNICODE_STR_LEN;
987   us_len = 0;
988   while (*us != 0 || *(us + 1) != 0) {
989     if (len > 0) {
990       *p++ = *us;
991       len--;
992     } else
993       overflow = 1;
994     us += 2;
995     us_len += 2;
996   }
997   if (overflow) {
998     /* Note that we're not showing the full string.  */
999     *p++ = '.';
1000     *p++ = '.';
1001     *p++ = '.';
1002   }
1003   *p = '\0';
1004   *us_lenp = us_len;
1005   return cur;
1006 }
1007
1008 /* Get a null terminated string, which is Unicode if "is_unicode" is true
1009    and ASCII (OEM character set) otherwise.
1010    XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
1011 static const gchar *
1012 get_unicode_or_ascii_string(const u_char *pd, int *offsetp, int SMB_offset,
1013     gboolean is_unicode, int *len)
1014 {
1015   int offset = *offsetp;
1016   const gchar *string;
1017   int string_len;
1018
1019   if (is_unicode) {
1020     if ((offset - SMB_offset) % 2) {
1021       /*
1022        * XXX - this should be an offset relative to the beginning of the SMB,
1023        * not an offset relative to the beginning of the frame; if the stuff
1024        * before the SMB has an odd number of bytes, an offset relative to
1025        * the beginning of the frame will give the wrong answer.
1026        */
1027       offset++;   /* Looks like a pad byte there sometimes */
1028       *offsetp = offset;
1029     }
1030     string = unicode_to_str(pd + offset, &string_len);
1031     string_len += 2;
1032   } else {
1033     string = pd + offset;
1034     string_len = strlen(string) + 1;
1035   }
1036   *len = string_len;
1037   return string;
1038 }
1039
1040 static const value_string buffer_format_vals[] = {
1041         { 1, "Data block" },
1042         { 2, "Dialect" },
1043         { 3, "Pathname" },
1044         { 4, "ASCII" },
1045         { 5, "Variable block" },
1046         { 0, NULL }
1047 };
1048
1049 /*
1050  * Each dissect routine is passed an offset to wct and works from there 
1051  */
1052
1053 void
1054 dissect_flush_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1055
1056 {
1057   guint8        WordCount;
1058   guint16       FID;
1059   guint16       ByteCount;
1060
1061   if (si.request) {
1062     /* Request(s) dissect code */
1063
1064     /* Build display for: Word Count (WCT) */
1065
1066     WordCount = GBYTE(pd, offset);
1067
1068     if (tree) {
1069
1070       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1071
1072     }
1073
1074     offset += 1; /* Skip Word Count (WCT) */
1075
1076     /* Build display for: FID */
1077
1078     FID = GSHORT(pd, offset);
1079
1080     if (tree) {
1081
1082       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1083
1084     }
1085
1086     offset += 2; /* Skip FID */
1087
1088     /* Build display for: Byte Count */
1089
1090     ByteCount = GSHORT(pd, offset);
1091
1092     if (tree) {
1093
1094       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
1095
1096     }
1097
1098     offset += 2; /* Skip Byte Count */
1099
1100   } else {
1101     /* Response(s) dissect code */
1102
1103     /* Build display for: Word Count (WCT) */
1104
1105     WordCount = GBYTE(pd, offset);
1106
1107     if (tree) {
1108
1109       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1110
1111     }
1112
1113     offset += 1; /* Skip Word Count (WCT) */
1114
1115     /* Build display for: Byte Count (BCC) */
1116
1117     ByteCount = GSHORT(pd, offset);
1118
1119     if (tree) {
1120
1121       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1122
1123     }
1124
1125     offset += 2; /* Skip Byte Count (BCC) */
1126
1127   }
1128
1129 }
1130
1131 void
1132 dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1133
1134 {
1135   guint8        WordCount;
1136   guint16       TotalUnits;
1137   guint16       Reserved;
1138   guint16       FreeUnits;
1139   guint16       ByteCount;
1140   guint16       BlocksPerUnit;
1141   guint16       BlockSize;
1142
1143   if (si.request) {
1144     /* Request(s) dissect code */
1145
1146     /* Build display for: Word Count (WCT) */
1147
1148     WordCount = GBYTE(pd, offset);
1149
1150     if (tree) {
1151
1152       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1153
1154     }
1155
1156     offset += 1; /* Skip Word Count (WCT) */
1157
1158     /* Build display for: Byte Count (BCC) */
1159
1160     ByteCount = GSHORT(pd, offset);
1161
1162     if (tree) {
1163
1164       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1165
1166     }
1167
1168     offset += 2; /* Skip Byte Count (BCC) */
1169
1170   } else {
1171     /* Response(s) dissect code */
1172
1173     /* Build display for: Word Count (WCT) */
1174
1175     WordCount = GBYTE(pd, offset);
1176
1177     if (tree) {
1178
1179       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1180
1181     }
1182
1183     offset += 1; /* Skip Word Count (WCT) */
1184
1185     if (WordCount != 0) {
1186
1187       /* Build display for: Total Units */
1188
1189       TotalUnits = GSHORT(pd, offset);
1190
1191       if (tree) {
1192
1193         proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
1194
1195       }
1196
1197       offset += 2; /* Skip Total Units */
1198
1199       /* Build display for: Blocks Per Unit */
1200
1201       BlocksPerUnit = GSHORT(pd, offset);
1202
1203       if (tree) {
1204
1205         proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
1206
1207       }
1208
1209       offset += 2; /* Skip Blocks Per Unit */
1210
1211       /* Build display for: Block Size */
1212
1213       BlockSize = GSHORT(pd, offset);
1214
1215       if (tree) {
1216
1217         proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
1218
1219       }
1220
1221       offset += 2; /* Skip Block Size */
1222
1223       /* Build display for: Free Units */
1224
1225       FreeUnits = GSHORT(pd, offset);
1226
1227       if (tree) {
1228
1229         proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
1230
1231       }
1232
1233       offset += 2; /* Skip Free Units */
1234
1235       /* Build display for: Reserved */
1236
1237       Reserved = GSHORT(pd, offset);
1238
1239       if (tree) {
1240
1241         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1242
1243       }
1244
1245       offset += 2; /* Skip Reserved */
1246
1247     }
1248
1249     /* Build display for: Byte Count (BCC) */
1250
1251     ByteCount = GSHORT(pd, offset);
1252
1253     if (tree) {
1254
1255       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1256
1257     }
1258
1259     offset += 2; /* Skip Byte Count (BCC) */
1260
1261   }
1262
1263 }
1264
1265 void
1266 dissect_set_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1267
1268 {
1269   proto_tree    *Attributes_tree;
1270   proto_item    *ti;
1271   guint8        WordCount;
1272   guint8        ByteCount;
1273   guint8        BufferFormat;
1274   guint16       Reserved5;
1275   guint16       Reserved4;
1276   guint16       Reserved3;
1277   guint16       Reserved2;
1278   guint16       Reserved1;
1279   guint16       LastWriteTime;
1280   guint16       LastWriteDate;
1281   guint16       Attributes;
1282   const char    *FileName;
1283   int           string_len;
1284
1285   if (si.request) {
1286     /* Request(s) dissect code */
1287
1288     /* Build display for: Word Count (WCT) */
1289
1290     WordCount = GBYTE(pd, offset);
1291
1292     if (tree) {
1293
1294       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1295
1296     }
1297
1298     offset += 1; /* Skip Word Count (WCT) */
1299
1300     if (WordCount != 0) {
1301
1302       /* Build display for: Attributes */
1303
1304       Attributes = GSHORT(pd, offset);
1305
1306       if (tree) {
1307
1308         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
1309         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
1310         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1311                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
1312         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1313                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
1314         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1315                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
1316         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1317                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
1318         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1319                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
1320         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1321                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
1322         
1323       }
1324
1325       offset += 2; /* Skip Attributes */
1326
1327       /* Build display for: Last Write Time */
1328
1329       LastWriteTime = GSHORT(pd, offset);
1330
1331       if (tree) {
1332
1333         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
1334
1335       }
1336
1337       offset += 2; /* Skip Last Write Time */
1338
1339       /* Build display for: Last Write Date */
1340
1341       LastWriteDate = GSHORT(pd, offset);
1342
1343       if (tree) {
1344
1345         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
1346
1347       }
1348
1349       offset += 2; /* Skip Last Write Date */
1350
1351       /* Build display for: Reserved 1 */
1352
1353       Reserved1 = GSHORT(pd, offset);
1354
1355       if (tree) {
1356
1357         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
1358
1359       }
1360
1361       offset += 2; /* Skip Reserved 1 */
1362
1363       /* Build display for: Reserved 2 */
1364
1365       Reserved2 = GSHORT(pd, offset);
1366
1367       if (tree) {
1368
1369         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
1370
1371       }
1372
1373       offset += 2; /* Skip Reserved 2 */
1374
1375       /* Build display for: Reserved 3 */
1376
1377       Reserved3 = GSHORT(pd, offset);
1378
1379       if (tree) {
1380
1381         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
1382
1383       }
1384
1385       offset += 2; /* Skip Reserved 3 */
1386
1387       /* Build display for: Reserved 4 */
1388
1389       Reserved4 = GSHORT(pd, offset);
1390
1391       if (tree) {
1392
1393         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
1394
1395       }
1396
1397       offset += 2; /* Skip Reserved 4 */
1398
1399       /* Build display for: Reserved 5 */
1400
1401       Reserved5 = GSHORT(pd, offset);
1402
1403       if (tree) {
1404
1405         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
1406
1407       }
1408
1409       offset += 2; /* Skip Reserved 5 */
1410
1411     }
1412
1413     /* Build display for: Byte Count (BCC) */
1414
1415     ByteCount = GSHORT(pd, offset);
1416
1417     if (tree) {
1418
1419       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1420
1421     }
1422
1423     offset += 2; /* Skip Byte Count (BCC) */
1424
1425     /* Build display for: Buffer Format */
1426
1427     BufferFormat = GBYTE(pd, offset);
1428
1429     if (tree) {
1430
1431       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
1432                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
1433                           BufferFormat);
1434
1435     }
1436
1437     offset += 1; /* Skip Buffer Format */
1438
1439     /* Build display for: File Name */
1440
1441     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
1442
1443     if (tree) {
1444
1445       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
1446
1447     }
1448
1449     offset += string_len; /* Skip File Name */
1450
1451   } else {
1452     /* Response(s) dissect code */
1453
1454     /* Build display for: Word Count (WCT) */
1455
1456     WordCount = GBYTE(pd, offset);
1457
1458     if (tree) {
1459
1460       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1461
1462     }
1463
1464     offset += 1; /* Skip Word Count (WCT) */
1465
1466     /* Build display for: Byte Count (BCC) */
1467
1468     ByteCount = GBYTE(pd, offset);
1469
1470     if (tree) {
1471
1472       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
1473
1474     }
1475
1476     offset += 1; /* Skip Byte Count (BCC) */
1477
1478   }
1479
1480 }
1481
1482 void
1483 dissect_write_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1484
1485 {
1486   guint8        WordCount;
1487   guint8        BufferFormat;
1488   guint32       Offset;
1489   guint16       Remaining;
1490   guint16       FID;
1491   guint16       DataLength;
1492   guint16       Count;
1493   guint16       ByteCount;
1494
1495   if (si.request) {
1496     /* Request(s) dissect code */
1497
1498     /* Build display for: Word Count (WCT) */
1499
1500     WordCount = GBYTE(pd, offset);
1501
1502     if (tree) {
1503
1504       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1505
1506     }
1507
1508     offset += 1; /* Skip Word Count (WCT) */
1509
1510     /* Build display for: FID */
1511
1512     FID = GSHORT(pd, offset);
1513
1514     if (tree) {
1515
1516       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1517
1518     }
1519
1520     offset += 2; /* Skip FID */
1521
1522     /* Build display for: Count */
1523
1524     Count = GSHORT(pd, offset);
1525
1526     if (tree) {
1527
1528       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1529
1530     }
1531
1532     offset += 2; /* Skip Count */
1533
1534     /* Build display for: Offset */
1535
1536     Offset = GWORD(pd, offset);
1537
1538     if (tree) {
1539
1540       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1541
1542     }
1543
1544     offset += 4; /* Skip Offset */
1545
1546     /* Build display for: Remaining */
1547
1548     Remaining = GSHORT(pd, offset);
1549
1550     if (tree) {
1551
1552       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
1553
1554     }
1555
1556     offset += 2; /* Skip Remaining */
1557
1558     /* Build display for: Byte Count (BCC) */
1559
1560     ByteCount = GSHORT(pd, offset);
1561
1562     if (tree) {
1563
1564       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1565
1566     }
1567
1568     offset += 2; /* Skip Byte Count (BCC) */
1569
1570     /* Build display for: Buffer Format */
1571
1572     BufferFormat = GBYTE(pd, offset);
1573
1574     if (tree) {
1575
1576       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
1577                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
1578                           BufferFormat);
1579
1580     }
1581
1582     offset += 1; /* Skip Buffer Format */
1583
1584     /* Build display for: Data Length */
1585
1586     DataLength = GSHORT(pd, offset);
1587
1588     if (tree) {
1589
1590       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1591
1592     }
1593
1594     offset += 2; /* Skip Data Length */
1595
1596     if (DataLength > 0 && tree) {
1597
1598         if(END_OF_FRAME >= DataLength)
1599             proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
1600         else
1601             proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
1602
1603     }
1604
1605   } else {
1606     /* Response(s) dissect code */
1607
1608     /* Build display for: Word Count (WCT) */
1609
1610     WordCount = GBYTE(pd, offset);
1611
1612     if (tree) {
1613
1614       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1615
1616     }
1617
1618     offset += 1; /* Skip Word Count (WCT) */
1619
1620     /* Build display for: Count */
1621
1622     Count = GSHORT(pd, offset);
1623
1624     if (tree) {
1625
1626       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1627
1628     }
1629
1630     offset += 2; /* Skip Count */
1631
1632     /* Build display for: Byte Count (BCC) */
1633
1634     ByteCount = GSHORT(pd, offset);
1635
1636     if (tree) {
1637
1638       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1639
1640     }
1641
1642     offset += 2; /* Skip Byte Count (BCC) */
1643
1644   }
1645
1646 }
1647
1648 void
1649 dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1650
1651 {
1652   guint8        WordCount;
1653   guint8        Pad;
1654   guint32       Reserved1;
1655   guint32       Offset;
1656   guint16       Reserved2;
1657   guint16       Reserved;
1658   guint16       MinCount;
1659   guint16       MaxCount;
1660   guint16       FID;
1661   guint16       DataOffset;
1662   guint16       DataLength;
1663   guint16       DataCompactionMode;
1664   guint16       Count;
1665   guint16       ByteCount;
1666
1667   if (si.request) {
1668     /* Request(s) dissect code */
1669
1670     /* Build display for: Word Count (WCT) */
1671
1672     WordCount = GBYTE(pd, offset);
1673
1674     if (tree) {
1675
1676       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1677
1678     }
1679
1680     offset += 1; /* Skip Word Count (WCT) */
1681
1682     /* Build display for: FID */
1683
1684     FID = GSHORT(pd, offset);
1685
1686     if (tree) {
1687
1688       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1689
1690     }
1691
1692     offset += 2; /* Skip FID */
1693
1694     /* Build display for: Offset */
1695
1696     Offset = GWORD(pd, offset);
1697
1698     if (tree) {
1699
1700       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1701
1702     }
1703
1704     offset += 4; /* Skip Offset */
1705
1706     /* Build display for: Max Count */
1707
1708     MaxCount = GSHORT(pd, offset);
1709
1710     if (tree) {
1711
1712       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
1713
1714     }
1715
1716     offset += 2; /* Skip Max Count */
1717
1718     /* Build display for: Min Count */
1719
1720     MinCount = GSHORT(pd, offset);
1721
1722     if (tree) {
1723
1724       proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
1725
1726     }
1727
1728     offset += 2; /* Skip Min Count */
1729
1730     /* Build display for: Reserved 1 */
1731
1732     Reserved1 = GWORD(pd, offset);
1733
1734     if (tree) {
1735
1736       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 1: %u", Reserved1);
1737
1738     }
1739
1740     offset += 4; /* Skip Reserved 1 */
1741
1742     /* Build display for: Reserved 2 */
1743
1744     Reserved2 = GSHORT(pd, offset);
1745
1746     if (tree) {
1747
1748       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
1749
1750     }
1751
1752     offset += 2; /* Skip Reserved 2 */
1753
1754     /* Build display for: Byte Count (BCC) */
1755
1756     ByteCount = GSHORT(pd, offset);
1757
1758     if (tree) {
1759
1760       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1761
1762     }
1763
1764     offset += 2; /* Skip Byte Count (BCC) */
1765
1766   } else {
1767     /* Response(s) dissect code */
1768
1769     /* Build display for: Word Count */
1770
1771     WordCount = GBYTE(pd, offset);
1772
1773     if (tree) {
1774
1775       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
1776
1777     }
1778
1779     offset += 1; /* Skip Word Count */
1780
1781     if (WordCount != 0) {
1782
1783       /* Build display for: Offset */
1784
1785       Offset = GWORD(pd, offset);
1786
1787       if (tree) {
1788
1789         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1790
1791       }
1792
1793       offset += 4; /* Skip Offset */
1794
1795       /* Build display for: Count */
1796
1797       Count = GSHORT(pd, offset);
1798
1799       if (tree) {
1800
1801         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1802
1803       }
1804
1805       offset += 2; /* Skip Count */
1806
1807       /* Build display for: Reserved */
1808
1809       Reserved = GSHORT(pd, offset);
1810
1811       if (tree) {
1812
1813         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1814
1815       }
1816
1817       offset += 2; /* Skip Reserved */
1818
1819       /* Build display for: Data Compaction Mode */
1820
1821       DataCompactionMode = GSHORT(pd, offset);
1822
1823       if (tree) {
1824
1825         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
1826
1827       }
1828
1829       offset += 2; /* Skip Data Compaction Mode */
1830
1831       /* Build display for: Reserved */
1832
1833       Reserved = GSHORT(pd, offset);
1834
1835       if (tree) {
1836
1837         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1838
1839       }
1840
1841       offset += 2; /* Skip Reserved */
1842
1843       /* Build display for: Data Length */
1844
1845       DataLength = GSHORT(pd, offset);
1846
1847       if (tree) {
1848
1849         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1850
1851       }
1852
1853       offset += 2; /* Skip Data Length */
1854
1855       /* Build display for: Data Offset */
1856
1857       DataOffset = GSHORT(pd, offset);
1858
1859       if (tree) {
1860
1861         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
1862
1863       }
1864
1865       offset += 2; /* Skip Data Offset */
1866
1867     }
1868
1869     /* Build display for: Byte Count (BCC) */
1870
1871     ByteCount = GSHORT(pd, offset);
1872
1873     if (tree) {
1874
1875       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1876
1877     }
1878
1879     offset += 2; /* Skip Byte Count (BCC) */
1880
1881     /* Build display for: Pad */
1882
1883     Pad = GBYTE(pd, offset);
1884
1885     if (tree) {
1886
1887       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
1888
1889     }
1890
1891     offset += 1; /* Skip Pad */
1892
1893   }
1894
1895 }
1896
1897 void
1898 dissect_delete_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *paernt, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
1899
1900 {
1901   guint8        WordCount;
1902   guint8        BufferFormat;
1903   guint16       SearchAttributes;
1904   guint16       ByteCount;
1905   const char    *FileName;
1906   int           string_len;
1907
1908   if (si.request) {
1909     /* Request(s) dissect code */
1910
1911     /* Build display for: Word Count (WCT) */
1912
1913     WordCount = GBYTE(pd, offset);
1914
1915     if (tree) {
1916
1917       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1918
1919     }
1920
1921     offset += 1; /* Skip Word Count (WCT) */
1922
1923     /* Build display for: SearchAttributes */
1924
1925     SearchAttributes = GSHORT(pd, offset);
1926
1927     if (tree) {
1928
1929         proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
1930     }
1931
1932     offset += 2; /* Skip SearchAttributes */
1933
1934     /* Build display for: Byte Count (BCC) */
1935
1936     ByteCount = GSHORT(pd, offset);
1937
1938     if (tree) {
1939
1940       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1941
1942     }
1943
1944     offset += 2; /* Skip Byte Count (BCC) */
1945
1946     /* Build display for: Buffer Format */
1947
1948     BufferFormat = GBYTE(pd, offset);
1949
1950     if (tree) {
1951
1952       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
1953                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
1954                           BufferFormat);
1955
1956     }
1957
1958     offset += 1; /* Skip Buffer Format */
1959
1960     /* Build display for: File Name */
1961
1962     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
1963
1964     if (tree) {
1965
1966       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
1967
1968     }
1969
1970     offset += string_len; /* Skip File Name */
1971
1972   } else {
1973     /* Response(s) dissect code */
1974
1975     /* Build display for: Word Count (WCT) */
1976
1977     WordCount = GBYTE(pd, offset);
1978
1979     if (tree) {
1980
1981       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1982
1983     }
1984
1985     offset += 1; /* Skip Word Count (WCT) */
1986
1987     /* Build display for: Byte Count (BCC) */
1988
1989     ByteCount = GSHORT(pd, offset);
1990
1991     if (tree) {
1992
1993       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1994
1995     }
1996
1997     offset += 2; /* Skip Byte Count (BCC) */
1998
1999   }
2000
2001 }
2002
2003 void
2004 dissect_query_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
2005
2006 {
2007   proto_tree    *Attributes_tree;
2008   proto_item    *ti;
2009   guint8        WordCount;
2010   guint32       FileDataSize;
2011   guint32       FileAllocationSize;
2012   guint16       LastWriteTime;
2013   guint16       LastWriteDate;
2014   guint16       LastAccessTime;
2015   guint16       LastAccessDate;
2016   guint16       FID;
2017   guint16       CreationTime;
2018   guint16       CreationDate;
2019   guint16       ByteCount;
2020   guint16       Attributes;
2021
2022   if (si.request) {
2023     /* Request(s) dissect code */
2024
2025     /* Build display for: Word Count (WCT) */
2026
2027     WordCount = GBYTE(pd, offset);
2028
2029     if (tree) {
2030
2031       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2032
2033     }
2034
2035     offset += 1; /* Skip Word Count (WCT) */
2036
2037     /* Build display for: FID */
2038
2039     FID = GSHORT(pd, offset);
2040
2041     if (tree) {
2042
2043       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
2044
2045     }
2046
2047     offset += 2; /* Skip FID */
2048
2049     /* Build display for: Byte Count */
2050
2051     ByteCount = GSHORT(pd, offset);
2052
2053     if (tree) {
2054
2055       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
2056
2057     }
2058
2059     offset += 2; /* Skip Byte Count */
2060
2061   } else {
2062     /* Response(s) dissect code */
2063
2064     /* Build display for: Word Count (WCT) */
2065
2066     WordCount = GBYTE(pd, offset);
2067
2068     if (tree) {
2069
2070       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2071
2072     }
2073
2074     offset += 1; /* Skip Word Count (WCT) */
2075
2076     if (WordCount != 0) {
2077
2078       /* Build display for: Creation Date */
2079
2080       CreationDate = GSHORT(pd, offset);
2081
2082       if (tree) {
2083
2084         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
2085
2086       }
2087
2088       offset += 2; /* Skip Creation Date */
2089
2090       /* Build display for: Creation Time */
2091
2092       CreationTime = GSHORT(pd, offset);
2093
2094       if (tree) {
2095
2096         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
2097
2098       }
2099
2100       offset += 2; /* Skip Creation Time */
2101
2102       /* Build display for: Last Access Date */
2103
2104       LastAccessDate = GSHORT(pd, offset);
2105
2106       if (tree) {
2107
2108         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
2109
2110       }
2111
2112       offset += 2; /* Skip Last Access Date */
2113
2114       /* Build display for: Last Access Time */
2115
2116       LastAccessTime = GSHORT(pd, offset);
2117
2118       if (tree) {
2119
2120         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
2121
2122       }
2123
2124       offset += 2; /* Skip Last Access Time */
2125
2126       /* Build display for: Last Write Date */
2127
2128       LastWriteDate = GSHORT(pd, offset);
2129
2130       if (tree) {
2131
2132         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
2133
2134       }
2135
2136       offset += 2; /* Skip Last Write Date */
2137
2138       /* Build display for: Last Write Time */
2139
2140       LastWriteTime = GSHORT(pd, offset);
2141
2142       if (tree) {
2143
2144         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
2145
2146       }
2147
2148       offset += 2; /* Skip Last Write Time */
2149
2150       /* Build display for: File Data Size */
2151
2152       FileDataSize = GWORD(pd, offset);
2153
2154       if (tree) {
2155         
2156         proto_tree_add_text(tree, NullTVB, offset, 4, "File Data Size: %u", FileDataSize);
2157
2158       }
2159
2160       offset += 4; /* Skip File Data Size */
2161
2162       /* Build display for: File Allocation Size */
2163
2164       FileAllocationSize = GWORD(pd, offset);
2165
2166       if (tree) {
2167
2168         proto_tree_add_text(tree, NullTVB, offset, 4, "File Allocation Size: %u", FileAllocationSize);
2169
2170       }
2171
2172       offset += 4; /* Skip File Allocation Size */
2173
2174       /* Build display for: Attributes */
2175
2176       Attributes = GSHORT(pd, offset);
2177       
2178       if (tree) {
2179
2180         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
2181         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
2182         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2183                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
2184         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2185                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
2186         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2187                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
2188         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2189                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
2190         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2191                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
2192         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
2193                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
2194     
2195       }
2196
2197       offset += 2; /* Skip Attributes */
2198
2199     }
2200
2201     /* Build display for: Byte Count */
2202
2203     ByteCount = GSHORT(pd, offset);
2204
2205     if (tree) {
2206
2207       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
2208
2209     }
2210
2211     offset += 2; /* Skip Byte Count */
2212
2213   }
2214
2215 }
2216
2217 void
2218 dissect_treecon_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
2219
2220 {
2221   guint8        WordCount;
2222   guint8        BufferFormat3;
2223   guint8        BufferFormat2;
2224   guint8        BufferFormat1;
2225   guint16       TID;
2226   guint16       MaxBufferSize;
2227   guint16       ByteCount;
2228   const char    *SharePath;
2229   const char    *Service;
2230   const char    *Password;
2231   int           string_len;
2232
2233   if (si.request) {
2234     /* Request(s) dissect code */
2235
2236     /* Build display for: Word Count (WCT) */
2237
2238     WordCount = GBYTE(pd, offset);
2239
2240     if (tree) {
2241
2242       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2243
2244     }
2245
2246     offset += 1; /* Skip Word Count (WCT) */
2247
2248     /* Build display for: Byte Count (BCC) */
2249
2250     ByteCount = GSHORT(pd, offset);
2251
2252     if (tree) {
2253
2254       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2255
2256     }
2257
2258     offset += 2; /* Skip Byte Count (BCC) */
2259
2260     /* Build display for: BufferFormat1 */
2261
2262     BufferFormat1 = GBYTE(pd, offset);
2263
2264     if (tree) {
2265
2266       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
2267                           val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
2268                           BufferFormat1);
2269
2270     }
2271
2272     offset += 1; /* Skip BufferFormat1 */
2273
2274     /* Build display for: Share Path */
2275
2276     SharePath = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
2277
2278     if (tree) {
2279
2280       proto_tree_add_text(tree, NullTVB, offset, string_len, "Share Path: %s", SharePath);
2281
2282     }
2283
2284     offset += string_len; /* Skip Share Path */
2285
2286     /* Build display for: BufferFormat2 */
2287
2288     BufferFormat2 = GBYTE(pd, offset);
2289
2290     if (tree) {
2291
2292       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
2293                           val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
2294                           BufferFormat2);
2295
2296     }
2297
2298     offset += 1; /* Skip BufferFormat2 */
2299
2300     /* Build display for: Password */
2301
2302     Password = pd + offset;
2303
2304     if (tree) {
2305
2306       proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
2307
2308     }
2309
2310     offset += strlen(Password) + 1; /* Skip Password */
2311
2312     /* Build display for: BufferFormat3 */
2313
2314     BufferFormat3 = GBYTE(pd, offset);
2315
2316     if (tree) {
2317
2318       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 3: %s (%u)",
2319                           val_to_str(BufferFormat3, buffer_format_vals, "Unknown"),
2320                           BufferFormat3);
2321
2322     }
2323
2324     offset += 1; /* Skip BufferFormat3 */
2325
2326     /* Build display for: Service */
2327
2328     Service = pd + offset;
2329
2330     if (tree) {
2331
2332       proto_tree_add_text(tree, NullTVB, offset, strlen(Service) + 1, "Service: %s", Service);
2333
2334     }
2335
2336     offset += strlen(Service) + 1; /* Skip Service */
2337
2338   } else {
2339     /* Response(s) dissect code */
2340
2341     /* Build display for: Word Count (WCT) */
2342
2343     WordCount = GBYTE(pd, offset);
2344
2345     if (tree) {
2346
2347       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2348
2349     }
2350
2351     offset += 1; /* Skip Word Count (WCT) */
2352
2353     if (WordCount != 0) {
2354
2355       /* Build display for: Max Buffer Size */
2356
2357       MaxBufferSize = GSHORT(pd, offset);
2358
2359       if (tree) {
2360
2361         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Buffer Size: %u", MaxBufferSize);
2362
2363       }
2364
2365       offset += 2; /* Skip Max Buffer Size */
2366
2367       /* Build display for: TID */
2368
2369       TID = GSHORT(pd, offset);
2370
2371       if (tree) {
2372
2373         proto_tree_add_text(tree, NullTVB, offset, 2, "TID: %u", TID);
2374
2375       }
2376
2377       offset += 2; /* Skip TID */
2378
2379     }
2380
2381     /* Build display for: Byte Count (BCC) */
2382
2383     ByteCount = GSHORT(pd, offset);
2384
2385     if (tree) {
2386
2387       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2388
2389     }
2390
2391     offset += 2; /* Skip Byte Count (BCC) */
2392
2393   }
2394
2395 }
2396
2397 /* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
2398 void
2399 dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
2400
2401 {
2402   proto_tree    *Capabilities_tree;
2403   proto_tree    *Action_tree;
2404   proto_item    *ti;
2405   guint8        WordCount;
2406   guint8        AndXReserved;
2407   guint8        AndXCommand = 0xFF;
2408   guint32       SessionKey;
2409   guint32       Reserved;
2410   guint32       Capabilities;
2411   guint16       VcNumber;
2412   guint16       SecurityBlobLength;
2413   guint16       ANSIAccountPasswordLength;
2414   guint16       UNICODEAccountPasswordLength;
2415   guint16       PasswordLen;
2416   guint16       MaxMpxCount;
2417   guint16       MaxBufferSize;
2418   guint16       ByteCount;
2419   guint16       AndXOffset = 0;
2420   guint16       Action;
2421   const char    *ANSIPassword;
2422   const char    *UNICODEPassword;
2423   const char    *SecurityBlob;
2424   const char    *Password;
2425   const char    *PrimaryDomain;
2426   const char    *NativeOS;
2427   const char    *NativeLanManType;
2428   const char    *NativeLanMan;
2429   const char    *AccountName;
2430   int           string_len;
2431
2432   if (si.request) {
2433     /* Request(s) dissect code */
2434
2435     /* Build display for: Word Count (WCT) */
2436
2437     WordCount = GBYTE(pd, offset);
2438
2439     if (tree) {
2440
2441       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2442
2443     }
2444
2445     offset += 1; /* Skip Word Count (WCT) */
2446
2447     switch (WordCount) {
2448
2449     case 10:
2450
2451       /* Build display for: AndXCommand */
2452
2453       AndXCommand = GBYTE(pd, offset);
2454
2455       if (tree) {
2456
2457         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2458                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2459
2460       }
2461
2462       offset += 1; /* Skip AndXCommand */
2463
2464       /* Build display for: AndXReserved */
2465
2466       AndXReserved = GBYTE(pd, offset);
2467
2468       if (tree) {
2469
2470         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2471
2472       }
2473
2474       offset += 1; /* Skip AndXReserved */
2475
2476       /* Build display for: AndXOffset */
2477
2478       AndXOffset = GSHORT(pd, offset);
2479
2480       if (tree) {
2481
2482         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2483
2484       }
2485
2486       offset += 2; /* Skip AndXOffset */
2487
2488       /* Build display for: MaxBufferSize */
2489
2490       MaxBufferSize = GSHORT(pd, offset);
2491
2492       if (tree) {
2493
2494         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2495
2496       }
2497
2498       offset += 2; /* Skip MaxBufferSize */
2499
2500       /* Build display for: MaxMpxCount */
2501
2502       MaxMpxCount = GSHORT(pd, offset);
2503
2504       if (tree) {
2505
2506         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2507
2508       }
2509
2510       offset += 2; /* Skip MaxMpxCount */
2511
2512       /* Build display for: VcNumber */
2513
2514       VcNumber = GSHORT(pd, offset);
2515
2516       if (tree) {
2517
2518         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2519
2520       }
2521
2522       offset += 2; /* Skip VcNumber */
2523
2524       /* Build display for: SessionKey */
2525
2526       SessionKey = GWORD(pd, offset);
2527
2528       if (tree) {
2529
2530         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2531
2532       }
2533
2534       offset += 4; /* Skip SessionKey */
2535
2536       /* Build display for: PasswordLen */
2537
2538       PasswordLen = GSHORT(pd, offset);
2539
2540       if (tree) {
2541
2542         proto_tree_add_text(tree, NullTVB, offset, 2, "PasswordLen: %u", PasswordLen);
2543
2544       }
2545
2546       offset += 2; /* Skip PasswordLen */
2547
2548       /* Build display for: Reserved */
2549
2550       Reserved = GWORD(pd, offset);
2551
2552       if (tree) {
2553
2554         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2555
2556       }
2557
2558       offset += 4; /* Skip Reserved */
2559
2560       /* Build display for: Byte Count (BCC) */
2561
2562       ByteCount = GSHORT(pd, offset);
2563
2564       if (tree) {
2565
2566         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2567
2568       }
2569
2570       offset += 2; /* Skip Byte Count (BCC) */
2571
2572       if (ByteCount > 0) {
2573
2574         /* Build display for: Password */
2575
2576         Password = pd + offset;
2577
2578         if (tree) {
2579
2580           proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
2581
2582         }
2583
2584         offset += PasswordLen;
2585
2586         /* Build display for: AccountName */
2587
2588         AccountName = pd + offset;
2589
2590         if (tree) {
2591
2592           proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
2593
2594         }
2595
2596         offset += strlen(AccountName) + 1; /* Skip AccountName */
2597
2598         /* Build display for: PrimaryDomain */
2599
2600         PrimaryDomain = pd + offset;
2601
2602         if (tree) {
2603
2604           proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
2605
2606         }
2607
2608         offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
2609
2610         /* Build display for: NativeOS */
2611
2612         NativeOS = pd + offset;
2613
2614         if (tree) {
2615
2616           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
2617
2618         }
2619
2620         offset += strlen(NativeOS) + 1; /* Skip NativeOS */
2621
2622         /* Build display for: NativeLanMan */
2623
2624         NativeLanMan = pd + offset;
2625
2626         if (tree) {
2627
2628           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "Native Lan Manager: %s", NativeLanMan);
2629
2630         }
2631
2632         offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
2633
2634       }
2635
2636       break;
2637
2638     case 12:
2639
2640       /* Build display for: AndXCommand */
2641
2642       AndXCommand = GBYTE(pd, offset);
2643
2644       if (tree) {
2645
2646         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2647                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2648
2649       }
2650
2651       offset += 1; /* Skip AndXCommand */
2652
2653       /* Build display for: AndXReserved */
2654
2655       AndXReserved = GBYTE(pd, offset);
2656
2657       if (tree) {
2658
2659         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2660
2661       }
2662
2663       offset += 1; /* Skip AndXReserved */
2664
2665       /* Build display for: AndXOffset */
2666
2667       AndXOffset = GSHORT(pd, offset);
2668
2669       if (tree) {
2670
2671         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2672
2673       }
2674
2675       offset += 2; /* Skip AndXOffset */
2676
2677       /* Build display for: MaxBufferSize */
2678
2679       MaxBufferSize = GSHORT(pd, offset);
2680
2681       if (tree) {
2682
2683         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2684
2685       }
2686
2687       offset += 2; /* Skip MaxBufferSize */
2688
2689       /* Build display for: MaxMpxCount */
2690
2691       MaxMpxCount = GSHORT(pd, offset);
2692
2693       if (tree) {
2694
2695         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2696
2697       }
2698
2699       offset += 2; /* Skip MaxMpxCount */
2700
2701       /* Build display for: VcNumber */
2702
2703       VcNumber = GSHORT(pd, offset);
2704
2705       if (tree) {
2706
2707         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2708
2709       }
2710
2711       offset += 2; /* Skip VcNumber */
2712
2713       /* Build display for: SessionKey */
2714
2715       SessionKey = GWORD(pd, offset);
2716
2717       if (tree) {
2718
2719         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2720
2721       }
2722
2723       offset += 4; /* Skip SessionKey */
2724
2725       /* Build display for: Security Blob Length */
2726
2727       SecurityBlobLength = GSHORT(pd, offset);
2728
2729       if (tree) {
2730
2731         proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
2732
2733       }
2734
2735       offset += 2; /* Skip Security Blob Length */
2736
2737       /* Build display for: Reserved */
2738
2739       Reserved = GWORD(pd, offset);
2740
2741       if (tree) {
2742
2743         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2744
2745       }
2746
2747       offset += 4; /* Skip Reserved */
2748
2749       /* Build display for: Capabilities */
2750
2751       Capabilities = GWORD(pd, offset);
2752
2753       if (tree) {
2754
2755         ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
2756         Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
2757         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2758                             decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
2759         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2760                             decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
2761         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2762                             decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
2763         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2764                             decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
2765         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2766                             decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
2767         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2768                             decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
2769         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2770                             decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
2771         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2772                             decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
2773         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2774                             decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
2775         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2776                             decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
2777         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2778                             decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
2779         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2780                             decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
2781         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2782                             decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
2783         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2784                             decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
2785
2786       }
2787
2788       offset += 4; /* Skip Capabilities */
2789
2790       /* Build display for: Byte Count */
2791
2792       ByteCount = GSHORT(pd, offset);
2793
2794       if (tree) {
2795
2796         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
2797
2798       }
2799
2800       offset += 2; /* Skip Byte Count */
2801
2802       if (ByteCount > 0) {
2803
2804         /* Build display for: Security Blob */
2805
2806         SecurityBlob = pd + offset;
2807
2808         if (SecurityBlobLength > 0) {
2809
2810           /* XXX - is this ASN.1-encoded?  Is it a Kerberos data structure,
2811              at least in NT 5.0-and-later server replies? */
2812
2813           if (tree) {
2814
2815             proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
2816                                 bytes_to_str(SecurityBlob, SecurityBlobLength));
2817
2818           }
2819
2820           offset += SecurityBlobLength; /* Skip Security Blob */
2821
2822         }
2823
2824         /* Build display for: Native OS */
2825
2826         NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
2827
2828         if (tree) {
2829
2830           proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
2831
2832         }
2833
2834         offset += string_len; /* Skip Native OS */
2835
2836         /* Build display for: Native LanMan Type */
2837
2838         NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
2839
2840         if (tree) {
2841
2842           proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
2843
2844         }
2845
2846         offset += string_len; /* Skip Native LanMan Type */
2847
2848         /* Build display for: Primary Domain */
2849
2850         PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
2851
2852         if (tree) {
2853
2854           proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
2855
2856         }
2857
2858         offset += string_len; /* Skip Primary Domain */
2859
2860       }
2861
2862       break;
2863
2864     case 13:
2865
2866       /* Build display for: AndXCommand */
2867
2868       AndXCommand = GBYTE(pd, offset);
2869
2870       if (tree) {
2871
2872         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2873                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2874
2875       }
2876
2877       offset += 1; /* Skip AndXCommand */
2878
2879       /* Build display for: AndXReserved */
2880
2881       AndXReserved = GBYTE(pd, offset);
2882
2883       if (tree) {
2884
2885         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2886
2887       }
2888
2889       offset += 1; /* Skip AndXReserved */
2890
2891       /* Build display for: AndXOffset */
2892
2893       AndXOffset = GSHORT(pd, offset);
2894
2895       if (tree) {
2896
2897         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2898
2899       }
2900
2901       offset += 2; /* Skip AndXOffset */
2902
2903       /* Build display for: MaxBufferSize */
2904
2905       MaxBufferSize = GSHORT(pd, offset);
2906
2907       if (tree) {
2908
2909         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2910
2911       }
2912
2913       offset += 2; /* Skip MaxBufferSize */
2914
2915       /* Build display for: MaxMpxCount */
2916
2917       MaxMpxCount = GSHORT(pd, offset);
2918
2919       if (tree) {
2920
2921         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2922
2923       }
2924
2925       offset += 2; /* Skip MaxMpxCount */
2926
2927       /* Build display for: VcNumber */
2928
2929       VcNumber = GSHORT(pd, offset);
2930
2931       if (tree) {
2932
2933         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2934
2935       }
2936
2937       offset += 2; /* Skip VcNumber */
2938
2939       /* Build display for: SessionKey */
2940
2941       SessionKey = GWORD(pd, offset);
2942
2943       if (tree) {
2944
2945         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2946
2947       }
2948
2949       offset += 4; /* Skip SessionKey */
2950
2951       /* Build display for: ANSI Account Password Length */
2952
2953       ANSIAccountPasswordLength = GSHORT(pd, offset);
2954
2955       if (tree) {
2956
2957         proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
2958
2959       }
2960
2961       offset += 2; /* Skip ANSI Account Password Length */
2962
2963       /* Build display for: UNICODE Account Password Length */
2964
2965       UNICODEAccountPasswordLength = GSHORT(pd, offset);
2966
2967       if (tree) {
2968
2969         proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
2970
2971       }
2972
2973       offset += 2; /* Skip UNICODE Account Password Length */
2974
2975       /* Build display for: Reserved */
2976
2977       Reserved = GWORD(pd, offset);
2978
2979       if (tree) {
2980
2981         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2982
2983       }
2984
2985       offset += 4; /* Skip Reserved */
2986
2987       /* Build display for: Capabilities */
2988
2989       Capabilities = GWORD(pd, offset);
2990
2991       if (tree) {
2992
2993         ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%08x", Capabilities);
2994         Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
2995         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2996                             decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
2997         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2998                             decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
2999         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3000                             decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
3001         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3002                             decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
3003         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3004                             decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
3005         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3006                             decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
3007         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3008                             decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
3009         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3010                             decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
3011         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3012                             decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
3013         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3014                             decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
3015         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3016                             decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
3017         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3018                             decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
3019         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3020                             decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
3021         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
3022                             decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
3023       
3024       }
3025
3026       offset += 4; /* Skip Capabilities */
3027
3028       /* Build display for: Byte Count */
3029
3030       ByteCount = GSHORT(pd, offset);
3031
3032       if (tree) {
3033
3034         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
3035
3036       }
3037
3038       offset += 2; /* Skip Byte Count */
3039
3040       if (ByteCount > 0) {
3041
3042         /* Build display for: ANSI Password */
3043
3044         ANSIPassword = pd + offset;
3045
3046         if (ANSIAccountPasswordLength > 0) {
3047
3048             if (tree) {
3049
3050                 proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
3051
3052             }
3053
3054             offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
3055         }
3056
3057         /* Build display for: UNICODE Password */
3058
3059         UNICODEPassword = pd + offset;
3060
3061         if (UNICODEAccountPasswordLength > 0) {
3062
3063           if (tree) {
3064
3065             proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
3066
3067           }
3068
3069           offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
3070
3071         }
3072
3073         /* Build display for: Account Name */
3074
3075         AccountName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3076
3077         if (tree) {
3078
3079           proto_tree_add_text(tree, NullTVB, offset, string_len, "Account Name: %s", AccountName);
3080
3081         }
3082
3083         offset += string_len; /* Skip Account Name */
3084
3085         /* Build display for: Primary Domain */
3086
3087         /*
3088          * XXX - pre-W2K NT systems sometimes appear to stick an extra
3089          * byte in front of this, at least if all the strings are
3090          * ASCII and the account name is empty.  Another bug?
3091          */
3092
3093         PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3094
3095         if (tree) {
3096
3097           proto_tree_add_text(tree, NullTVB, offset, string_len, "Primary Domain: %s", PrimaryDomain);
3098
3099         }
3100
3101         offset += string_len; /* Skip Primary Domain */
3102
3103         /* Build display for: Native OS */
3104
3105         NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3106
3107         if (tree) {
3108
3109           proto_tree_add_text(tree, NullTVB, offset, string_len, "Native OS: %s", NativeOS);
3110
3111         }
3112
3113         offset += string_len; /* Skip Native OS */
3114
3115         /* Build display for: Native LanMan Type */
3116
3117         /*
3118          * XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
3119          * padding/null string/whatever in front of this.  W2K doesn't
3120          * appear to.  I suspect that's a bug that got fixed; I also
3121          * suspect that, in practice, nobody ever looks at that field
3122          * because the bug didn't appear to get fixed until NT 5.0....
3123          */
3124
3125         NativeLanManType = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3126
3127         if (tree) {
3128
3129           proto_tree_add_text(tree, NullTVB, offset, string_len, "Native LanMan Type: %s", NativeLanManType);
3130
3131         }
3132
3133         offset += string_len; /* Skip Native LanMan Type */
3134
3135       }
3136
3137       break;
3138
3139     default:
3140
3141       /* XXX - dump the parameter words, one word at a time? */
3142
3143       offset += WordCount;
3144
3145       /* Build display for: Byte Count (BCC) */
3146
3147       ByteCount = GSHORT(pd, offset);
3148
3149       if (tree) {
3150
3151         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3152
3153       }
3154
3155       offset += 2; /* Skip Byte Count (BCC) */
3156
3157       break;
3158
3159     }
3160
3161     if (AndXCommand != 0xFF) {
3162
3163       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
3164
3165     }
3166
3167   } else {
3168     /* Response(s) dissect code */
3169
3170     /* Build display for: Word Count (WCT) */
3171
3172     WordCount = GBYTE(pd, offset);
3173
3174     if (tree) {
3175
3176       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3177
3178     }
3179
3180     offset += 1; /* Skip Word Count (WCT) */
3181
3182     switch (WordCount) {
3183
3184     case 3:
3185
3186       /* Build display for: AndXCommand */
3187
3188       AndXCommand = GBYTE(pd, offset);
3189
3190       if (tree) {
3191
3192         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
3193                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
3194
3195       }
3196
3197       offset += 1; /* Skip AndXCommand */
3198
3199       /* Build display for: AndXReserved */
3200
3201       AndXReserved = GBYTE(pd, offset);
3202
3203       if (tree) {
3204
3205         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
3206
3207       }
3208
3209       offset += 1; /* Skip AndXReserved */
3210
3211       /* Build display for: AndXOffset */
3212
3213       AndXOffset = GSHORT(pd, offset);
3214
3215       if (tree) {
3216
3217         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
3218
3219       }
3220
3221       offset += 2; /* Skip AndXOffset */
3222
3223       /* Build display for: Action */
3224
3225       Action = GSHORT(pd, offset);
3226
3227       if (tree) {
3228
3229         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
3230         Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
3231         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
3232                             decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
3233
3234       }
3235
3236       offset += 2; /* Skip Action */
3237
3238       /* Build display for: Byte Count (BCC) */
3239
3240       ByteCount = GSHORT(pd, offset);
3241
3242       if (tree) {
3243
3244         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3245
3246       }
3247
3248       offset += 2; /* Skip Byte Count (BCC) */
3249
3250       if (ByteCount > 0) {
3251
3252         /* Build display for: NativeOS */
3253
3254         NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3255
3256         if (tree) {
3257
3258           proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
3259
3260         }
3261
3262         offset += string_len; /* Skip NativeOS */
3263
3264         /* Build display for: NativeLanMan */
3265
3266         NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3267
3268         if (tree) {
3269
3270           proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
3271
3272         }
3273
3274         offset += string_len; /* Skip NativeLanMan */
3275
3276         /* Build display for: PrimaryDomain */
3277
3278         PrimaryDomain = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3279
3280         if (tree) {
3281
3282           proto_tree_add_text(tree, NullTVB, offset, string_len, "PrimaryDomain: %s", PrimaryDomain);
3283
3284         }
3285
3286         offset += string_len; /* Skip PrimaryDomain */
3287
3288       }
3289
3290       break;
3291
3292     case 4:
3293
3294       /* Build display for: AndXCommand */
3295
3296       AndXCommand = GBYTE(pd, offset);
3297
3298       if (tree) {
3299
3300         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
3301                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
3302
3303       }
3304
3305       offset += 1; /* Skip AndXCommand */
3306
3307       /* Build display for: AndXReserved */
3308
3309       AndXReserved = GBYTE(pd, offset);
3310
3311       if (tree) {
3312
3313         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
3314
3315       }
3316
3317       offset += 1; /* Skip AndXReserved */
3318
3319       /* Build display for: AndXOffset */
3320
3321       AndXOffset = GSHORT(pd, offset);
3322
3323       if (tree) {
3324
3325         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
3326
3327       }
3328
3329
3330       offset += 2; /* Skip AndXOffset */
3331
3332       /* Build display for: Action */
3333
3334       Action = GSHORT(pd, offset);
3335
3336       if (tree) {
3337
3338         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
3339         Action_tree = proto_item_add_subtree(ti, ett_smb_ssetupandxaction);
3340         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
3341                             decode_boolean_bitfield(Action, 0x0001, 16, "Logged in as GUEST", "Not logged in as GUEST"));
3342
3343       }
3344
3345       offset += 2; /* Skip Action */
3346
3347       /* Build display for: Security Blob Length */
3348
3349       SecurityBlobLength = GSHORT(pd, offset);
3350
3351       if (tree) {
3352
3353         proto_tree_add_text(tree, NullTVB, offset, 2, "Security Blob Length: %u", SecurityBlobLength);
3354
3355       }
3356
3357       offset += 2; /* Skip Security Blob Length */
3358
3359       /* Build display for: Byte Count (BCC) */
3360
3361       ByteCount = GSHORT(pd, offset);
3362
3363       if (tree) {
3364
3365         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3366
3367       }
3368
3369       offset += 2; /* Skip Byte Count (BCC) */
3370
3371       if (ByteCount > 0) {
3372
3373         SecurityBlob = pd + offset;
3374
3375         if (SecurityBlobLength > 0) {
3376
3377           /* XXX - is this ASN.1-encoded?  Is it a Kerberos data structure,
3378              at least in NT 5.0-and-later server replies? */
3379
3380           if (tree) {
3381
3382             proto_tree_add_text(tree, NullTVB, offset, SecurityBlobLength, "Security Blob: %s",
3383                                 bytes_to_str(SecurityBlob, SecurityBlobLength));
3384
3385           }
3386
3387           offset += SecurityBlobLength; /* Skip Security Blob */
3388
3389         }
3390
3391         /* Build display for: NativeOS */
3392
3393         NativeOS = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3394
3395         if (tree) {
3396
3397           proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeOS: %s", NativeOS);
3398
3399         }
3400
3401         offset += string_len; /* Skip NativeOS */
3402
3403         /* Build display for: NativeLanMan */
3404
3405         NativeLanMan = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3406
3407         if (tree) {
3408
3409           proto_tree_add_text(tree, NullTVB, offset, string_len, "NativeLanMan: %s", NativeLanMan);
3410
3411         }
3412
3413         offset += string_len; /* Skip NativeLanMan */
3414
3415       }
3416
3417       break;
3418
3419     default:
3420
3421       /* XXX - dump the parameter words, one word at a time? */
3422
3423       offset += WordCount;
3424
3425       /* Build display for: Byte Count (BCC) */
3426
3427       ByteCount = GSHORT(pd, offset);
3428
3429       if (tree) {
3430
3431         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3432
3433       }
3434
3435       offset += 2; /* Skip Byte Count (BCC) */
3436
3437       break;
3438
3439     }
3440
3441     if (AndXCommand != 0xFF) {
3442
3443       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
3444
3445     }
3446
3447   }
3448
3449 }
3450
3451 void
3452 dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
3453
3454 {
3455   guint8      wct, andxcmd = 0xFF;
3456   guint16     andxoffs = 0, flags, passwdlen, bcc, optionsup;
3457   const char  *str;
3458   int         string_len;
3459   proto_tree  *flags_tree;
3460   proto_tree  *optionsup_tree;
3461   proto_item  *ti;
3462
3463   wct = pd[offset];
3464
3465   /* Now figure out what format we are talking about, 2, 3, or 4 response
3466    * words ...
3467    */
3468
3469   if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
3470       !(!si.request && (wct == 3)) && !(wct == 0)) {
3471
3472     if (tree) {
3473
3474       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
3475
3476       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
3477
3478       return;
3479
3480     }
3481     
3482   }
3483
3484   if (tree) {
3485
3486     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
3487
3488   }
3489
3490   offset += 1;
3491
3492   if (wct > 0) {
3493
3494     andxcmd = pd[offset];
3495
3496     if (tree) {
3497
3498       proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
3499                           (andxcmd == 0xFF) ? "No further commands":
3500                           decode_smb_name(andxcmd));
3501                 
3502       proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
3503
3504     }
3505
3506     offset += 2;
3507
3508     andxoffs = GSHORT(pd, offset);
3509
3510     if (tree) {
3511
3512       proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
3513
3514     }
3515
3516     offset += 2;
3517
3518   }
3519
3520   switch (wct) {
3521
3522   case 0:
3523
3524     bcc = GSHORT(pd, offset);
3525
3526     if (tree) {
3527
3528       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3529
3530     }
3531
3532     break;
3533
3534   case 4:
3535
3536     flags = GSHORT(pd, offset);
3537
3538     if (tree) {
3539
3540       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%04x", flags);
3541       flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
3542       proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s", 
3543                           decode_boolean_bitfield(flags, 0x0001, 16,
3544                                                   "Disconnect TID",
3545                                                   "Don't disconnect TID"));
3546
3547     }
3548
3549     offset += 2;
3550
3551     passwdlen = GSHORT(pd, offset);
3552
3553     if (tree) {
3554
3555       proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
3556
3557     }
3558
3559     offset += 2;
3560
3561     bcc = GSHORT(pd, offset);
3562
3563     if (tree) {
3564
3565       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3566
3567     }
3568
3569     offset += 2;
3570
3571     str = pd + offset;
3572
3573     if (tree) {
3574
3575       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
3576
3577     }
3578
3579     offset += passwdlen;
3580
3581     str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3582
3583     if (tree) {
3584
3585       proto_tree_add_text(tree, NullTVB, offset, string_len, "Path: %s", str);
3586
3587     }
3588
3589     offset += string_len;
3590
3591     str = pd + offset;
3592
3593     if (tree) {
3594
3595       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
3596
3597     }
3598
3599     break;
3600
3601   case 2:
3602
3603     bcc = GSHORT(pd, offset);
3604
3605     if (tree) {
3606
3607       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3608
3609     }
3610
3611     offset += 2;
3612
3613     str = pd + offset;
3614
3615     if (tree) {
3616
3617       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
3618                           str);
3619
3620     }
3621
3622     offset += strlen(str) + 1;
3623
3624     break;
3625
3626   case 3:
3627
3628     optionsup = GSHORT(pd, offset);
3629
3630     if (tree) {
3631
3632       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x", 
3633                           optionsup);
3634       optionsup_tree = proto_item_add_subtree(ti, ett_smb_optionsup);
3635       proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
3636                           decode_boolean_bitfield(optionsup, 0x0001, 16, "Share supports Search", "Share doesn't support Search"));
3637       proto_tree_add_text(optionsup_tree, NullTVB, offset, 2, "%s",
3638                           decode_boolean_bitfield(optionsup, 0x0002, 16, "Share is in DFS", "Share isn't in DFS"));
3639       
3640     }
3641
3642     offset += 2;
3643
3644     bcc = GSHORT(pd, offset);
3645
3646     if (tree) {
3647
3648       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3649
3650     }
3651
3652     offset += 2;
3653
3654     /*
3655      * NOTE: the Service string is always ASCII, even if the "strings are
3656      * Unicode" bit is set in the flags2 field of the SMB.
3657      */
3658
3659     str = pd + offset;
3660
3661     if (tree) {
3662
3663       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
3664
3665     }
3666
3667     offset += strlen(str) + 1;
3668
3669     str = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
3670
3671     if (tree) {
3672
3673       proto_tree_add_text(tree, NullTVB, offset, string_len, "Native File System: %s", str);
3674
3675     }
3676
3677     offset += string_len;
3678
3679     
3680     break;
3681
3682   default:
3683         ; /* nothing */
3684         break;
3685   }
3686
3687   if (andxcmd != 0xFF) /* Process that next command ... ??? */
3688
3689     (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset);
3690
3691 }
3692
3693 void 
3694 dissect_negprot_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
3695 {
3696   guint8        wct, enckeylen;
3697   guint16       bcc, mode, rawmode, dialect;
3698   guint32       caps;
3699   proto_tree    *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree;
3700   proto_item    *ti;
3701   const char    *str;
3702   char          *ustr;
3703   int           ustr_len;
3704
3705   wct = pd[offset];    /* Should be 0, 1 or 13 or 17, I think */
3706
3707   if (!((wct == 0) && si.request) && !((wct == 1) && !si.request) &&
3708       !((wct == 13) && !si.request) && !((wct == 17) && !si.request)) {
3709     if (tree) {
3710
3711       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., not %u", wct);
3712
3713       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
3714
3715       return;
3716     }
3717   }
3718
3719   if (tree) {
3720
3721     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %d", wct);
3722
3723   }
3724
3725   offset += 1; 
3726
3727   if (!si.request && wct == 0) {
3728
3729     /* Build display for: Byte Count (BCC) */
3730
3731     bcc = GSHORT(pd, offset);
3732
3733     if (tree) {
3734
3735       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3736
3737     }
3738
3739     offset += 2; /* Skip Byte Count (BCC) */
3740
3741     return;
3742
3743   }
3744
3745   /* Now decode the various formats ... */
3746
3747   switch (wct) {
3748
3749   case 0:     /* A request */
3750
3751     bcc = GSHORT(pd, offset);
3752
3753     if (tree) {
3754
3755       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3756
3757     }
3758
3759     offset += 2;
3760
3761     if (tree) {
3762
3763       ti = proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Dialects");
3764       dialects = proto_item_add_subtree(ti, ett_smb_dialects);
3765
3766     }
3767
3768     while (IS_DATA_IN_FRAME(offset)) {
3769       const char *str;
3770
3771       if (tree) {
3772
3773         proto_tree_add_text(dialects, NullTVB, offset, 1, "Dialect Marker: %d", pd[offset]);
3774
3775       }
3776
3777       offset += 1;
3778
3779       str = pd + offset;
3780
3781       if (tree) {
3782
3783         proto_tree_add_text(dialects, NullTVB, offset, strlen(str)+1, "Dialect: %s", str);
3784
3785       }
3786
3787       offset += strlen(str) + 1;
3788
3789     }
3790     break;
3791
3792   case 1:     /* PC NETWORK PROGRAM 1.0 */
3793
3794     dialect = GSHORT(pd, offset);
3795
3796     if (tree) {  /* Hmmmm, what if none of the dialects is recognized */
3797
3798       if (dialect == 0xFFFF) { /* Server didn't like them dialects */
3799
3800         proto_tree_add_text(tree, NullTVB, offset, 2, "Supplied dialects not recognized");
3801
3802       }
3803       else {
3804
3805         proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, PC NETWORK PROTGRAM 1.0", dialect);
3806
3807       }
3808
3809     }
3810
3811     offset += 2;
3812
3813     bcc = GSHORT(pd, offset);
3814
3815     if (tree) {
3816
3817       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3818
3819     }
3820
3821     break;
3822
3823   case 13:    /* Greater than Core and up to and incl LANMAN2.1  */
3824
3825     if (tree) {
3826
3827       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
3828
3829     }
3830
3831     /* Much of this is similar to response 17 below */
3832
3833     offset += 2;
3834
3835     mode = GSHORT(pd, offset);
3836
3837     if (tree) {
3838
3839       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Security Mode: 0x%04x", mode);
3840       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
3841       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
3842                           decode_boolean_bitfield(mode, 0x0001, 16,
3843                                                   "Security  = User",
3844                                                   "Security  = Share"));
3845       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
3846                           decode_boolean_bitfield(mode, 0x0002, 16,
3847                                                   "Passwords = Encrypted",
3848                                                   "Passwords = Plaintext"));
3849
3850     }
3851
3852     offset += 2;
3853
3854     if (tree) {
3855
3856       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GSHORT(pd, offset));
3857
3858     }
3859
3860     offset += 2;
3861
3862     if (tree) {
3863
3864       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
3865
3866     }
3867     
3868     offset += 2;
3869
3870     if (tree) {
3871
3872       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
3873
3874     }
3875
3876     offset += 2;
3877
3878     rawmode = GSHORT(pd, offset);
3879
3880     if (tree) {
3881
3882       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Raw Mode: 0x%04x", rawmode);
3883       rawmode_tree = proto_item_add_subtree(ti, ett_smb_rawmode);
3884       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
3885                           decode_boolean_bitfield(rawmode, 0x01, 16,
3886                                                   "Read Raw supported",
3887                                                   "Read Raw not supported"));
3888       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
3889                           decode_boolean_bitfield(rawmode, 0x02, 16,
3890                                                   "Write Raw supported",
3891                                                   "Write Raw not supported"));
3892
3893     }
3894
3895     offset += 2;
3896
3897     if (tree) {
3898
3899       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
3900
3901     }
3902
3903     offset += 4;
3904
3905     /* Now the server time, two short parameters ... */
3906
3907     if (tree) {
3908
3909       proto_tree_add_text(tree, NullTVB, offset, 2, "Server Time: %s",
3910                         dissect_dos_time(GSHORT(pd, offset)));
3911       proto_tree_add_text(tree, NullTVB, offset + 2, 2, "Server Date: %s",
3912                         dissect_dos_date(GSHORT(pd, offset + 2)));
3913
3914     }
3915
3916     offset += 4;
3917
3918     /* Server Time Zone, SHORT */
3919
3920     if (tree) {
3921
3922       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
3923                           (signed short)GSSHORT(pd, offset));
3924
3925     }
3926
3927     offset += 2;
3928
3929     /* Challenge Length */
3930
3931     enckeylen = GSHORT(pd, offset);
3932
3933     if (tree) {
3934
3935       proto_tree_add_text(tree, NullTVB, offset, 2, "Challenge Length: %u", enckeylen);
3936
3937     }
3938
3939     offset += 2;
3940
3941     if (tree) {
3942
3943       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u (MBZ)", GSHORT(pd, offset));
3944
3945     }
3946
3947     offset += 2;
3948
3949     bcc = GSHORT(pd, offset);
3950
3951     if (tree) {
3952
3953       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
3954
3955     }
3956
3957     offset += 2;
3958
3959     if (enckeylen) { /* only if non-zero key len */
3960
3961       str = pd + offset;
3962
3963       if (tree) {
3964
3965         proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge: %s",
3966                                 bytes_to_str(str, enckeylen));
3967       }
3968
3969       offset += enckeylen;
3970
3971     }
3972
3973     /* Primary Domain ... */
3974
3975     str = pd + offset;
3976
3977     if (tree) {
3978
3979       proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "Primary Domain: %s", str);
3980
3981     }
3982
3983     break;
3984
3985   case 17:    /* Greater than LANMAN2.1 */
3986
3987     if (tree) {
3988
3989       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than LANMAN2.1", GSHORT(pd, offset));
3990
3991     }
3992
3993     offset += 2;
3994
3995     mode = GBYTE(pd, offset);
3996
3997     if (tree) {
3998
3999       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Security Mode: 0x%02x", mode);
4000       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
4001       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
4002                           decode_boolean_bitfield(mode, 0x01, 8,
4003                                                   "Security  = User",
4004                                                   "Security  = Share"));
4005       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
4006                           decode_boolean_bitfield(mode, 0x02, 8,
4007                                                   "Passwords = Encrypted",
4008                                                   "Passwords = Plaintext"));
4009       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
4010                           decode_boolean_bitfield(mode, 0x04, 8,
4011                                                   "Security signatures enabled",
4012                                                   "Security signatures not enabled"));
4013       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
4014                           decode_boolean_bitfield(mode, 0x08, 8,
4015                                                   "Security signatures required",
4016                                                   "Security signatures not required"));
4017
4018     }
4019
4020     offset += 1;
4021
4022     if (tree) {
4023
4024       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
4025
4026     }
4027     
4028     offset += 2;
4029
4030     if (tree) {
4031
4032       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
4033
4034     }
4035
4036     offset += 2;
4037
4038     if (tree) {
4039
4040       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GWORD(pd, offset));
4041
4042     }
4043
4044     offset += 4;
4045
4046     if (tree) {
4047
4048       proto_tree_add_text(tree, NullTVB, offset, 4, "Max raw size:        %u", GWORD(pd, offset));
4049
4050     }
4051
4052     offset += 4;
4053
4054     if (tree) {
4055
4056       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
4057
4058     }
4059
4060     offset += 4;
4061
4062     caps = GWORD(pd, offset);
4063
4064     if (tree) {
4065
4066       ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", caps);
4067       caps_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
4068       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4069                           decode_boolean_bitfield(caps, 0x0001, 32,
4070                                                   "Raw Mode supported",
4071                                                   "Raw Mode not supported"));
4072       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4073                           decode_boolean_bitfield(caps, 0x0002, 32,
4074                                                   "MPX Mode supported",
4075                                                   "MPX Mode not supported"));
4076       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4077                           decode_boolean_bitfield(caps, 0x0004, 32,
4078                                                   "Unicode supported",
4079                                                   "Unicode not supported"));
4080       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4081                           decode_boolean_bitfield(caps, 0x0008, 32,
4082                                                   "Large files supported",
4083                                                   "Large files not supported"));
4084       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4085                           decode_boolean_bitfield(caps, 0x0010, 32, 
4086                                                   "NT LM 0.12 SMBs supported",
4087                                                   "NT LM 0.12 SMBs not supported"));
4088       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4089                           decode_boolean_bitfield(caps, 0x0020, 32,
4090                                                   "RPC remote APIs supported",
4091                                                   "RPC remote APIs not supported"));
4092       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4093                           decode_boolean_bitfield(caps, 0x0040, 32,
4094                                                   "NT status codes supported",
4095                                                   "NT status codes  not supported"));
4096       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4097                           decode_boolean_bitfield(caps, 0x0080, 32,
4098                                                   "Level 2 OpLocks supported",
4099                                                   "Level 2 OpLocks not supported"));
4100       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4101                           decode_boolean_bitfield(caps, 0x0100, 32,
4102                                                   "Lock&Read supported",
4103                                                   "Lock&Read not supported"));
4104       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4105                           decode_boolean_bitfield(caps, 0x0200, 32,
4106                                                   "NT Find supported",
4107                                                   "NT Find not supported"));
4108       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4109                           decode_boolean_bitfield(caps, 0x1000, 32,
4110                                                   "DFS supported",
4111                                                   "DFS not supported"));
4112       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4113                           decode_boolean_bitfield(caps, 0x4000, 32,
4114                                                   "Large READX supported",
4115                                                   "Large READX not supported"));
4116       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4117                           decode_boolean_bitfield(caps, 0x8000, 32,
4118                                                   "Large WRITEX supported",
4119                                                   "Large WRITEX not supported"));
4120       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
4121                           decode_boolean_bitfield(caps, 0x80000000, 32,
4122                                                   "Extended security exchanges supported",
4123                                                   "Extended security exchanges not supported"));
4124     }
4125
4126     offset += 4;
4127
4128     /* Server time, 2 WORDS */
4129
4130     if (tree) {
4131
4132       proto_tree_add_text(tree, NullTVB, offset, 4, "System Time Low: 0x%08x", GWORD(pd, offset));
4133       proto_tree_add_text(tree, NullTVB, offset + 4, 4, "System Time High: 0x%08x", GWORD(pd, offset + 4)); 
4134
4135     }
4136
4137     offset += 8;
4138
4139     /* Server Time Zone, SHORT */
4140
4141     if (tree) {
4142
4143       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
4144                           (signed short)GSSHORT(pd, offset));
4145
4146     }
4147
4148     offset += 2;
4149
4150     /* Encryption key len */
4151
4152     enckeylen = pd[offset];
4153
4154     if (tree) {
4155
4156       proto_tree_add_text(tree, NullTVB, offset, 1, "Encryption key len: %u", enckeylen);
4157
4158     }
4159
4160     offset += 1;
4161
4162     bcc = GSHORT(pd, offset);
4163
4164     if (tree) {
4165
4166       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte count (BCC): %u", bcc);
4167
4168     }
4169
4170     offset += 2;
4171
4172     if (caps & 0x80000000) {
4173       /* Extended security */
4174
4175       /* GUID */
4176
4177       if (tree) {
4178
4179         /* XXX - show it in GUID form, with dashes or whatever */
4180         proto_tree_add_text(tree, NullTVB, offset, 16, "GUID: %s",
4181                                 bytes_to_str(&pd[offset], 16));
4182
4183       }
4184
4185       offset += 16;
4186
4187       /* Security blob */
4188       /* XXX - is this ASN.1-encoded?  Is it a Kerberos data structure,
4189          at least in NT 5.0-and-later server replies? */
4190
4191       if (bcc > 16) {
4192         bcc -= 16;
4193
4194         if (tree) {
4195
4196           proto_tree_add_text(tree, NullTVB, offset, bcc, "Security blob: %s",
4197                                 bytes_to_str(&pd[offset], bcc));
4198
4199         }
4200       }
4201     } else {
4202       /* Non-extended security */
4203
4204       if (enckeylen) { /* only if non-zero key len */
4205
4206         /* Encryption challenge key */
4207
4208         str = pd + offset;
4209
4210         if (tree) {
4211
4212           proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge encryption key: %s",
4213                                 bytes_to_str(str, enckeylen));
4214
4215         }
4216
4217         offset += enckeylen;
4218
4219       }
4220
4221       /* The domain, a null terminated string; Unicode if "caps" has
4222          the 0x0004 bit set, ASCII (OEM character set) otherwise.
4223         XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
4224
4225       str = pd + offset;
4226
4227       if (tree) {
4228
4229         if (caps & 0x0004) {
4230           ustr = unicode_to_str(str, &ustr_len);
4231           proto_tree_add_text(tree, NullTVB, offset, ustr_len+2, "OEM domain name: %s", ustr);
4232         } else {
4233           proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "OEM domain name: %s", str);
4234         }
4235
4236       }
4237     }
4238
4239     break;
4240
4241   default:    /* Baddd */
4242
4243     if (tree)
4244       proto_tree_add_text(tree, NullTVB, offset, 1, "Bad format, should never get here");
4245     return;
4246
4247   }
4248
4249 }
4250
4251 void
4252 dissect_deletedir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
4253
4254 {
4255   guint8        WordCount;
4256   guint8        BufferFormat;
4257   guint16       ByteCount;
4258   const char    *DirectoryName;
4259   int           string_len;
4260
4261   if (si.request) {
4262     /* Request(s) dissect code */
4263
4264     /* Build display for: Word Count (WCT) */
4265
4266     WordCount = GBYTE(pd, offset);
4267
4268     if (tree) {
4269
4270       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4271
4272     }
4273
4274     offset += 1; /* Skip Word Count (WCT) */
4275
4276     /* Build display for: Byte Count (BCC) */
4277
4278     ByteCount = GSHORT(pd, offset);
4279
4280     if (tree) {
4281
4282       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4283
4284     }
4285
4286     offset += 2; /* Skip Byte Count (BCC) */
4287
4288     /* Build display for: Buffer Format */
4289
4290     BufferFormat = GBYTE(pd, offset);
4291
4292     if (tree) {
4293
4294       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
4295                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
4296                           BufferFormat);
4297
4298     }
4299
4300     offset += 1; /* Skip Buffer Format */
4301
4302     /* Build display for: Directory Name */
4303
4304     DirectoryName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
4305
4306     if (tree) {
4307
4308       proto_tree_add_text(tree, NullTVB, offset, string_len, "Directory Name: %s", DirectoryName);
4309
4310     }
4311
4312     offset += string_len; /* Skip Directory Name */
4313
4314   } else {
4315     /* Response(s) dissect code */
4316
4317     /* Build display for: Word Count (WCT) */
4318
4319     WordCount = GBYTE(pd, offset);
4320
4321     if (tree) {
4322
4323       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4324
4325     }
4326
4327     offset += 1; /* Skip Word Count (WCT) */
4328
4329     /* Build display for: Byte Count (BCC) */
4330
4331     ByteCount = GSHORT(pd, offset);
4332
4333     if (tree) {
4334
4335       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4336
4337     }
4338
4339     offset += 2; /* Skip Byte Count (BCC) */
4340
4341   }
4342
4343 }
4344
4345 void
4346 dissect_createdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
4347
4348 {
4349   guint8        WordCount;
4350   guint8        BufferFormat;
4351   guint16       ByteCount;
4352   const char    *DirectoryName;
4353   int           string_len;
4354
4355   if (si.request) {
4356     /* Request(s) dissect code */
4357
4358     /* Build display for: Word Count (WCT) */
4359
4360     WordCount = GBYTE(pd, offset);
4361
4362     if (tree) {
4363
4364       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4365
4366     }
4367
4368     offset += 1; /* Skip Word Count (WCT) */
4369
4370     /* Build display for: Byte Count (BCC) */
4371
4372     ByteCount = GSHORT(pd, offset);
4373
4374     if (tree) {
4375
4376       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4377
4378     }
4379
4380     offset += 2; /* Skip Byte Count (BCC) */
4381
4382     /* Build display for: Buffer Format */
4383
4384     BufferFormat = GBYTE(pd, offset);
4385
4386     if (tree) {
4387
4388       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
4389                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
4390                           BufferFormat);
4391
4392     }
4393
4394     offset += 1; /* Skip Buffer Format */
4395
4396     /* Build display for: Directory Name */
4397
4398     DirectoryName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
4399
4400     if (tree) {
4401
4402       proto_tree_add_text(tree, NullTVB, offset, string_len, "Directory Name: %s", DirectoryName);
4403
4404     }
4405
4406     offset += string_len; /* Skip Directory Name */
4407
4408   } else {
4409     /* Response(s) dissect code */
4410
4411     /* Build display for: Word Count (WCT) */
4412
4413     WordCount = GBYTE(pd, offset);
4414
4415     if (tree) {
4416
4417       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4418
4419     }
4420
4421     offset += 1; /* Skip Word Count (WCT) */
4422
4423     /* Build display for: Byte Count (BCC) */
4424
4425     ByteCount = GSHORT(pd, offset);
4426
4427     if (tree) {
4428
4429       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4430
4431     }
4432
4433     offset += 2; /* Skip Byte Count (BCC) */
4434
4435   }
4436
4437 }
4438
4439
4440 void
4441 dissect_checkdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
4442
4443 {
4444   guint8        WordCount;
4445   guint8        BufferFormat;
4446   guint16       ByteCount;
4447   const char    *DirectoryName;
4448   int           string_len;
4449
4450   if (si.request) {
4451     /* Request(s) dissect code */
4452
4453     /* Build display for: Word Count (WCT) */
4454
4455     WordCount = GBYTE(pd, offset);
4456
4457     if (tree) {
4458
4459       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4460
4461     }
4462
4463     offset += 1; /* Skip Word Count (WCT) */
4464
4465     /* Build display for: Byte Count (BCC) */
4466
4467     ByteCount = GSHORT(pd, offset);
4468
4469     if (tree) {
4470
4471       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4472
4473     }
4474
4475     offset += 2; /* Skip Byte Count (BCC) */
4476
4477     /* Build display for: Buffer Format */
4478
4479     BufferFormat = GBYTE(pd, offset);
4480
4481     if (tree) {
4482
4483       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
4484                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
4485                           BufferFormat);
4486
4487     }
4488
4489     offset += 1; /* Skip Buffer Format */
4490
4491     /* Build display for: Directory Name */
4492
4493     DirectoryName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
4494
4495     if (tree) {
4496
4497       proto_tree_add_text(tree, NullTVB, offset, string_len, "Directory Name: %s", DirectoryName);
4498
4499     }
4500
4501     offset += string_len; /* Skip Directory Name */
4502
4503   } else {
4504     /* Response(s) dissect code */
4505
4506     /* Build display for: Word Count (WCT) */
4507
4508     WordCount = GBYTE(pd, offset);
4509
4510     if (tree) {
4511
4512       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4513
4514     }
4515
4516     offset += 1; /* Skip Word Count (WCT) */
4517
4518     /* Build display for: Byte Count (BCC) */
4519
4520     ByteCount = GSHORT(pd, offset);
4521
4522     if (tree) {
4523
4524       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4525
4526     }
4527
4528     offset += 2; /* Skip Byte Count (BCC) */
4529
4530   }
4531
4532 }
4533
4534 void
4535 dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
4536
4537 {
4538   static const value_string OpenFunction_0x10[] = {
4539         { 0, "Fail if file does not exist"},
4540         { 16, "Create file if it does not exist"},
4541         { 0, NULL}
4542   };
4543   static const value_string OpenFunction_0x03[] = {
4544         { 0, "Fail if file exists"},
4545         { 1, "Open file if it exists"},
4546         { 2, "Truncate File if it exists"},
4547         { 0, NULL}
4548   };
4549   static const value_string FileType_0xFFFF[] = {
4550         { 0, "Disk file or directory"},
4551         { 1, "Named pipe in byte mode"},
4552         { 2, "Named pipe in message mode"},
4553         { 3, "Spooled printer"},
4554         { 0, NULL}
4555   };
4556   static const value_string DesiredAccess_0x70[] = {
4557         { 00, "Compatibility mode"},
4558         { 16, "Deny read/write/execute (exclusive)"},
4559         { 32, "Deny write"},
4560         { 48, "Deny read/execute"},
4561         { 64, "Deny none"},
4562         { 0, NULL}
4563   };
4564   static const value_string DesiredAccess_0x700[] = {
4565         { 0, "Locality of reference unknown"},
4566         { 256, "Mainly sequential access"},
4567         { 512, "Mainly random access"},
4568         { 768, "Random access with some locality"},
4569         {0, NULL}
4570   };
4571   static const value_string DesiredAccess_0x4000[] = {
4572         { 0, "Write through mode disabled"},
4573         { 16384, "Write through mode enabled"},
4574         {0, NULL}
4575   };
4576   static const value_string DesiredAccess_0x1000[] = {
4577         { 0, "Normal file (caching permitted)"},
4578         { 4096, "Do not cache this file"},
4579         {0, NULL}
4580   };
4581   static const value_string DesiredAccess_0x07[] = {
4582         { 0, "Open for reading"},
4583         { 1, "Open for writing"},
4584         { 2, "Open for reading and writing"},
4585         { 3, "Open for execute"},
4586         {0, NULL}
4587   };
4588   static const value_string Action_0x8000[] = {
4589         { 0, "File opened by another user (or mode not supported by server)"},
4590         { 32768, "File is opened only by this user at present"},
4591         {0, NULL}
4592   };
4593   static const value_string Action_0x0003[] = {
4594         { 0, "No action taken?"},
4595         { 1, "The file existed and was opened"},
4596         { 2, "The file did not exist but was created"},
4597         { 3, "The file existed and was truncated"},
4598         {0, NULL}
4599   };
4600   proto_tree    *Search_tree;
4601   proto_tree    *OpenFunction_tree;
4602   proto_tree    *Flags_tree;
4603   proto_tree    *File_tree;
4604   proto_tree    *FileType_tree;
4605   proto_tree    *FileAttributes_tree;
4606   proto_tree    *DesiredAccess_tree;
4607   proto_tree    *Action_tree;
4608   proto_item    *ti;
4609   guint8        WordCount;
4610   guint8        AndXReserved;
4611   guint8        AndXCommand = 0xFF;
4612   guint32       ServerFID;
4613   guint32       Reserved2;
4614   guint32       Reserved1;
4615   guint32       DataSize;
4616   guint32       AllocatedSize;
4617   guint16       Search;
4618   guint16       Reserved;
4619   guint16       OpenFunction;
4620   guint16       LastWriteTime;
4621   guint16       LastWriteDate;
4622   guint16       GrantedAccess;
4623   guint16       Flags;
4624   guint16       FileType;
4625   guint16       FileAttributes;
4626   guint16       File;
4627   guint16       FID;
4628   guint16       DeviceState;
4629   guint16       DesiredAccess;
4630   guint16       CreationTime;
4631   guint16       CreationDate;
4632   guint16       ByteCount;
4633   guint16       AndXOffset = 0;
4634   guint16       Action;
4635   const char    *FileName;
4636   int           string_len;
4637
4638   if (si.request) {
4639     /* Request(s) dissect code */
4640
4641     /* Build display for: Word Count (WCT) */
4642
4643     WordCount = GBYTE(pd, offset);
4644
4645     if (tree) {
4646
4647       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4648
4649     }
4650
4651     offset += 1; /* Skip Word Count (WCT) */
4652
4653     /* Build display for: AndXCommand */
4654
4655     AndXCommand = GBYTE(pd, offset);
4656
4657     if (tree) {
4658
4659       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
4660                           (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
4661
4662     }
4663
4664     offset += 1; /* Skip AndXCommand */
4665
4666     /* Build display for: AndXReserved */
4667
4668     AndXReserved = GBYTE(pd, offset);
4669
4670     if (tree) {
4671
4672       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
4673
4674     }
4675
4676     offset += 1; /* Skip AndXReserved */
4677
4678     /* Build display for: AndXOffset */
4679
4680     AndXOffset = GSHORT(pd, offset);
4681
4682     if (tree) {
4683
4684       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
4685
4686     }
4687
4688     offset += 2; /* Skip AndXOffset */
4689
4690     /* Build display for: Flags */
4691
4692     Flags = GSHORT(pd, offset);
4693
4694     if (tree) {
4695
4696       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
4697       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
4698       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
4699                           decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
4700       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
4701                           decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
4702       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
4703                           decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
4704     
4705     }
4706
4707     offset += 2; /* Skip Flags */
4708
4709     /* Build display for: Desired Access */
4710
4711     DesiredAccess = GSHORT(pd, offset);
4712
4713     if (tree) {
4714
4715       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
4716       DesiredAccess_tree = proto_item_add_subtree(ti, ett_smb_desiredaccess);
4717       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4718                           decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
4719       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4720                           decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
4721       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4722                           decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
4723       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4724                           decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
4725       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
4726                           decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
4727     
4728     }
4729
4730     offset += 2; /* Skip Desired Access */
4731
4732     /* Build display for: Search */
4733
4734     Search = GSHORT(pd, offset);
4735
4736     if (tree) {
4737
4738       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Search: 0x%02x", Search);
4739       Search_tree = proto_item_add_subtree(ti, ett_smb_search);
4740       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4741                           decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
4742       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4743                           decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
4744       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4745                           decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
4746       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4747                           decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
4748       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4749                           decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
4750       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
4751                           decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
4752     
4753     }
4754
4755     offset += 2; /* Skip Search */
4756
4757     /* Build display for: File */
4758
4759     File = GSHORT(pd, offset);
4760
4761     if (tree) {
4762
4763       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File: 0x%02x", File);
4764       File_tree = proto_item_add_subtree(ti, ett_smb_file);
4765       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4766                           decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
4767       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4768                           decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
4769       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4770                           decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
4771       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4772                           decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
4773       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4774                           decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
4775       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
4776                           decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
4777     
4778     }
4779
4780     offset += 2; /* Skip File */
4781
4782     /* Build display for: Creation Time */
4783
4784     CreationTime = GSHORT(pd, offset);
4785
4786     if (tree) {
4787
4788
4789     }
4790
4791     offset += 2; /* Skip Creation Time */
4792
4793     /* Build display for: Creation Date */
4794
4795     CreationDate = GSHORT(pd, offset);
4796
4797     if (tree) {
4798
4799       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_smbu_date(CreationDate, CreationTime));
4800       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_smbu_time(CreationDate, CreationTime));
4801
4802     }
4803
4804     offset += 2; /* Skip Creation Date */
4805
4806     /* Build display for: Open Function */
4807
4808     OpenFunction = GSHORT(pd, offset);
4809
4810     if (tree) {
4811
4812       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: 0x%02x", OpenFunction);
4813       OpenFunction_tree = proto_item_add_subtree(ti, ett_smb_openfunction);
4814       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
4815                           decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
4816       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
4817                           decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
4818     
4819     }
4820
4821     offset += 2; /* Skip Open Function */
4822
4823     /* Build display for: Allocated Size */
4824
4825     AllocatedSize = GWORD(pd, offset);
4826
4827     if (tree) {
4828
4829       proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
4830
4831     }
4832
4833     offset += 4; /* Skip Allocated Size */
4834
4835     /* Build display for: Reserved1 */
4836
4837     Reserved1 = GWORD(pd, offset);
4838
4839     if (tree) {
4840
4841       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
4842
4843     }
4844
4845     offset += 4; /* Skip Reserved1 */
4846
4847     /* Build display for: Reserved2 */
4848
4849     Reserved2 = GWORD(pd, offset);
4850
4851     if (tree) {
4852
4853       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
4854
4855     }
4856
4857     offset += 4; /* Skip Reserved2 */
4858
4859     /* Build display for: Byte Count */
4860
4861     ByteCount = GSHORT(pd, offset);
4862
4863     if (tree) {
4864
4865       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4866
4867     }
4868
4869     offset += 2; /* Skip Byte Count */
4870
4871     /* Build display for: File Name */
4872
4873     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
4874
4875     if (tree) {
4876
4877       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
4878
4879     }
4880
4881     offset += string_len; /* Skip File Name */
4882
4883
4884     if (AndXCommand != 0xFF) {
4885
4886       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
4887
4888     }
4889
4890   } else {
4891     /* Response(s) dissect code */
4892
4893     /* Build display for: Word Count (WCT) */
4894
4895     WordCount = GBYTE(pd, offset);
4896
4897     if (tree) {
4898
4899       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4900
4901     }
4902
4903     offset += 1; /* Skip Word Count (WCT) */
4904
4905     if (WordCount != 0) {
4906
4907       /* Build display for: AndXCommand */
4908
4909       AndXCommand = GBYTE(pd, offset);
4910
4911       if (tree) {
4912
4913         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
4914                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
4915
4916       }
4917
4918       offset += 1; /* Skip AndXCommand */
4919
4920       /* Build display for: AndXReserved */
4921
4922       AndXReserved = GBYTE(pd, offset);
4923
4924       if (tree) {
4925
4926         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
4927
4928       }
4929
4930       offset += 1; /* Skip AndXReserved */
4931
4932       /* Build display for: AndXOffset */
4933
4934       AndXOffset = GSHORT(pd, offset);
4935
4936       if (tree) {
4937
4938         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
4939
4940       }
4941
4942       offset += 2; /* Skip AndXOffset */
4943
4944       /* Build display for: FID */
4945
4946       FID = GSHORT(pd, offset);
4947
4948       if (tree) {
4949
4950         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4951
4952       }
4953
4954       offset += 2; /* Skip FID */
4955
4956       /* Build display for: FileAttributes */
4957
4958       FileAttributes = GSHORT(pd, offset);
4959
4960       if (tree) {
4961
4962         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
4963         FileAttributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
4964         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4965                             decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
4966         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4967                             decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
4968         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4969                             decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
4970         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4971                             decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
4972         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4973                             decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
4974         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
4975                             decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
4976     
4977       }
4978
4979       offset += 2; /* Skip FileAttributes */
4980
4981       /* Build display for: Last Write Time */
4982
4983       LastWriteTime = GSHORT(pd, offset);
4984
4985       if (tree) {
4986
4987       }
4988
4989       offset += 2; /* Skip Last Write Time */
4990
4991       /* Build display for: Last Write Date */
4992
4993       LastWriteDate = GSHORT(pd, offset);
4994
4995       if (tree) {
4996
4997         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
4998         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
4999
5000
5001       }
5002
5003       offset += 2; /* Skip Last Write Date */
5004
5005       /* Build display for: Data Size */
5006
5007       DataSize = GWORD(pd, offset);
5008
5009       if (tree) {
5010
5011         proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
5012
5013       }
5014
5015       offset += 4; /* Skip Data Size */
5016
5017       /* Build display for: Granted Access */
5018
5019       GrantedAccess = GSHORT(pd, offset);
5020
5021       if (tree) {
5022
5023         proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
5024
5025       }
5026
5027       offset += 2; /* Skip Granted Access */
5028
5029       /* Build display for: File Type */
5030
5031       FileType = GSHORT(pd, offset);
5032
5033       if (tree) {
5034
5035         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File Type: 0x%02x", FileType);
5036         FileType_tree = proto_item_add_subtree(ti, ett_smb_filetype);
5037         proto_tree_add_text(FileType_tree, NullTVB, offset, 2, "%s",
5038                           decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
5039     
5040       }
5041
5042       offset += 2; /* Skip File Type */
5043
5044       /* Build display for: Device State */
5045
5046       DeviceState = GSHORT(pd, offset);
5047
5048       if (tree) {
5049
5050         proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
5051
5052       }
5053
5054       offset += 2; /* Skip Device State */
5055
5056       /* Build display for: Action */
5057
5058       Action = GSHORT(pd, offset);
5059
5060       if (tree) {
5061
5062         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: 0x%02x", Action);
5063         Action_tree = proto_item_add_subtree(ti, ett_smb_openaction);
5064         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
5065                             decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
5066         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
5067                             decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
5068         
5069       }
5070       
5071       offset += 2; /* Skip Action */
5072
5073       /* Build display for: Server FID */
5074       
5075       ServerFID = GWORD(pd, offset);
5076
5077       if (tree) {
5078
5079         proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: %u", ServerFID);
5080
5081       }
5082
5083       offset += 4; /* Skip Server FID */
5084
5085       /* Build display for: Reserved */
5086
5087       Reserved = GSHORT(pd, offset);
5088
5089       if (tree) {
5090         
5091         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5092
5093       }
5094
5095       offset += 2; /* Skip Reserved */
5096
5097     }
5098
5099     /* Build display for: Byte Count */
5100
5101     ByteCount = GSHORT(pd, offset);
5102
5103     if (tree) {
5104
5105       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
5106
5107     }
5108
5109     offset += 2; /* Skip Byte Count */
5110
5111
5112     if (AndXCommand != 0xFF) {
5113
5114       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
5115
5116     }
5117
5118   }
5119
5120 }
5121
5122 void
5123 dissect_write_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5124
5125 {
5126   proto_tree    *WriteMode_tree;
5127   proto_item    *ti;
5128   guint8        WordCount;
5129   guint8        Pad;
5130   guint32       Timeout;
5131   guint32       Reserved2;
5132   guint32       Offset;
5133   guint16       WriteMode;
5134   guint16       Reserved1;
5135   guint16       Remaining;
5136   guint16       FID;
5137   guint16       DataOffset;
5138   guint16       DataLength;
5139   guint16       Count;
5140   guint16       ByteCount;
5141
5142   if (si.request) {
5143     /* Request(s) dissect code */
5144
5145     WordCount = GBYTE(pd, offset);
5146
5147     switch (WordCount) {
5148
5149     case 12:
5150
5151       /* Build display for: Word Count (WCT) */
5152
5153       WordCount = GBYTE(pd, offset);
5154
5155       if (tree) {
5156
5157         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5158
5159       }
5160
5161       offset += 1; /* Skip Word Count (WCT) */
5162
5163       /* Build display for: FID */
5164
5165       FID = GSHORT(pd, offset);
5166
5167       if (tree) {
5168
5169         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5170
5171       }
5172
5173       offset += 2; /* Skip FID */
5174
5175       /* Build display for: Count */
5176
5177       Count = GSHORT(pd, offset);
5178
5179       if (tree) {
5180
5181         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
5182
5183       }
5184
5185       offset += 2; /* Skip Count */
5186
5187       /* Build display for: Reserved 1 */
5188
5189       Reserved1 = GSHORT(pd, offset);
5190
5191       if (tree) {
5192
5193         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
5194
5195       }
5196
5197       offset += 2; /* Skip Reserved 1 */
5198
5199       /* Build display for: Offset */
5200
5201       Offset = GWORD(pd, offset);
5202
5203       if (tree) {
5204
5205         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5206
5207       }
5208
5209       offset += 4; /* Skip Offset */
5210
5211       /* Build display for: Timeout */
5212
5213       Timeout = GWORD(pd, offset);
5214
5215       if (tree) {
5216
5217         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5218
5219       }
5220
5221       offset += 4; /* Skip Timeout */
5222
5223       /* Build display for: WriteMode */
5224
5225       WriteMode = GSHORT(pd, offset);
5226
5227       if (tree) {
5228
5229         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
5230         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
5231         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
5232                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
5233         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
5234                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
5235       
5236       }
5237
5238       offset += 2; /* Skip WriteMode */
5239
5240       /* Build display for: Reserved 2 */
5241
5242       Reserved2 = GWORD(pd, offset);
5243
5244       if (tree) {
5245
5246         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
5247
5248       }
5249
5250       offset += 4; /* Skip Reserved 2 */
5251
5252       /* Build display for: Data Length */
5253
5254       DataLength = GSHORT(pd, offset);
5255
5256       if (tree) {
5257
5258         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
5259
5260       }
5261
5262       offset += 2; /* Skip Data Length */
5263
5264       /* Build display for: Data Offset */
5265
5266       DataOffset = GSHORT(pd, offset);
5267
5268       if (tree) {
5269
5270         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
5271
5272       }
5273
5274       offset += 2; /* Skip Data Offset */
5275
5276       /* Build display for: Byte Count (BCC) */
5277
5278       ByteCount = GSHORT(pd, offset);
5279
5280       if (tree) {
5281
5282         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5283
5284       }
5285
5286       offset += 2; /* Skip Byte Count (BCC) */
5287
5288       /* Build display for: Pad */
5289
5290       Pad = GBYTE(pd, offset);
5291
5292       if (tree) {
5293
5294         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
5295
5296       }
5297
5298       offset += 1; /* Skip Pad */
5299
5300     break;
5301
5302     case 14:
5303
5304       /* Build display for: Word Count (WCT) */
5305
5306       WordCount = GBYTE(pd, offset);
5307
5308       if (tree) {
5309
5310         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5311
5312       }
5313
5314       offset += 1; /* Skip Word Count (WCT) */
5315
5316       /* Build display for: FID */
5317
5318       FID = GSHORT(pd, offset);
5319
5320       if (tree) {
5321
5322         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5323
5324       }
5325
5326       offset += 2; /* Skip FID */
5327
5328       /* Build display for: Count */
5329
5330       Count = GSHORT(pd, offset);
5331
5332       if (tree) {
5333
5334         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
5335
5336       }
5337
5338       offset += 2; /* Skip Count */
5339
5340       /* Build display for: Reserved 1 */
5341
5342       Reserved1 = GSHORT(pd, offset);
5343
5344       if (tree) {
5345
5346         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
5347
5348       }
5349
5350       offset += 2; /* Skip Reserved 1 */
5351
5352       /* Build display for: Timeout */
5353
5354       Timeout = GWORD(pd, offset);
5355
5356       if (tree) {
5357
5358         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5359
5360       }
5361
5362       offset += 4; /* Skip Timeout */
5363
5364       /* Build display for: WriteMode */
5365
5366       WriteMode = GSHORT(pd, offset);
5367
5368       if (tree) {
5369
5370         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
5371         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
5372         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
5373                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
5374         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
5375                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
5376       
5377       }
5378
5379       offset += 2; /* Skip WriteMode */
5380
5381       /* Build display for: Reserved 2 */
5382
5383       Reserved2 = GWORD(pd, offset);
5384
5385       if (tree) {
5386
5387         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
5388
5389       }
5390
5391       offset += 4; /* Skip Reserved 2 */
5392
5393       /* Build display for: Data Length */
5394
5395       DataLength = GSHORT(pd, offset);
5396
5397       if (tree) {
5398
5399         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
5400
5401       }
5402
5403       offset += 2; /* Skip Data Length */
5404
5405       /* Build display for: Data Offset */
5406
5407       DataOffset = GSHORT(pd, offset);
5408
5409       if (tree) {
5410
5411         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
5412
5413       }
5414
5415       offset += 2; /* Skip Data Offset */
5416
5417       /* Build display for: Byte Count (BCC) */
5418
5419       ByteCount = GSHORT(pd, offset);
5420
5421       if (tree) {
5422
5423         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5424
5425       }
5426
5427       offset += 2; /* Skip Byte Count (BCC) */
5428
5429       /* Build display for: Pad */
5430
5431       Pad = GBYTE(pd, offset);
5432
5433       if (tree) {
5434
5435         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
5436
5437       }
5438
5439       offset += 1; /* Skip Pad */
5440
5441     break;
5442
5443     }
5444
5445   } else {
5446     /* Response(s) dissect code */
5447
5448     /* Build display for: Word Count (WCT) */
5449
5450     WordCount = GBYTE(pd, offset);
5451
5452     if (tree) {
5453
5454       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5455
5456     }
5457
5458     offset += 1; /* Skip Word Count (WCT) */
5459
5460     if (WordCount != 0) {
5461
5462       /* Build display for: Remaining */
5463
5464       Remaining = GSHORT(pd, offset);
5465
5466       if (tree) {
5467
5468         proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
5469
5470       }
5471
5472       offset += 2; /* Skip Remaining */
5473
5474     }
5475
5476     /* Build display for: Byte Count */
5477
5478     ByteCount = GSHORT(pd, offset);
5479
5480     if (tree) {
5481
5482       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
5483
5484     }
5485
5486     offset += 2; /* Skip Byte Count */
5487
5488   }
5489
5490 }
5491
5492 void
5493 dissect_tdis_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5494
5495 {
5496   guint8        WordCount;
5497   guint16       ByteCount;
5498
5499   if (si.request) {
5500     /* Request(s) dissect code */
5501
5502     /* Build display for: Word Count (WCT) */
5503
5504     WordCount = GBYTE(pd, offset);
5505
5506     if (tree) {
5507
5508       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5509
5510     }
5511
5512     offset += 1; /* Skip Word Count (WCT) */
5513
5514     /* Build display for: Byte Count (BCC) */
5515
5516     ByteCount = GSHORT(pd, offset);
5517
5518     if (tree) {
5519
5520       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5521
5522     }
5523
5524     offset += 2; /* Skip Byte Count (BCC) */
5525
5526   } else {
5527     /* Response(s) dissect code */
5528
5529     /* Build display for: Word Count (WCT) */
5530
5531     WordCount = GBYTE(pd, offset);
5532
5533     if (tree) {
5534
5535       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5536
5537     }
5538
5539     offset += 1; /* Skip Word Count (WCT) */
5540
5541     /* Build display for: Byte Count (BCC) */
5542
5543     ByteCount = GSHORT(pd, offset);
5544
5545     if (tree) {
5546
5547       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5548
5549     }
5550
5551     offset += 2; /* Skip Byte Count (BCC) */
5552
5553   }
5554
5555 }
5556
5557 void
5558 dissect_move_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5559
5560 {
5561   static const value_string Flags_0x03[] = {
5562         { 0, "Target must be a file"},
5563         { 1, "Target must be a directory"},
5564         { 2, "Reserved"},
5565         { 3, "Reserved"},
5566         { 4, "Verify all writes"},
5567         { 0, NULL}
5568   };
5569   proto_tree    *Flags_tree;
5570   proto_item    *ti;
5571   guint8        WordCount;
5572   guint8        ErrorFileFormat;
5573   guint16       TID2;
5574   guint16       OpenFunction;
5575   guint16       Flags;
5576   guint16       Count;
5577   guint16       ByteCount;
5578   const char    *ErrorFileName;
5579   int           string_len;
5580
5581   if (si.request) {
5582     /* Request(s) dissect code */
5583
5584     /* Build display for: Word Count (WCT) */
5585
5586     WordCount = GBYTE(pd, offset);
5587
5588     if (tree) {
5589
5590       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5591
5592     }
5593
5594     offset += 1; /* Skip Word Count (WCT) */
5595
5596     /* Build display for: TID2 */
5597
5598     TID2 = GSHORT(pd, offset);
5599
5600     if (tree) {
5601
5602       proto_tree_add_text(tree, NullTVB, offset, 2, "TID2: %u", TID2);
5603
5604     }
5605
5606     offset += 2; /* Skip TID2 */
5607
5608     /* Build display for: Open Function */
5609
5610     OpenFunction = GSHORT(pd, offset);
5611
5612     if (tree) {
5613
5614       proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: %u", OpenFunction);
5615
5616     }
5617
5618     offset += 2; /* Skip Open Function */
5619
5620     /* Build display for: Flags */
5621
5622     Flags = GSHORT(pd, offset);
5623
5624     if (tree) {
5625
5626       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
5627       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
5628       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
5629                           decode_enumerated_bitfield(Flags, 0x03, 16, Flags_0x03, "%s"));
5630     
5631     }
5632
5633     offset += 2; /* Skip Flags */
5634
5635   } else {
5636     /* Response(s) dissect code */
5637
5638     /* Build display for: Word Count (WCT) */
5639
5640     WordCount = GBYTE(pd, offset);
5641
5642     if (tree) {
5643
5644       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5645
5646     }
5647
5648     offset += 1; /* Skip Word Count (WCT) */
5649
5650     if (WordCount != 0) {
5651
5652       /* Build display for: Count */
5653
5654       Count = GSHORT(pd, offset);
5655
5656       if (tree) {
5657
5658         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
5659
5660       }
5661
5662       offset += 2; /* Skip Count */
5663
5664     }
5665
5666     /* Build display for: Byte Count */
5667
5668     ByteCount = GSHORT(pd, offset);
5669
5670     if (tree) {
5671
5672       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
5673
5674     }
5675
5676     offset += 2; /* Skip Byte Count */
5677
5678     /* Build display for: Error File Format */
5679
5680     ErrorFileFormat = GBYTE(pd, offset);
5681
5682     if (tree) {
5683
5684       proto_tree_add_text(tree, NullTVB, offset, 1, "Error File Format: %s (%u)",
5685                           val_to_str(ErrorFileFormat, buffer_format_vals, "Unknown"),
5686                           ErrorFileFormat);
5687
5688     }
5689
5690     offset += 1; /* Skip Error File Format */
5691
5692     /* Build display for: Error File Name */
5693
5694     ErrorFileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
5695
5696     if (tree) {
5697
5698       proto_tree_add_text(tree, NullTVB, offset, string_len, "Error File Name: %s", ErrorFileName);
5699
5700     }
5701
5702     offset += string_len; /* Skip Error File Name */
5703
5704   }
5705
5706 }
5707
5708 void
5709 dissect_rename_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5710
5711 {
5712   guint8        WordCount;
5713   guint8        BufferFormat2;
5714   guint8        BufferFormat1;
5715   guint16       SearchAttributes;
5716   guint16       ByteCount;
5717   const char    *OldFileName;
5718   const char    *NewFileName;
5719   int           string_len;
5720
5721   if (si.request) {
5722     /* Request(s) dissect code */
5723
5724     /* Build display for: Word Count (WCT) */
5725
5726     WordCount = GBYTE(pd, offset);
5727
5728     if (tree) {
5729
5730       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5731
5732     }
5733
5734     offset += 1; /* Skip Word Count (WCT) */
5735
5736     /* Build display for: Search Attributes */
5737
5738     SearchAttributes = GSHORT(pd, offset);
5739
5740     if (tree) {
5741
5742       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
5743
5744     }
5745
5746     offset += 2; /* Skip Search Attributes */
5747
5748     /* Build display for: Byte Count */
5749
5750     ByteCount = GSHORT(pd, offset);
5751
5752     if (tree) {
5753
5754       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
5755
5756     }
5757
5758     offset += 2; /* Skip Byte Count */
5759
5760     /* Build display for: Buffer Format 1 */
5761
5762     BufferFormat1 = GBYTE(pd, offset);
5763
5764     if (tree) {
5765
5766       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
5767                           val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
5768                           BufferFormat1);
5769
5770     }
5771
5772     offset += 1; /* Skip Buffer Format 1 */
5773
5774     /* Build display for: Old File Name */
5775
5776     OldFileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
5777
5778     if (tree) {
5779
5780       proto_tree_add_text(tree, NullTVB, offset, string_len, "Old File Name: %s", OldFileName);
5781
5782     }
5783
5784     offset += string_len; /* Skip Old File Name */
5785
5786     /* Build display for: Buffer Format 2 */
5787
5788     BufferFormat2 = GBYTE(pd, offset);
5789
5790     if (tree) {
5791
5792       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
5793                           val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
5794                           BufferFormat2);
5795
5796     }
5797
5798     offset += 1; /* Skip Buffer Format 2 */
5799
5800     /* Build display for: New File Name */
5801
5802     NewFileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
5803
5804     if (tree) {
5805
5806       proto_tree_add_text(tree, NullTVB, offset, string_len, "New File Name: %s", NewFileName);
5807
5808     }
5809
5810     offset += string_len; /* Skip New File Name */
5811
5812   } else {
5813     /* Response(s) dissect code */
5814
5815     /* Build display for: Word Count (WCT) */
5816
5817     WordCount = GBYTE(pd, offset);
5818
5819     if (tree) {
5820
5821       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5822
5823     }
5824
5825     offset += 1; /* Skip Word Count (WCT) */
5826
5827     /* Build display for: Byte Count (BCC) */
5828
5829     ByteCount = GSHORT(pd, offset);
5830
5831     if (tree) {
5832
5833       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5834
5835     }
5836
5837     offset += 2; /* Skip Byte Count (BCC) */
5838
5839   }
5840
5841 }
5842
5843 void
5844 dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5845
5846 {
5847   static const value_string Mode_0x03[] = {
5848         { 0, "Text mode (DOS expands TABs)"},
5849         { 1, "Graphics mode"},
5850         { 0, NULL}
5851   };
5852   proto_tree    *Mode_tree;
5853   proto_item    *ti;
5854   guint8        WordCount;
5855   guint8        BufferFormat;
5856   guint16       SetupLength;
5857   guint16       Mode;
5858   guint16       FID;
5859   guint16       ByteCount;
5860   const char    *IdentifierString;
5861   int           string_len;
5862
5863   if (si.request) {
5864     /* Request(s) dissect code */
5865
5866     /* Build display for: Word Count (WCT) */
5867
5868     WordCount = GBYTE(pd, offset);
5869
5870     if (tree) {
5871
5872       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5873
5874     }
5875
5876     offset += 1; /* Skip Word Count (WCT) */
5877
5878     /* Build display for: Setup Length */
5879
5880     SetupLength = GSHORT(pd, offset);
5881
5882     if (tree) {
5883
5884       proto_tree_add_text(tree, NullTVB, offset, 2, "Setup Length: %u", SetupLength);
5885
5886     }
5887
5888     offset += 2; /* Skip Setup Length */
5889
5890     /* Build display for: Mode */
5891
5892     Mode = GSHORT(pd, offset);
5893
5894     if (tree) {
5895
5896       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
5897       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
5898       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
5899                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
5900     
5901     }
5902
5903     offset += 2; /* Skip Mode */
5904
5905     /* Build display for: Byte Count (BCC) */
5906
5907     ByteCount = GSHORT(pd, offset);
5908
5909     if (tree) {
5910
5911       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5912
5913     }
5914
5915     offset += 2; /* Skip Byte Count (BCC) */
5916
5917     /* Build display for: Buffer Format */
5918
5919     BufferFormat = GBYTE(pd, offset);
5920
5921     if (tree) {
5922
5923       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
5924                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
5925                           BufferFormat);
5926
5927     }
5928
5929     offset += 1; /* Skip Buffer Format */
5930
5931     /* Build display for: Identifier String */
5932
5933     IdentifierString = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
5934
5935     if (tree) {
5936
5937       proto_tree_add_text(tree, NullTVB, offset, string_len, "Identifier String: %s", IdentifierString);
5938
5939     }
5940
5941     offset += string_len; /* Skip Identifier String */
5942
5943   } else {
5944     /* Response(s) dissect code */
5945
5946     /* Build display for: Word Count (WCT) */
5947
5948     WordCount = GBYTE(pd, offset);
5949
5950     if (tree) {
5951
5952       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5953
5954     }
5955
5956     offset += 1; /* Skip Word Count (WCT) */
5957
5958     /* Build display for: FID */
5959
5960     FID = GSHORT(pd, offset);
5961
5962     if (tree) {
5963
5964       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5965
5966     }
5967
5968     offset += 2; /* Skip FID */
5969
5970     /* Build display for: Byte Count (BCC) */
5971
5972     ByteCount = GSHORT(pd, offset);
5973
5974     if (tree) {
5975
5976       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5977
5978     }
5979
5980     offset += 2; /* Skip Byte Count (BCC) */
5981
5982   }
5983
5984 }
5985
5986 void
5987 dissect_close_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
5988
5989 {
5990   guint8        WordCount;
5991   guint16       FID;
5992   guint16       ByteCount;
5993
5994   if (si.request) {
5995     /* Request(s) dissect code */
5996
5997     /* Build display for: Word Count (WCT) */
5998
5999     WordCount = GBYTE(pd, offset);
6000
6001     if (tree) {
6002
6003       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6004
6005     }
6006
6007     offset += 1; /* Skip Word Count (WCT) */
6008
6009     /* Build display for: FID */
6010
6011     FID = GSHORT(pd, offset);
6012
6013     if (tree) {
6014
6015       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6016
6017     }
6018
6019     offset += 2; /* Skip FID */
6020
6021     /* Build display for: Byte Count (BCC) */
6022
6023     ByteCount = GSHORT(pd, offset);
6024
6025     if (tree) {
6026
6027       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6028
6029     }
6030
6031     offset += 2; /* Skip Byte Count (BCC) */
6032
6033   } else {
6034     /* Response(s) dissect code */
6035
6036     /* Build display for: Word Count */
6037
6038     WordCount = GBYTE(pd, offset);
6039
6040     if (tree) {
6041
6042       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
6043
6044     }
6045
6046     offset += 1; /* Skip Word Count */
6047
6048     /* Build display for: Byte Count (BCC) */
6049
6050     ByteCount = GSHORT(pd, offset);
6051
6052     if (tree) {
6053
6054       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6055
6056     }
6057
6058     offset += 2; /* Skip Byte Count (BCC) */
6059
6060   }
6061
6062 }
6063
6064 void
6065 dissect_read_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
6066
6067 {
6068   guint8        WordCount;
6069   guint32       Timeout;
6070   guint32       OffsetHigh;
6071   guint32       Offset;
6072   guint16       Reserved;
6073   guint16       MinCount;
6074   guint16       MaxCount;
6075   guint16       FID;
6076   guint16       ByteCount;
6077
6078   if (si.request) {
6079     /* Request(s) dissect code */
6080
6081     WordCount = GBYTE(pd, offset);
6082
6083     switch (WordCount) {
6084
6085     case 8:
6086
6087       /* Build display for: Word Count (WCT) */
6088
6089       WordCount = GBYTE(pd, offset);
6090
6091       if (tree) {
6092
6093         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6094
6095       }
6096
6097       offset += 1; /* Skip Word Count (WCT) */
6098
6099       /* Build display for: FID */
6100
6101       FID = GSHORT(pd, offset);
6102
6103       if (tree) {
6104
6105         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6106
6107       }
6108
6109       offset += 2; /* Skip FID */
6110
6111       /* Build display for: Offset */
6112
6113       Offset = GWORD(pd, offset);
6114
6115       if (tree) {
6116
6117         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6118
6119       }
6120
6121       offset += 4; /* Skip Offset */
6122
6123       /* Build display for: Max Count */
6124
6125       MaxCount = GSHORT(pd, offset);
6126
6127       if (tree) {
6128
6129         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6130
6131       }
6132
6133       offset += 2; /* Skip Max Count */
6134
6135       /* Build display for: Min Count */
6136
6137       MinCount = GSHORT(pd, offset);
6138
6139       if (tree) {
6140
6141         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
6142
6143       }
6144
6145       offset += 2; /* Skip Min Count */
6146
6147       /* Build display for: Timeout */
6148
6149       Timeout = GWORD(pd, offset);
6150
6151       if (tree) {
6152
6153         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
6154
6155       }
6156
6157       offset += 4; /* Skip Timeout */
6158
6159       /* Build display for: Reserved */
6160
6161       Reserved = GSHORT(pd, offset);
6162
6163       if (tree) {
6164
6165         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
6166
6167       }
6168
6169       offset += 2; /* Skip Reserved */
6170
6171       /* Build display for: Byte Count (BCC) */
6172
6173       ByteCount = GSHORT(pd, offset);
6174
6175       if (tree) {
6176
6177         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6178
6179       }
6180
6181       offset += 2; /* Skip Byte Count (BCC) */
6182
6183     break;
6184
6185     case 10:
6186
6187       /* Build display for: Word Count (WCT) */
6188
6189       WordCount = GBYTE(pd, offset);
6190
6191       if (tree) {
6192
6193         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6194
6195       }
6196
6197       offset += 1; /* Skip Word Count (WCT) */
6198
6199       /* Build display for: FID */
6200
6201       FID = GSHORT(pd, offset);
6202
6203       if (tree) {
6204
6205         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6206
6207       }
6208
6209       offset += 2; /* Skip FID */
6210
6211       /* Build display for: Offset */
6212
6213       Offset = GWORD(pd, offset);
6214
6215       if (tree) {
6216
6217         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6218
6219       }
6220
6221       offset += 4; /* Skip Offset */
6222
6223       /* Build display for: Max Count */
6224
6225       MaxCount = GSHORT(pd, offset);
6226
6227       if (tree) {
6228
6229         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6230
6231       }
6232
6233       offset += 2; /* Skip Max Count */
6234
6235       /* Build display for: Min Count */
6236
6237       MinCount = GSHORT(pd, offset);
6238
6239       if (tree) {
6240
6241         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
6242
6243       }
6244
6245       offset += 2; /* Skip Min Count */
6246
6247       /* Build display for: Timeout */
6248
6249       Timeout = GWORD(pd, offset);
6250
6251       if (tree) {
6252
6253         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
6254
6255       }
6256
6257       offset += 4; /* Skip Timeout */
6258
6259       /* Build display for: Reserved */
6260
6261       Reserved = GSHORT(pd, offset);
6262
6263       if (tree) {
6264
6265         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
6266
6267       }
6268
6269       offset += 2; /* Skip Reserved */
6270
6271       /* Build display for: Offset High */
6272
6273       OffsetHigh = GWORD(pd, offset);
6274
6275       if (tree) {
6276
6277         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
6278
6279       }
6280
6281       offset += 4; /* Skip Offset High */
6282
6283       /* Build display for: Byte Count (BCC) */
6284
6285       ByteCount = GSHORT(pd, offset);
6286
6287       if (tree) {
6288
6289         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6290
6291       }
6292
6293       offset += 2; /* Skip Byte Count (BCC) */
6294
6295     break;
6296
6297     }
6298
6299   } else {
6300     /* Response(s) dissect code */
6301
6302   }
6303
6304 }
6305
6306 void
6307 dissect_read_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
6308
6309 {
6310   guint8        WordCount;
6311   guint8        AndXReserved;
6312   guint8        AndXCommand = 0xFF;
6313   guint16       ByteCount;
6314   guint16       AndXOffset = 0;
6315   guint16       FID;
6316   guint16       DataCompactionMode;
6317   guint16       DataLength;
6318   guint16       DataOffset;
6319   guint16       Remaining;
6320   guint16       MaxCount;
6321   guint16       MinCount;
6322   guint16       Reserved;
6323   guint32       Offset;
6324   guint32       OffsetHigh;
6325   int           i;
6326
6327   if (si.request) {
6328     /* Request(s) dissect code */
6329
6330     /* Build display for: Word Count (WCT) */
6331
6332     WordCount = GBYTE(pd, offset);
6333
6334     if (tree) {
6335
6336       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6337
6338     }
6339
6340     offset += 1; /* Skip Word Count (WCT) */
6341
6342     /* Build display for: AndXCommand */
6343
6344     AndXCommand = GBYTE(pd, offset);
6345
6346     if (tree) {
6347
6348       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6349
6350     }
6351
6352     offset += 1; /* Skip AndXCommand */
6353
6354     /* Build display for: AndXReserved */
6355
6356     AndXReserved = GBYTE(pd, offset);
6357
6358     if (tree) {
6359
6360       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6361
6362     }
6363
6364     offset += 1; /* Skip AndXReserved */
6365
6366     /* Build display for: AndXOffset */
6367
6368     AndXOffset = GSHORT(pd, offset);
6369
6370     if (tree) {
6371
6372       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6373
6374     }
6375
6376     offset += 2; /* Skip AndXOffset */
6377
6378     /* Build display for: FID */
6379
6380     FID = GSHORT(pd, offset);
6381
6382     if (tree) {
6383         
6384       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6385         
6386     }
6387
6388     offset += 2; /* Skip FID */
6389
6390     /* Build display for: Offset */
6391
6392     Offset = GWORD(pd, offset);
6393
6394     if (tree) {
6395
6396       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6397
6398     }
6399
6400     offset += 4; /* Skip Offset */
6401
6402     /* Build display for: Max Count */
6403
6404     MaxCount = GSHORT(pd, offset);
6405
6406     if (tree) {
6407
6408         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6409
6410     }
6411
6412     offset += 2; /* Skip Max Count */
6413
6414     /* Build display for: Min Count */
6415
6416     MinCount = GSHORT(pd, offset);
6417
6418     if (tree) {
6419
6420         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
6421
6422     }
6423
6424     offset += 2; /* Skip Min Count */
6425
6426     /* Build display for: Reserved */
6427
6428     Reserved = GWORD(pd, offset);
6429
6430     if (tree) {
6431
6432       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
6433
6434     }
6435
6436     offset += 4; /* Skip Reserved */
6437
6438     /* Build display for: Remaining */
6439
6440     Remaining = GSHORT(pd, offset);
6441
6442     if (tree) {
6443
6444       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
6445
6446     }
6447
6448     offset += 2; /* Skip Remaining */
6449
6450     if (WordCount == 12) {
6451
6452         /* Build display for: Offset High */
6453
6454         OffsetHigh = GWORD(pd, offset);
6455
6456         if (tree) {
6457
6458             proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
6459
6460         }
6461
6462         offset += 4; /* Skip Offset High */
6463     }
6464
6465     /* Build display for: Byte Count (BCC) */
6466
6467     ByteCount = GSHORT(pd, offset);
6468
6469     if (tree) {
6470
6471       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6472
6473     }
6474
6475     offset += 2; /* Skip Byte Count (BCC) */
6476
6477
6478     if (AndXCommand != 0xFF) {
6479
6480       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
6481
6482     }
6483
6484   } else {
6485     /* Response(s) dissect code */
6486
6487     /* Build display for: Word Count (WCT) */
6488
6489     WordCount = GBYTE(pd, offset);
6490
6491     if (tree) {
6492
6493       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6494
6495     }
6496
6497     offset += 1; /* Skip Word Count (WCT) */
6498
6499     /* Build display for: AndXCommand */
6500
6501     AndXCommand = GBYTE(pd, offset);
6502
6503     if (tree) {
6504
6505       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6506
6507     }
6508
6509     offset += 1; /* Skip AndXCommand */
6510
6511     /* Build display for: AndXReserved */
6512
6513     AndXReserved = GBYTE(pd, offset);
6514
6515     if (tree) {
6516
6517       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6518
6519     }
6520
6521     offset += 1; /* Skip AndXReserved */
6522
6523     /* Build display for: AndXOffset */
6524
6525     AndXOffset = GSHORT(pd, offset);
6526
6527     if (tree) {
6528
6529       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6530
6531     }
6532
6533     offset += 2; /* Skip AndXOffset */
6534
6535     /* Build display for: Remaining */
6536
6537     Remaining = GSHORT(pd, offset);
6538
6539     if (tree) {
6540
6541       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
6542
6543     }
6544
6545     offset += 2; /* Skip Remaining */
6546
6547     /* Build display for: Data Compaction Mode */
6548
6549     DataCompactionMode = GSHORT(pd, offset);
6550
6551     if (tree) {
6552
6553         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
6554
6555     }
6556
6557     offset += 2; /* Skip Data Compaction Mode */
6558
6559     /* Build display for: Reserved */
6560
6561     Reserved = GSHORT(pd, offset);
6562
6563     if (tree) {
6564
6565         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
6566
6567     }
6568
6569     offset += 2; /* Skip Reserved */
6570
6571     /* Build display for: Data Length */
6572
6573     DataLength = GSHORT(pd, offset);
6574
6575     if (tree) {
6576
6577         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
6578
6579     }
6580
6581     offset += 2; /* Skip Data Length */
6582
6583     /* Build display for: Data Offset */
6584
6585     DataOffset = GSHORT(pd, offset);
6586
6587     if (tree) {
6588
6589         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
6590
6591     }
6592
6593     offset += 2; /* Skip Data Offset */
6594
6595     /* Build display for: Reserved[5] */
6596  
6597     for(i = 1; i <= 5; ++i) {
6598
6599         Reserved = GSHORT(pd, offset);
6600
6601         if (tree) {
6602
6603             proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);
6604
6605         }
6606         offset += 2;
6607     }
6608
6609     /* Build display for: Byte Count (BCC) */
6610
6611     ByteCount = GSHORT(pd, offset);
6612
6613     if (tree) {
6614
6615       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6616
6617     }
6618
6619     offset += 2; /* Skip Byte Count (BCC) */
6620
6621     /* Build display for data */
6622
6623     if (tree) {
6624
6625         offset = SMB_offset + DataOffset;
6626         if(END_OF_FRAME >= DataLength)
6627             proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
6628         else
6629             proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
6630
6631     }
6632
6633     if (AndXCommand != 0xFF) {
6634
6635       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
6636
6637     }
6638
6639   }
6640
6641 }
6642
6643 void
6644 dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
6645
6646 {
6647   guint8        WordCount;
6648   guint8        AndXReserved;
6649   guint8        AndXCommand = 0xFF;
6650   guint16       ByteCount;
6651   guint16       AndXOffset = 0;
6652
6653   if (si.request) {
6654     /* Request(s) dissect code */
6655
6656     /* Build display for: Word Count (WCT) */
6657
6658     WordCount = GBYTE(pd, offset);
6659
6660     if (tree) {
6661
6662       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6663
6664     }
6665
6666     offset += 1; /* Skip Word Count (WCT) */
6667
6668     /* Build display for: AndXCommand */
6669
6670     AndXCommand = GBYTE(pd, offset);
6671
6672     if (tree) {
6673
6674       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6675
6676     }
6677
6678     offset += 1; /* Skip AndXCommand */
6679
6680     /* Build display for: AndXReserved */
6681
6682     AndXReserved = GBYTE(pd, offset);
6683
6684     if (tree) {
6685
6686       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6687
6688     }
6689
6690     offset += 1; /* Skip AndXReserved */
6691
6692     /* Build display for: AndXOffset */
6693
6694     AndXOffset = GSHORT(pd, offset);
6695
6696     if (tree) {
6697
6698       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6699
6700     }
6701
6702     offset += 2; /* Skip AndXOffset */
6703
6704     /* Build display for: Byte Count (BCC) */
6705
6706     ByteCount = GSHORT(pd, offset);
6707
6708     if (tree) {
6709
6710       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6711
6712     }
6713
6714     offset += 2; /* Skip Byte Count (BCC) */
6715
6716
6717     if (AndXCommand != 0xFF) {
6718
6719       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
6720
6721     }
6722
6723   } else {
6724     /* Response(s) dissect code */
6725
6726     /* Build display for: Word Count (WCT) */
6727
6728     WordCount = GBYTE(pd, offset);
6729
6730     if (tree) {
6731
6732       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6733
6734     }
6735
6736     offset += 1; /* Skip Word Count (WCT) */
6737
6738     /* Build display for: AndXCommand */
6739
6740     AndXCommand = GBYTE(pd, offset);
6741
6742     if (tree) {
6743
6744       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6745
6746     }
6747
6748     offset += 1; /* Skip AndXCommand */
6749
6750     /* Build display for: AndXReserved */
6751
6752     AndXReserved = GBYTE(pd, offset);
6753
6754     if (tree) {
6755
6756       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6757
6758     }
6759
6760     offset += 1; /* Skip AndXReserved */
6761
6762     /* Build display for: AndXOffset */
6763
6764     AndXOffset = GSHORT(pd, offset);
6765
6766     if (tree) {
6767
6768       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6769
6770     }
6771
6772     offset += 2; /* Skip AndXOffset */
6773
6774     /* Build display for: Byte Count (BCC) */
6775
6776     ByteCount = GSHORT(pd, offset);
6777
6778     if (tree) {
6779
6780       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6781
6782     }
6783
6784     offset += 2; /* Skip Byte Count (BCC) */
6785
6786
6787     if (AndXCommand != 0xFF) {
6788
6789       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
6790
6791     }
6792
6793   }
6794
6795 }
6796
6797 void
6798 dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
6799
6800 {
6801   static const value_string Mode_0x03[] = {
6802         { 0, "Seek from start of file"},
6803         { 1, "Seek from current position"},
6804         { 2, "Seek from end of file"},
6805         { 0, NULL}
6806   };
6807   proto_tree    *Mode_tree;
6808   proto_item    *ti;
6809   guint8        WordCount;
6810   guint32       Offset;
6811   guint16       Mode;
6812   guint16       FID;
6813   guint16       ByteCount;
6814
6815   if (si.request) {
6816     /* Request(s) dissect code */
6817
6818     /* Build display for: Word Count (WCT) */
6819
6820     WordCount = GBYTE(pd, offset);
6821
6822     if (tree) {
6823
6824       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6825
6826     }
6827
6828     offset += 1; /* Skip Word Count (WCT) */
6829
6830     /* Build display for: FID */
6831
6832     FID = GSHORT(pd, offset);
6833
6834     if (tree) {
6835
6836       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6837
6838     }
6839
6840     offset += 2; /* Skip FID */
6841
6842     /* Build display for: Mode */
6843
6844     Mode = GSHORT(pd, offset);
6845
6846     if (tree) {
6847
6848       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
6849       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
6850       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
6851                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
6852     
6853     }
6854
6855     offset += 2; /* Skip Mode */
6856
6857     /* Build display for: Offset */
6858
6859     Offset = GWORD(pd, offset);
6860
6861     if (tree) {
6862
6863       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6864
6865     }
6866
6867     offset += 4; /* Skip Offset */
6868
6869     /* Build display for: Byte Count (BCC) */
6870
6871     ByteCount = GSHORT(pd, offset);
6872
6873     if (tree) {
6874
6875       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6876
6877     }
6878
6879     offset += 2; /* Skip Byte Count (BCC) */
6880
6881   } else {
6882     /* Response(s) dissect code */
6883
6884     /* Build display for: Word Count (WCT) */
6885
6886     WordCount = GBYTE(pd, offset);
6887
6888     if (tree) {
6889
6890       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6891
6892     }
6893
6894     offset += 1; /* Skip Word Count (WCT) */
6895
6896     /* Build display for: Offset */
6897
6898     Offset = GWORD(pd, offset);
6899
6900     if (tree) {
6901
6902       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6903
6904     }
6905
6906     offset += 4; /* Skip Offset */
6907
6908     /* Build display for: Byte Count (BCC) */
6909
6910     ByteCount = GSHORT(pd, offset);
6911
6912     if (tree) {
6913
6914       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6915
6916     }
6917
6918     offset += 2; /* Skip Byte Count (BCC) */
6919
6920   }
6921
6922 }
6923
6924 void
6925 dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
6926
6927 {
6928   guint8        WordCount;
6929   guint8        BufferFormat;
6930   guint32       Offset;
6931   guint16       Remaining;
6932   guint16       FID;
6933   guint16       DataLength;
6934   guint16       Count;
6935   guint16       ByteCount;
6936
6937   if (si.request) {
6938     /* Request(s) dissect code */
6939
6940     /* Build display for: Word Count (WCT) */
6941
6942     WordCount = GBYTE(pd, offset);
6943
6944     if (tree) {
6945
6946       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6947
6948     }
6949
6950     offset += 1; /* Skip Word Count (WCT) */
6951
6952     /* Build display for: FID */
6953
6954     FID = GSHORT(pd, offset);
6955
6956     if (tree) {
6957
6958       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6959
6960     }
6961
6962     offset += 2; /* Skip FID */
6963
6964     /* Build display for: Count */
6965
6966     Count = GSHORT(pd, offset);
6967
6968     if (tree) {
6969
6970       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6971
6972     }
6973
6974     offset += 2; /* Skip Count */
6975
6976     /* Build display for: Offset */
6977
6978     Offset = GWORD(pd, offset);
6979
6980     if (tree) {
6981
6982       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6983
6984     }
6985
6986     offset += 4; /* Skip Offset */
6987
6988     /* Build display for: Remaining */
6989
6990     Remaining = GSHORT(pd, offset);
6991
6992     if (tree) {
6993
6994       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
6995
6996     }
6997
6998     offset += 2; /* Skip Remaining */
6999
7000     /* Build display for: Byte Count (BCC) */
7001
7002     ByteCount = GSHORT(pd, offset);
7003
7004     if (tree) {
7005
7006       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7007
7008     }
7009
7010     offset += 2; /* Skip Byte Count (BCC) */
7011
7012     /* Build display for: Buffer Format */
7013
7014     BufferFormat = GBYTE(pd, offset);
7015
7016     if (tree) {
7017
7018       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
7019                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
7020                           BufferFormat);
7021
7022     }
7023
7024     offset += 1; /* Skip Buffer Format */
7025
7026     /* Build display for: Data Length */
7027
7028     DataLength = GSHORT(pd, offset);
7029
7030     if (tree) {
7031
7032       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7033
7034     }
7035
7036     offset += 2; /* Skip Data Length */
7037
7038   } else {
7039     /* Response(s) dissect code */
7040
7041     /* Build display for: Word Count (WCT) */
7042
7043     WordCount = GBYTE(pd, offset);
7044
7045     if (tree) {
7046
7047       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7048
7049     }
7050
7051     offset += 1; /* Skip Word Count (WCT) */
7052
7053     /* Build display for: Count */
7054
7055     Count = GSHORT(pd, offset);
7056
7057     if (tree) {
7058
7059       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7060
7061     }
7062
7063     offset += 2; /* Skip Count */
7064
7065     /* Build display for: Byte Count (BCC) */
7066
7067     ByteCount = GSHORT(pd, offset);
7068
7069     if (tree) {
7070
7071       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7072
7073     }
7074
7075     offset += 2; /* Skip Byte Count (BCC) */
7076
7077   }
7078
7079 }
7080
7081 void
7082 dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7083
7084 {
7085   guint8        WordCount;
7086   guint16       LastWriteTime;
7087   guint16       LastWriteDate;
7088   guint16       LastAccessTime;
7089   guint16       LastAccessDate;
7090   guint16       FID;
7091   guint16       CreationTime;
7092   guint16       CreationDate;
7093   guint16       ByteCount;
7094
7095   if (si.request) {
7096     /* Request(s) dissect code */
7097
7098     /* Build display for: Word Count */
7099
7100     WordCount = GBYTE(pd, offset);
7101
7102     if (tree) {
7103
7104       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
7105
7106     }
7107
7108     offset += 1; /* Skip Word Count */
7109
7110     /* Build display for: FID */
7111
7112     FID = GSHORT(pd, offset);
7113
7114     if (tree) {
7115
7116       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7117
7118     }
7119
7120     offset += 2; /* Skip FID */
7121
7122     /* Build display for: Creation Date */
7123
7124     CreationDate = GSHORT(pd, offset);
7125
7126     if (tree) {
7127
7128       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
7129
7130     }
7131
7132     offset += 2; /* Skip Creation Date */
7133
7134     /* Build display for: Creation Time */
7135
7136     CreationTime = GSHORT(pd, offset);
7137
7138     if (tree) {
7139
7140       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
7141
7142     }
7143
7144     offset += 2; /* Skip Creation Time */
7145
7146     /* Build display for: Last Access Date */
7147
7148     LastAccessDate = GSHORT(pd, offset);
7149
7150     if (tree) {
7151
7152       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
7153
7154     }
7155
7156     offset += 2; /* Skip Last Access Date */
7157
7158     /* Build display for: Last Access Time */
7159
7160     LastAccessTime = GSHORT(pd, offset);
7161
7162     if (tree) {
7163
7164       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
7165
7166     }
7167
7168     offset += 2; /* Skip Last Access Time */
7169
7170     /* Build display for: Last Write Date */
7171
7172     LastWriteDate = GSHORT(pd, offset);
7173
7174     if (tree) {
7175
7176       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
7177
7178     }
7179
7180     offset += 2; /* Skip Last Write Date */
7181
7182     /* Build display for: Last Write Time */
7183
7184     LastWriteTime = GSHORT(pd, offset);
7185
7186     if (tree) {
7187
7188       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
7189
7190     }
7191
7192     offset += 2; /* Skip Last Write Time */
7193
7194     /* Build display for: Byte Count (BCC) */
7195
7196     ByteCount = GSHORT(pd, offset);
7197
7198     if (tree) {
7199
7200       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7201
7202     }
7203
7204     offset += 2; /* Skip Byte Count (BCC) */
7205
7206   } else {
7207     /* Response(s) dissect code */
7208
7209     /* Build display for: Word Count (WCC) */
7210
7211     WordCount = GBYTE(pd, offset);
7212
7213     if (tree) {
7214
7215       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
7216
7217     }
7218
7219     offset += 1; /* Skip Word Count (WCC) */
7220
7221     /* Build display for: Byte Count (BCC) */
7222
7223     ByteCount = GSHORT(pd, offset);
7224
7225     if (tree) {
7226
7227       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7228
7229     }
7230
7231     offset += 2; /* Skip Byte Count (BCC) */
7232
7233   }
7234
7235 }
7236
7237 void
7238 dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7239
7240 {
7241   guint8        WordCount;
7242   guint32       Offset;
7243   guint32       Count;
7244   guint16       FID;
7245   guint16       ByteCount;
7246
7247   if (si.request) {
7248     /* Request(s) dissect code */
7249
7250     /* Build display for: Word Count (WCT) */
7251
7252     WordCount = GBYTE(pd, offset);
7253
7254     if (tree) {
7255
7256       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7257
7258     }
7259
7260     offset += 1; /* Skip Word Count (WCT) */
7261
7262     /* Build display for: FID */
7263
7264     FID = GSHORT(pd, offset);
7265
7266     if (tree) {
7267
7268       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7269
7270     }
7271
7272     offset += 2; /* Skip FID */
7273
7274     /* Build display for: Count */
7275
7276     Count = GWORD(pd, offset);
7277
7278     if (tree) {
7279
7280       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
7281
7282     }
7283
7284     offset += 4; /* Skip Count */
7285
7286     /* Build display for: Offset */
7287
7288     Offset = GWORD(pd, offset);
7289
7290     if (tree) {
7291
7292       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7293
7294     }
7295
7296     offset += 4; /* Skip Offset */
7297
7298     /* Build display for: Byte Count (BCC) */
7299
7300     ByteCount = GSHORT(pd, offset);
7301
7302     if (tree) {
7303
7304       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7305
7306     }
7307
7308     offset += 2; /* Skip Byte Count (BCC) */
7309
7310   } else {
7311     /* Response(s) dissect code */
7312
7313     /* Build display for: Word Count (WCT) */
7314
7315     WordCount = GBYTE(pd, offset);
7316
7317     if (tree) {
7318
7319       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7320
7321     }
7322
7323     offset += 1; /* Skip Word Count (WCT) */
7324
7325     /* Build display for: Byte Count (BCC) */
7326
7327     ByteCount = GSHORT(pd, offset);
7328
7329     if (tree) {
7330
7331       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7332
7333     }
7334
7335     offset += 2; /* Skip Byte Count (BCC) */
7336
7337   }
7338
7339 }
7340
7341 void
7342 dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7343
7344 {
7345   guint8        WordCount;
7346   guint8        BufferFormat;
7347   guint16       StartIndex;
7348   guint16       RestartIndex;
7349   guint16       MaxCount;
7350   guint16       DataLength;
7351   guint16       Count;
7352   guint16       ByteCount;
7353
7354   if (si.request) {
7355     /* Request(s) dissect code */
7356
7357     /* Build display for: Word Count */
7358
7359     WordCount = GBYTE(pd, offset);
7360
7361     if (tree) {
7362
7363       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
7364
7365     }
7366
7367     offset += 1; /* Skip Word Count */
7368
7369     /* Build display for: Max Count */
7370
7371     MaxCount = GSHORT(pd, offset);
7372
7373     if (tree) {
7374
7375       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
7376
7377     }
7378
7379     offset += 2; /* Skip Max Count */
7380
7381     /* Build display for: Start Index */
7382
7383     StartIndex = GSHORT(pd, offset);
7384
7385     if (tree) {
7386
7387       proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);
7388
7389     }
7390
7391     offset += 2; /* Skip Start Index */
7392
7393     /* Build display for: Byte Count (BCC) */
7394
7395     ByteCount = GSHORT(pd, offset);
7396
7397     if (tree) {
7398
7399       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7400
7401     }
7402
7403     offset += 2; /* Skip Byte Count (BCC) */
7404
7405   } else {
7406     /* Response(s) dissect code */
7407
7408     /* Build display for: Word Count (WCT) */
7409
7410     WordCount = GBYTE(pd, offset);
7411
7412     if (tree) {
7413
7414       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7415
7416     }
7417
7418     offset += 1; /* Skip Word Count (WCT) */
7419
7420     if (WordCount != 0) {
7421
7422       /* Build display for: Count */
7423
7424       Count = GSHORT(pd, offset);
7425
7426       if (tree) {
7427
7428         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7429
7430       }
7431
7432       offset += 2; /* Skip Count */
7433
7434       /* Build display for: Restart Index */
7435
7436       RestartIndex = GSHORT(pd, offset);
7437
7438       if (tree) {
7439
7440         proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
7441
7442       }
7443
7444       offset += 2; /* Skip Restart Index */
7445
7446       /* Build display for: Byte Count (BCC) */
7447
7448     }
7449
7450     ByteCount = GSHORT(pd, offset);
7451
7452     if (tree) {
7453
7454       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7455
7456     }
7457
7458     offset += 2; /* Skip Byte Count (BCC) */
7459
7460     /* Build display for: Buffer Format */
7461
7462     BufferFormat = GBYTE(pd, offset);
7463
7464     if (tree) {
7465
7466       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
7467                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
7468                           BufferFormat);
7469
7470     }
7471
7472     offset += 1; /* Skip Buffer Format */
7473
7474     /* Build display for: Data Length */
7475
7476     DataLength = GSHORT(pd, offset);
7477
7478     if (tree) {
7479
7480       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7481
7482     }
7483
7484     offset += 2; /* Skip Data Length */
7485
7486   }
7487
7488 }
7489
7490 void
7491 dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7492
7493 {
7494   proto_tree    *LockType_tree;
7495   proto_item    *ti;
7496   guint8        LockType;
7497   guint8        WordCount;
7498   guint8        OplockLevel;
7499   guint8        AndXReserved;
7500   guint8        AndXCommand = 0xFF;
7501   guint32       Timeout;
7502   guint16       NumberofLocks;
7503   guint16       NumberOfUnlocks;
7504   guint16       FID;
7505   guint16       ByteCount;
7506   guint16       AndXoffset;
7507   guint16       AndXOffset = 0;
7508
7509   if (si.request) {
7510     /* Request(s) dissect code */
7511
7512     /* Build display for: Word Count (WCT) */
7513
7514     WordCount = GBYTE(pd, offset);
7515
7516     if (tree) {
7517
7518       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7519
7520     }
7521
7522     offset += 1; /* Skip Word Count (WCT) */
7523
7524     /* Build display for: AndXCommand */
7525
7526     AndXCommand = GBYTE(pd, offset);
7527
7528     if (tree) {
7529
7530       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
7531                           (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
7532
7533     }
7534
7535     offset += 1; /* Skip AndXCommand */
7536
7537     /* Build display for: AndXReserved */
7538
7539     AndXReserved = GBYTE(pd, offset);
7540
7541     if (tree) {
7542
7543       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
7544
7545     }
7546
7547     offset += 1; /* Skip AndXReserved */
7548
7549     /* Build display for: AndXOffset */
7550
7551     AndXOffset = GSHORT(pd, offset);
7552
7553     if (tree) {
7554
7555       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
7556
7557     }
7558
7559     offset += 2; /* Skip AndXOffset */
7560
7561     /* Build display for: FID */
7562
7563     FID = GSHORT(pd, offset);
7564
7565     if (tree) {
7566
7567       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7568
7569     }
7570
7571     offset += 2; /* Skip FID */
7572
7573     /* Build display for: Lock Type */
7574
7575     LockType = GBYTE(pd, offset);
7576
7577     if (tree) {
7578
7579       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
7580       LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
7581       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
7582                           decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
7583       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
7584                           decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
7585       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
7586                           decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
7587       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
7588                           decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
7589       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
7590                           decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
7591     
7592     }
7593
7594     offset += 1; /* Skip Lock Type */
7595
7596     /* Build display for: OplockLevel */
7597
7598     OplockLevel = GBYTE(pd, offset);
7599
7600     if (tree) {
7601
7602       proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);
7603
7604     }
7605
7606     offset += 1; /* Skip OplockLevel */
7607
7608     /* Build display for: Timeout */
7609
7610     Timeout = GWORD(pd, offset);
7611
7612     if (tree) {
7613
7614       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
7615
7616     }
7617
7618     offset += 4; /* Skip Timeout */
7619
7620     /* Build display for: Number Of Unlocks */
7621
7622     NumberOfUnlocks = GSHORT(pd, offset);
7623
7624     if (tree) {
7625
7626       proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
7627
7628     }
7629
7630     offset += 2; /* Skip Number Of Unlocks */
7631
7632     /* Build display for: Number of Locks */
7633
7634     NumberofLocks = GSHORT(pd, offset);
7635
7636     if (tree) {
7637
7638       proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
7639
7640     }
7641
7642     offset += 2; /* Skip Number of Locks */
7643
7644     /* Build display for: Byte Count (BCC) */
7645
7646     ByteCount = GSHORT(pd, offset);
7647
7648     if (tree) {
7649
7650       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7651
7652     }
7653
7654     offset += 2; /* Skip Byte Count (BCC) */
7655
7656
7657     if (AndXCommand != 0xFF) {
7658
7659       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
7660
7661     }
7662
7663   } else {
7664     /* Response(s) dissect code */
7665
7666     /* Build display for: Word Count (WCT) */
7667
7668     WordCount = GBYTE(pd, offset);
7669
7670     if (tree) {
7671
7672       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7673
7674     }
7675
7676     offset += 1; /* Skip Word Count (WCT) */
7677
7678     if (WordCount != 0) {
7679
7680       /* Build display for: AndXCommand */
7681
7682       AndXCommand = GBYTE(pd, offset);
7683
7684       if (tree) {
7685
7686         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
7687                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
7688
7689       }
7690
7691       offset += 1; /* Skip AndXCommand */
7692
7693       /* Build display for: AndXReserved */
7694
7695       AndXReserved = GBYTE(pd, offset);
7696
7697       if (tree) {
7698
7699         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
7700
7701       }
7702
7703       offset += 1; /* Skip AndXReserved */
7704
7705       /* Build display for: AndXoffset */
7706
7707       AndXoffset = GSHORT(pd, offset);
7708
7709       if (tree) {
7710
7711         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
7712
7713       }
7714
7715       offset += 2; /* Skip AndXoffset */
7716
7717     }
7718
7719     /* Build display for: Byte Count */
7720
7721     ByteCount = GSHORT(pd, offset);
7722
7723     if (tree) {
7724
7725       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
7726
7727     }
7728
7729     offset += 2; /* Skip Byte Count */
7730
7731
7732     if (AndXCommand != 0xFF) {
7733
7734       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset);
7735
7736     }
7737
7738   }
7739
7740 }
7741
7742 void
7743 dissect_unlock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7744
7745 {
7746   guint8        WordCount;
7747   guint32       Offset;
7748   guint32       Count;
7749   guint16       FID;
7750   guint16       ByteCount;
7751
7752   if (si.request) {
7753     /* Request(s) dissect code */
7754
7755     /* Build display for: Word Count (WCT) */
7756
7757     WordCount = GBYTE(pd, offset);
7758
7759     if (tree) {
7760
7761       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7762
7763     }
7764
7765     offset += 1; /* Skip Word Count (WCT) */
7766
7767     /* Build display for: FID */
7768
7769     FID = GSHORT(pd, offset);
7770
7771     if (tree) {
7772
7773       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7774
7775     }
7776
7777     offset += 2; /* Skip FID */
7778
7779     /* Build display for: Count */
7780
7781     Count = GWORD(pd, offset);
7782
7783     if (tree) {
7784
7785       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
7786
7787     }
7788
7789     offset += 4; /* Skip Count */
7790
7791     /* Build display for: Offset */
7792
7793     Offset = GWORD(pd, offset);
7794
7795     if (tree) {
7796
7797       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7798
7799     }
7800
7801     offset += 4; /* Skip Offset */
7802
7803     /* Build display for: Byte Count (BCC) */
7804
7805     ByteCount = GSHORT(pd, offset);
7806
7807     if (tree) {
7808
7809       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7810
7811     }
7812
7813     offset += 2; /* Skip Byte Count (BCC) */
7814
7815   } else {
7816     /* Response(s) dissect code */
7817
7818     /* Build display for: Word Count (WCT) */
7819
7820     WordCount = GBYTE(pd, offset);
7821
7822     if (tree) {
7823
7824       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7825
7826     }
7827
7828     offset += 1; /* Skip Word Count (WCT) */
7829
7830     /* Build display for: Byte Count (BCC) */
7831
7832     ByteCount = GSHORT(pd, offset);
7833
7834     if (tree) {
7835
7836       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7837
7838     }
7839
7840     offset += 2; /* Skip Byte Count (BCC) */
7841
7842   }
7843
7844 }
7845
7846 void
7847 dissect_create_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
7848
7849 {
7850   proto_tree    *Attributes_tree;
7851   proto_item    *ti;
7852   guint8        WordCount;
7853   guint8        BufferFormat;
7854   guint16       FID;
7855   guint16       CreationTime;
7856   guint16       ByteCount;
7857   guint16       Attributes;
7858   const char    *FileName;
7859   int           string_len;
7860
7861   if (si.request) {
7862     /* Request(s) dissect code */
7863
7864     /* Build display for: Word Count (WCT) */
7865
7866     WordCount = GBYTE(pd, offset);
7867
7868     if (tree) {
7869
7870       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7871
7872     }
7873
7874     offset += 1; /* Skip Word Count (WCT) */
7875
7876     /* Build display for: Attributes */
7877
7878     Attributes = GSHORT(pd, offset);
7879
7880     if (tree) {
7881
7882       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
7883       Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
7884       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7885                           decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
7886       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7887                           decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
7888       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7889                           decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
7890       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7891                           decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
7892       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7893                           decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
7894       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7895                           decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
7896     
7897     }
7898
7899     offset += 2; /* Skip Attributes */
7900
7901     /* Build display for: Creation Time */
7902
7903     CreationTime = GSHORT(pd, offset);
7904
7905     if (tree) {
7906
7907       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
7908
7909     }
7910
7911     offset += 2; /* Skip Creation Time */
7912
7913     /* Build display for: Byte Count (BCC) */
7914
7915     ByteCount = GSHORT(pd, offset);
7916
7917     if (tree) {
7918
7919       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7920
7921     }
7922
7923     offset += 2; /* Skip Byte Count (BCC) */
7924
7925     /* Build display for: Buffer Format */
7926
7927     BufferFormat = GBYTE(pd, offset);
7928
7929     if (tree) {
7930
7931       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
7932                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
7933                           BufferFormat);
7934
7935     }
7936
7937     offset += 1; /* Skip Buffer Format */
7938
7939     /* Build display for: File Name */
7940
7941     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
7942
7943     if (tree) {
7944
7945       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
7946
7947     }
7948
7949     offset += string_len; /* Skip File Name */
7950
7951   } else {
7952     /* Response(s) dissect code */
7953
7954     /* Build display for: Word Count (WCT) */
7955
7956     WordCount = GBYTE(pd, offset);
7957
7958     if (tree) {
7959
7960       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7961
7962     }
7963
7964     offset += 1; /* Skip Word Count (WCT) */
7965
7966     if (WordCount != 0) {
7967
7968       /* Build display for: FID */
7969
7970       FID = GSHORT(pd, offset);
7971
7972       if (tree) {
7973
7974         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7975
7976       }
7977
7978       offset += 2; /* Skip FID */
7979       
7980     }
7981     
7982     /* Build display for: Byte Count (BCC) */
7983
7984     ByteCount = GSHORT(pd, offset);
7985
7986     if (tree) {
7987
7988       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7989
7990     }
7991
7992     offset += 2; /* Skip Byte Count (BCC) */
7993
7994   }
7995
7996 }
7997
7998 void
7999 dissect_search_dir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8000
8001 {
8002   guint8        WordCount;
8003   guint8        BufferFormat2;
8004   guint8        BufferFormat1;
8005   guint8        BufferFormat;
8006   guint16       SearchAttributes;
8007   guint16       ResumeKeyLength;
8008   guint16       MaxCount;
8009   guint16       DataLength;
8010   guint16       Count;
8011   guint16       ByteCount;
8012   const char    *FileName;
8013   int           string_len;
8014
8015   if (si.request) {
8016     /* Request(s) dissect code */
8017
8018     /* Build display for: Word Count (WCT) */
8019
8020     WordCount = GBYTE(pd, offset);
8021
8022     if (tree) {
8023
8024       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8025
8026     }
8027
8028     offset += 1; /* Skip Word Count (WCT) */
8029
8030     /* Build display for: Max Count */
8031
8032     MaxCount = GSHORT(pd, offset);
8033
8034     if (tree) {
8035
8036       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
8037
8038     }
8039
8040     offset += 2; /* Skip Max Count */
8041
8042     /* Build display for: Search Attributes */
8043
8044     SearchAttributes = GSHORT(pd, offset);
8045
8046     if (tree) {
8047
8048       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
8049
8050     }
8051
8052     offset += 2; /* Skip Search Attributes */
8053
8054     /* Build display for: Byte Count (BCC) */
8055
8056     ByteCount = GSHORT(pd, offset);
8057
8058     if (tree) {
8059
8060       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8061
8062     }
8063
8064     offset += 2; /* Skip Byte Count (BCC) */
8065
8066     /* Build display for: Buffer Format 1 */
8067
8068     BufferFormat1 = GBYTE(pd, offset);
8069
8070     if (tree) {
8071
8072       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %s (%u)",
8073                           val_to_str(BufferFormat1, buffer_format_vals, "Unknown"),
8074                           BufferFormat1);
8075
8076     }
8077
8078     offset += 1; /* Skip Buffer Format 1 */
8079
8080     /* Build display for: File Name */
8081
8082     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
8083
8084     if (tree) {
8085
8086       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
8087
8088     }
8089
8090     offset += string_len; /* Skip File Name */
8091
8092     /* Build display for: Buffer Format 2 */
8093
8094     BufferFormat2 = GBYTE(pd, offset);
8095
8096     if (tree) {
8097
8098       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %s (%u)",
8099                           val_to_str(BufferFormat2, buffer_format_vals, "Unknown"),
8100                           BufferFormat2);
8101
8102     }
8103
8104     offset += 1; /* Skip Buffer Format 2 */
8105
8106     /* Build display for: Resume Key Length */
8107
8108     ResumeKeyLength = GSHORT(pd, offset);
8109
8110     if (tree) {
8111
8112       proto_tree_add_text(tree, NullTVB, offset, 2, "Resume Key Length: %u", ResumeKeyLength);
8113
8114     }
8115
8116     offset += 2; /* Skip Resume Key Length */
8117
8118   } else {
8119     /* Response(s) dissect code */
8120
8121     /* Build display for: Word Count (WCT) */
8122
8123     WordCount = GBYTE(pd, offset);
8124
8125     if (tree) {
8126
8127       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8128
8129     }
8130
8131     offset += 1; /* Skip Word Count (WCT) */
8132
8133     if (WordCount != 0) {
8134
8135       /* Build display for: Count */
8136
8137       Count = GSHORT(pd, offset);
8138
8139       if (tree) {
8140
8141         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8142
8143       }
8144
8145       offset += 2; /* Skip Count */
8146
8147     }
8148
8149     /* Build display for: Byte Count (BCC) */
8150
8151     ByteCount = GSHORT(pd, offset);
8152
8153     if (tree) {
8154
8155       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8156
8157     }
8158
8159     offset += 2; /* Skip Byte Count (BCC) */
8160
8161     /* Build display for: Buffer Format */
8162
8163     BufferFormat = GBYTE(pd, offset);
8164
8165     if (tree) {
8166
8167       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8168                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8169                           BufferFormat);
8170
8171     }
8172
8173     offset += 1; /* Skip Buffer Format */
8174
8175     /* Build display for: Data Length */
8176
8177     DataLength = GSHORT(pd, offset);
8178
8179     if (tree) {
8180
8181       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8182
8183     }
8184
8185     offset += 2; /* Skip Data Length */
8186
8187   }
8188
8189 }
8190
8191 void
8192 dissect_create_temporary_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8193
8194 {
8195   guint8        WordCount;
8196   guint8        BufferFormat;
8197   guint16       Reserved;
8198   guint16       FID;
8199   guint16       CreationTime;
8200   guint16       CreationDate;
8201   guint16       ByteCount;
8202   const char    *FileName;
8203   const char    *DirectoryName;
8204   int           string_len;
8205
8206   if (si.request) {
8207     /* Request(s) dissect code */
8208
8209     /* Build display for: Word Count (WCT) */
8210
8211     WordCount = GBYTE(pd, offset);
8212
8213     if (tree) {
8214
8215       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8216
8217     }
8218
8219     offset += 1; /* Skip Word Count (WCT) */
8220
8221     /* Build display for: Reserved */
8222
8223     Reserved = GSHORT(pd, offset);
8224
8225     if (tree) {
8226
8227       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
8228
8229     }
8230
8231     offset += 2; /* Skip Reserved */
8232
8233     /* Build display for: Creation Time */
8234
8235     CreationTime = GSHORT(pd, offset);
8236
8237     if (tree) {
8238
8239       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
8240
8241     }
8242
8243     offset += 2; /* Skip Creation Time */
8244
8245     /* Build display for: Creation Date */
8246
8247     CreationDate = GSHORT(pd, offset);
8248
8249     if (tree) {
8250
8251       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
8252
8253     }
8254
8255     offset += 2; /* Skip Creation Date */
8256
8257     /* Build display for: Byte Count (BCC) */
8258
8259     ByteCount = GSHORT(pd, offset);
8260
8261     if (tree) {
8262
8263       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8264
8265     }
8266
8267     offset += 2; /* Skip Byte Count (BCC) */
8268
8269     /* Build display for: Buffer Format */
8270
8271     BufferFormat = GBYTE(pd, offset);
8272
8273     if (tree) {
8274
8275       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8276                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8277                           BufferFormat);
8278
8279     }
8280
8281     offset += 1; /* Skip Buffer Format */
8282
8283     /* Build display for: Directory Name */
8284
8285     DirectoryName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
8286
8287     if (tree) {
8288
8289       proto_tree_add_text(tree, NullTVB, offset, string_len, "Directory Name: %s", DirectoryName);
8290
8291     }
8292
8293     offset += string_len; /* Skip Directory Name */
8294
8295   } else {
8296     /* Response(s) dissect code */
8297
8298     /* Build display for: Word Count (WCT) */
8299
8300     WordCount = GBYTE(pd, offset);
8301
8302     if (tree) {
8303
8304       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8305
8306     }
8307
8308     offset += 1; /* Skip Word Count (WCT) */
8309
8310     if (WordCount != 0) {
8311
8312       /* Build display for: FID */
8313
8314       FID = GSHORT(pd, offset);
8315
8316       if (tree) {
8317
8318         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8319
8320       }
8321
8322       offset += 2; /* Skip FID */
8323
8324     }
8325
8326     /* Build display for: Byte Count (BCC) */
8327
8328     ByteCount = GSHORT(pd, offset);
8329
8330     if (tree) {
8331
8332       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8333
8334     }
8335
8336     offset += 2; /* Skip Byte Count (BCC) */
8337
8338     /* Build display for: Buffer Format */
8339
8340     BufferFormat = GBYTE(pd, offset);
8341
8342     if (tree) {
8343
8344       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8345                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8346                           BufferFormat);
8347
8348     }
8349
8350     offset += 1; /* Skip Buffer Format */
8351
8352     /* Build display for: File Name */
8353
8354     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
8355
8356     if (tree) {
8357
8358       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
8359
8360     }
8361
8362     offset += string_len; /* Skip File Name */
8363
8364   }
8365
8366 }
8367
8368 void
8369 dissect_close_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8370
8371 {
8372   guint8        WordCount;
8373   guint16       LastWriteTime;
8374   guint16       LastWriteDate;
8375   guint16       FID;
8376   guint16       ByteCount;
8377
8378   if (si.request) {
8379     /* Request(s) dissect code */
8380
8381     /* Build display for: Word Count (WCT) */
8382
8383     WordCount = GBYTE(pd, offset);
8384
8385     if (tree) {
8386
8387       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8388
8389     }
8390
8391     offset += 1; /* Skip Word Count (WCT) */
8392
8393     /* Build display for: FID */
8394
8395     FID = GSHORT(pd, offset);
8396
8397     if (tree) {
8398
8399       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8400
8401     }
8402
8403     offset += 2; /* Skip FID */
8404
8405     /* Build display for: Last Write Time */
8406
8407     LastWriteTime = GSHORT(pd, offset);
8408
8409     if (tree) {
8410
8411       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
8412
8413     }
8414
8415     offset += 2; /* Skip Last Write Time */
8416
8417     /* Build display for: Last Write Date */
8418
8419     LastWriteDate = GSHORT(pd, offset);
8420
8421     if (tree) {
8422
8423       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
8424
8425     }
8426
8427     offset += 2; /* Skip Last Write Date */
8428
8429     /* Build display for: Byte Count (BCC) */
8430
8431     ByteCount = GSHORT(pd, offset);
8432
8433     if (tree) {
8434
8435       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8436
8437     }
8438
8439     offset += 2; /* Skip Byte Count (BCC) */
8440
8441   } else {
8442     /* Response(s) dissect code */
8443
8444     /* Build display for: Word Count (WCT) */
8445
8446     WordCount = GBYTE(pd, offset);
8447
8448     if (tree) {
8449
8450       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8451
8452     }
8453
8454     offset += 1; /* Skip Word Count (WCT) */
8455
8456     /* Build display for: Byte Count (BCC) */
8457
8458     ByteCount = GSHORT(pd, offset);
8459
8460     if (tree) {
8461
8462       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8463
8464     }
8465
8466     offset += 2; /* Skip Byte Count (BCC) */
8467
8468   }
8469
8470 }
8471
8472 void
8473 dissect_write_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8474
8475 {
8476   guint8        WordCount;
8477   guint8        BufferFormat;
8478   guint16       FID;
8479   guint16       DataLength;
8480   guint16       ByteCount;
8481
8482   if (si.request) {
8483     /* Request(s) dissect code */
8484
8485     /* Build display for: Word Count (WCT) */
8486
8487     WordCount = GBYTE(pd, offset);
8488
8489     if (tree) {
8490
8491       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8492
8493     }
8494
8495     offset += 1; /* Skip Word Count (WCT) */
8496
8497     /* Build display for: FID */
8498
8499     FID = GSHORT(pd, offset);
8500
8501     if (tree) {
8502
8503       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8504
8505     }
8506
8507     offset += 2; /* Skip FID */
8508
8509     /* Build display for: Byte Count (BCC) */
8510
8511     ByteCount = GSHORT(pd, offset);
8512
8513     if (tree) {
8514
8515       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8516
8517     }
8518
8519     offset += 2; /* Skip Byte Count (BCC) */
8520
8521     /* Build display for: Buffer Format */
8522
8523     BufferFormat = GBYTE(pd, offset);
8524
8525     if (tree) {
8526
8527       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8528                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8529                           BufferFormat);
8530
8531     }
8532
8533     offset += 1; /* Skip Buffer Format */
8534
8535     /* Build display for: Data Length */
8536
8537     DataLength = GSHORT(pd, offset);
8538
8539     if (tree) {
8540
8541       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8542
8543     }
8544
8545     offset += 2; /* Skip Data Length */
8546
8547   } else {
8548     /* Response(s) dissect code */
8549
8550     /* Build display for: Word Count (WCT) */
8551
8552     WordCount = GBYTE(pd, offset);
8553
8554     if (tree) {
8555
8556       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8557
8558     }
8559
8560     offset += 1; /* Skip Word Count (WCT) */
8561
8562     /* Build display for: Byte Count (BCC) */
8563
8564     ByteCount = GSHORT(pd, offset);
8565
8566     if (tree) {
8567
8568       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8569
8570     }
8571
8572     offset += 2; /* Skip Byte Count (BCC) */
8573
8574   }
8575
8576 }
8577
8578 void
8579 dissect_lock_and_read_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8580
8581 {
8582   guint8        WordCount;
8583   guint8        BufferFormat;
8584   guint32       Offset;
8585   guint16       Reserved4;
8586   guint16       Reserved3;
8587   guint16       Reserved2;
8588   guint16       Reserved1;
8589   guint16       Remaining;
8590   guint16       FID;
8591   guint16       DataLength;
8592   guint16       Count;
8593   guint16       ByteCount;
8594
8595   if (si.request) {
8596     /* Request(s) dissect code */
8597
8598     /* Build display for: Word Count (WCT) */
8599
8600     WordCount = GBYTE(pd, offset);
8601
8602     if (tree) {
8603
8604       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8605
8606     }
8607
8608     offset += 1; /* Skip Word Count (WCT) */
8609
8610     /* Build display for: FID */
8611
8612     FID = GSHORT(pd, offset);
8613
8614     if (tree) {
8615
8616       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8617
8618     }
8619
8620     offset += 2; /* Skip FID */
8621
8622     /* Build display for: Count */
8623
8624     Count = GSHORT(pd, offset);
8625
8626     if (tree) {
8627
8628       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8629
8630     }
8631
8632     offset += 2; /* Skip Count */
8633
8634     /* Build display for: Offset */
8635
8636     Offset = GWORD(pd, offset);
8637
8638     if (tree) {
8639
8640       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
8641
8642     }
8643
8644     offset += 4; /* Skip Offset */
8645
8646     /* Build display for: Remaining */
8647
8648     Remaining = GSHORT(pd, offset);
8649
8650     if (tree) {
8651
8652       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
8653
8654     }
8655
8656     offset += 2; /* Skip Remaining */
8657
8658     /* Build display for: Byte Count (BCC) */
8659
8660     ByteCount = GSHORT(pd, offset);
8661
8662     if (tree) {
8663
8664       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8665
8666     }
8667
8668     offset += 2; /* Skip Byte Count (BCC) */
8669
8670   } else {
8671     /* Response(s) dissect code */
8672
8673     /* Build display for: Word Count (WCT) */
8674
8675     WordCount = GBYTE(pd, offset);
8676
8677     if (tree) {
8678
8679       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8680
8681     }
8682
8683     offset += 1; /* Skip Word Count (WCT) */
8684
8685     if (WordCount != 0) {
8686
8687       /* Build display for: Count */
8688
8689       Count = GSHORT(pd, offset);
8690
8691       if (tree) {
8692
8693         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
8694
8695       }
8696
8697       offset += 2; /* Skip Count */
8698
8699       /* Build display for: Reserved 1 */
8700
8701       Reserved1 = GSHORT(pd, offset);
8702
8703       if (tree) {
8704
8705         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
8706
8707       }
8708
8709       offset += 2; /* Skip Reserved 1 */
8710
8711       /* Build display for: Reserved 2 */
8712
8713       Reserved2 = GSHORT(pd, offset);
8714
8715       if (tree) {
8716
8717         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
8718
8719       }
8720
8721       offset += 2; /* Skip Reserved 2 */
8722
8723       /* Build display for: Reserved 3 */
8724
8725       Reserved3 = GSHORT(pd, offset);
8726
8727       if (tree) {
8728
8729         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
8730
8731       }
8732
8733       offset += 2; /* Skip Reserved 3 */
8734
8735       /* Build display for: Reserved 4 */
8736
8737       Reserved4 = GSHORT(pd, offset);
8738
8739       if (tree) {
8740
8741         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
8742
8743       }
8744
8745       offset += 2; /* Skip Reserved 4 */
8746
8747     }
8748
8749     /* Build display for: Byte Count (BCC) */
8750
8751     ByteCount = GSHORT(pd, offset);
8752
8753     if (tree) {
8754
8755       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8756
8757     }
8758
8759     offset += 2; /* Skip Byte Count (BCC) */
8760
8761     /* Build display for: Buffer Format */
8762
8763     BufferFormat = GBYTE(pd, offset);
8764
8765     if (tree) {
8766
8767       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8768                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8769                           BufferFormat);
8770
8771     }
8772
8773     offset += 1; /* Skip Buffer Format */
8774
8775     /* Build display for: Data Length */
8776
8777     DataLength = GSHORT(pd, offset);
8778
8779     if (tree) {
8780
8781       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8782
8783     }
8784
8785     offset += 2; /* Skip Data Length */
8786
8787   }
8788
8789 }
8790
8791 void
8792 dissect_process_exit_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8793
8794 {
8795   guint8        WordCount;
8796   guint16       ByteCount;
8797
8798   if (si.request) {
8799     /* Request(s) dissect code */
8800
8801     /* Build display for: Word Count (WCT) */
8802
8803     WordCount = GBYTE(pd, offset);
8804
8805     if (tree) {
8806
8807       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8808
8809     }
8810
8811     offset += 1; /* Skip Word Count (WCT) */
8812
8813     /* Build display for: Byte Count (BCC) */
8814
8815     ByteCount = GSHORT(pd, offset);
8816
8817     if (tree) {
8818
8819       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8820
8821     }
8822
8823     offset += 2; /* Skip Byte Count (BCC) */
8824
8825   } else {
8826     /* Response(s) dissect code */
8827
8828     /* Build display for: Word Count (WCT) */
8829
8830     WordCount = GBYTE(pd, offset);
8831
8832     if (tree) {
8833
8834       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8835
8836     }
8837
8838     offset += 1; /* Skip Word Count (WCT) */
8839
8840     /* Build display for: Byte Count (BCC) */
8841
8842     ByteCount = GSHORT(pd, offset);
8843
8844     if (tree) {
8845
8846       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8847
8848     }
8849
8850     offset += 2; /* Skip Byte Count (BCC) */
8851
8852   }
8853
8854 }
8855
8856 void
8857 dissect_get_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
8858
8859 {
8860   proto_tree    *Attributes_tree;
8861   proto_item    *ti;
8862   guint8        WordCount;
8863   guint8        BufferFormat;
8864   guint32       FileSize;
8865   guint16       Reserved5;
8866   guint16       Reserved4;
8867   guint16       Reserved3;
8868   guint16       Reserved2;
8869   guint16       Reserved1;
8870   guint16       LastWriteTime;
8871   guint16       LastWriteDate;
8872   guint16       ByteCount;
8873   guint16       Attributes;
8874   const char    *FileName;
8875   int           string_len;
8876
8877   if (si.request) {
8878     /* Request(s) dissect code */
8879
8880     /* Build display for: Word Count (WCT) */
8881
8882     WordCount = GBYTE(pd, offset);
8883
8884     if (tree) {
8885
8886       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8887
8888     }
8889
8890     offset += 1; /* Skip Word Count (WCT) */
8891
8892     /* Build display for: Byte Count (BCC) */
8893
8894     ByteCount = GSHORT(pd, offset);
8895
8896     if (tree) {
8897
8898       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8899
8900     }
8901
8902     offset += 2; /* Skip Byte Count (BCC) */
8903
8904     /* Build display for: Buffer Format */
8905
8906     BufferFormat = GBYTE(pd, offset);
8907
8908     if (tree) {
8909
8910       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %s (%u)",
8911                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
8912                           BufferFormat);
8913
8914     }
8915
8916     offset += 1; /* Skip Buffer Format */
8917
8918     /* Build display for: File Name */
8919
8920     FileName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &string_len);
8921
8922     if (tree) {
8923
8924       proto_tree_add_text(tree, NullTVB, offset, string_len, "File Name: %s", FileName);
8925
8926     }
8927
8928     offset += string_len; /* Skip File Name */
8929
8930   } else {
8931     /* Response(s) dissect code */
8932
8933     /* Build display for: Word Count (WCT) */
8934
8935     WordCount = GBYTE(pd, offset);
8936
8937     if (tree) {
8938
8939       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8940
8941     }
8942
8943     offset += 1; /* Skip Word Count (WCT) */
8944
8945     if (WordCount != 0) {
8946
8947       /* Build display for: Attributes */
8948
8949       Attributes = GSHORT(pd, offset);
8950
8951       if (tree) {
8952
8953         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
8954         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
8955         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8956                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
8957         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8958                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
8959         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8960                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
8961         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8962                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
8963         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8964                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
8965         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
8966                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
8967         
8968       }
8969
8970       offset += 2; /* Skip Attributes */
8971
8972       /* Build display for: Last Write Time */
8973
8974       LastWriteTime = GSHORT(pd, offset);
8975
8976       if (tree) {
8977
8978       }
8979
8980       offset += 2; /* Skip Last Write Time */
8981
8982       /* Build display for: Last Write Date */
8983
8984       LastWriteDate = GSHORT(pd, offset);
8985
8986       if (tree) {
8987
8988         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
8989
8990         proto_tree_add_text(tree, NullTVB, offset - 2, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
8991
8992       }
8993
8994       offset += 2; /* Skip Last Write Date */
8995
8996       /* Build display for: File Size */
8997
8998       FileSize = GWORD(pd, offset);
8999
9000       if (tree) {
9001
9002         proto_tree_add_text(tree, NullTVB, offset, 4, "File Size: %u", FileSize);
9003
9004       }
9005
9006       offset += 4; /* Skip File Size */
9007
9008       /* Build display for: Reserved 1 */
9009
9010       Reserved1 = GSHORT(pd, offset);
9011
9012       if (tree) {
9013
9014         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
9015
9016       }
9017
9018       offset += 2; /* Skip Reserved 1 */
9019
9020       /* Build display for: Reserved 2 */
9021
9022       Reserved2 = GSHORT(pd, offset);
9023
9024       if (tree) {
9025
9026         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
9027
9028       }
9029
9030       offset += 2; /* Skip Reserved 2 */
9031
9032       /* Build display for: Reserved 3 */
9033
9034       Reserved3 = GSHORT(pd, offset);
9035
9036       if (tree) {
9037
9038         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
9039
9040       }
9041
9042       offset += 2; /* Skip Reserved 3 */
9043
9044       /* Build display for: Reserved 4 */
9045
9046       Reserved4 = GSHORT(pd, offset);
9047
9048       if (tree) {
9049
9050         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
9051
9052       }
9053
9054       offset += 2; /* Skip Reserved 4 */
9055
9056       /* Build display for: Reserved 5 */
9057
9058       Reserved5 = GSHORT(pd, offset);
9059
9060       if (tree) {
9061
9062         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
9063
9064       }
9065
9066       offset += 2; /* Skip Reserved 5 */
9067
9068     }
9069
9070     /* Build display for: Byte Count (BCC) */
9071
9072     ByteCount = GSHORT(pd, offset);
9073
9074     if (tree) {
9075
9076       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9077
9078     }
9079
9080     offset += 2; /* Skip Byte Count (BCC) */
9081
9082   }
9083
9084 }
9085
9086 void
9087 dissect_read_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
9088
9089 {
9090   guint8        WordCount;
9091   guint32       Offset;
9092   guint16       Reserved4;
9093   guint16       Reserved3;
9094   guint16       Reserved2;
9095   guint16       Reserved1;
9096   guint16       Remaining;
9097   guint16       FID;
9098   guint16       DataLength;
9099   guint16       Count;
9100   guint16       ByteCount;
9101   guint16       BufferFormat;
9102
9103   if (si.request) {
9104     /* Request(s) dissect code */
9105
9106     /* Build display for: Word Count (WCT) */
9107
9108     WordCount = GBYTE(pd, offset);
9109
9110     if (tree) {
9111
9112       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9113
9114     }
9115
9116     offset += 1; /* Skip Word Count (WCT) */
9117
9118     /* Build display for: FID */
9119
9120     FID = GSHORT(pd, offset);
9121
9122     if (tree) {
9123
9124       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
9125
9126     }
9127
9128     offset += 2; /* Skip FID */
9129
9130     /* Build display for: Count */
9131
9132     Count = GSHORT(pd, offset);
9133
9134     if (tree) {
9135
9136       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
9137
9138     }
9139
9140     offset += 2; /* Skip Count */
9141
9142     /* Build display for: Offset */
9143
9144     Offset = GWORD(pd, offset);
9145
9146     if (tree) {
9147
9148       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
9149
9150     }
9151
9152     offset += 4; /* Skip Offset */
9153
9154     /* Build display for: Remaining */
9155
9156     Remaining = GSHORT(pd, offset);
9157
9158     if (tree) {
9159
9160       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
9161
9162     }
9163
9164     offset += 2; /* Skip Remaining */
9165
9166     /* Build display for: Byte Count (BCC) */
9167
9168     ByteCount = GSHORT(pd, offset);
9169
9170     if (tree) {
9171
9172       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9173
9174     }
9175
9176     offset += 2; /* Skip Byte Count (BCC) */
9177
9178   } else {
9179     /* Response(s) dissect code */
9180
9181     /* Build display for: Word Count (WCT) */
9182
9183     WordCount = GBYTE(pd, offset);
9184
9185     if (tree) {
9186
9187       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9188
9189     }
9190
9191     offset += 1; /* Skip Word Count (WCT) */
9192
9193     if (WordCount != 0) {
9194
9195       /* Build display for: Count */
9196
9197       Count = GSHORT(pd, offset);
9198
9199       if (tree) {
9200
9201         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
9202
9203       }
9204
9205       offset += 2; /* Skip Count */
9206
9207       /* Build display for: Reserved 1 */
9208
9209       Reserved1 = GSHORT(pd, offset);
9210
9211       if (tree) {
9212
9213         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
9214
9215       }
9216
9217       offset += 2; /* Skip Reserved 1 */
9218
9219       /* Build display for: Reserved 2 */
9220
9221       Reserved2 = GSHORT(pd, offset);
9222
9223       if (tree) {
9224
9225         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
9226
9227       }
9228
9229       offset += 2; /* Skip Reserved 2 */
9230
9231       /* Build display for: Reserved 3 */
9232
9233       Reserved3 = GSHORT(pd, offset);
9234
9235       if (tree) {
9236
9237         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
9238
9239       }
9240
9241       offset += 2; /* Skip Reserved 3 */
9242
9243       /* Build display for: Reserved 4 */
9244
9245       Reserved4 = GSHORT(pd, offset);
9246
9247       if (tree) {
9248
9249         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
9250
9251       }
9252
9253       offset += 2; /* Skip Reserved 4 */
9254
9255     }
9256     
9257     /* Build display for: Byte Count (BCC) */
9258     
9259     ByteCount = GSHORT(pd, offset);
9260       
9261     if (tree) {
9262
9263       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9264
9265     }
9266
9267     offset += 2; /* Skip Byte Count (BCC) */
9268
9269     /* Build display for: Buffer Format */
9270
9271     BufferFormat = GSHORT(pd, offset);
9272
9273     if (tree) {
9274
9275       proto_tree_add_text(tree, NullTVB, offset, 2, "Buffer Format: %s (%u)",
9276                           val_to_str(BufferFormat, buffer_format_vals, "Unknown"),
9277                           BufferFormat);
9278
9279     }
9280
9281     offset += 2; /* Skip Buffer Format */
9282
9283     /* Build display for: Data Length */
9284
9285     DataLength = GSHORT(pd, offset);
9286
9287     if (tree) {
9288
9289       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
9290
9291     }
9292
9293     offset += 2; /* Skip Data Length */
9294
9295   }
9296
9297 }
9298
9299 void
9300 dissect_write_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
9301
9302 {
9303   proto_tree    *WriteMode_tree;
9304   proto_item    *ti;
9305   guint8        WordCount;
9306   guint8        Pad;
9307   guint32       Timeout;
9308   guint32       ResponseMask;
9309   guint32       RequestMask;
9310   guint16       WriteMode;
9311   guint16       Reserved1;
9312   guint16       FID;
9313   guint16       DataOffset;
9314   guint16       DataLength;
9315   guint16       Count;
9316   guint16       ByteCount;
9317
9318   if (si.request) {
9319     /* Request(s) dissect code */
9320
9321     /* Build display for: Word Count (WCT) */
9322
9323     WordCount = GBYTE(pd, offset);
9324
9325     if (tree) {
9326
9327       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9328
9329     }
9330
9331     offset += 1; /* Skip Word Count (WCT) */
9332
9333     /* Build display for: FID */
9334
9335     FID = GSHORT(pd, offset);
9336
9337     if (tree) {
9338
9339       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
9340
9341     }
9342
9343     offset += 2; /* Skip FID */
9344
9345     /* Build display for: Count */
9346
9347     Count = GSHORT(pd, offset);
9348
9349     if (tree) {
9350
9351       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
9352
9353     }
9354
9355     offset += 2; /* Skip Count */
9356
9357     /* Build display for: Reserved 1 */
9358
9359     Reserved1 = GSHORT(pd, offset);
9360
9361     if (tree) {
9362
9363       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
9364
9365     }
9366
9367     offset += 2; /* Skip Reserved 1 */
9368
9369     /* Build display for: Timeout */
9370
9371     Timeout = GWORD(pd, offset);
9372
9373     if (tree) {
9374
9375       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
9376
9377     }
9378
9379     offset += 4; /* Skip Timeout */
9380
9381     /* Build display for: WriteMode */
9382
9383     WriteMode = GSHORT(pd, offset);
9384
9385     if (tree) {
9386
9387       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
9388       WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
9389       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
9390                           decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
9391       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
9392                           decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining", "Dont return Remaining"));
9393       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
9394                           decode_boolean_bitfield(WriteMode, 0x40, 16, "Connectionless mode requested", "Connectionless mode not requested"));
9395     
9396     }
9397
9398     offset += 2; /* Skip WriteMode */
9399
9400     /* Build display for: Request Mask */
9401
9402     RequestMask = GWORD(pd, offset);
9403
9404     if (tree) {
9405
9406       proto_tree_add_text(tree, NullTVB, offset, 4, "Request Mask: %u", RequestMask);
9407
9408     }
9409
9410     offset += 4; /* Skip Request Mask */
9411
9412     /* Build display for: Data Length */
9413
9414     DataLength = GSHORT(pd, offset);
9415
9416     if (tree) {
9417
9418       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
9419
9420     }
9421
9422     offset += 2; /* Skip Data Length */
9423
9424     /* Build display for: Data Offset */
9425
9426     DataOffset = GSHORT(pd, offset);
9427
9428     if (tree) {
9429
9430       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9431
9432     }
9433
9434     offset += 2; /* Skip Data Offset */
9435
9436     /* Build display for: Byte Count (BCC) */
9437
9438     ByteCount = GSHORT(pd, offset);
9439
9440     if (tree) {
9441
9442       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9443
9444     }
9445
9446     offset += 2; /* Skip Byte Count (BCC) */
9447
9448     /* Build display for: Pad */
9449
9450     Pad = GBYTE(pd, offset);
9451
9452     if (tree) {
9453
9454       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
9455
9456     }
9457
9458     offset += 1; /* Skip Pad */
9459
9460   } else {
9461     /* Response(s) dissect code */
9462
9463     /* Build display for: Word Count (WCT) */
9464
9465     WordCount = GBYTE(pd, offset);
9466
9467     if (tree) {
9468
9469       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9470
9471     }
9472
9473     offset += 1; /* Skip Word Count (WCT) */
9474
9475     if (WordCount != 0) {
9476
9477       /* Build display for: Response Mask */
9478
9479       ResponseMask = GWORD(pd, offset);
9480
9481       if (tree) {
9482
9483         proto_tree_add_text(tree, NullTVB, offset, 4, "Response Mask: %u", ResponseMask);
9484
9485       }
9486
9487       offset += 4; /* Skip Response Mask */
9488
9489     }
9490
9491     /* Build display for: Byte Count (BCC) */
9492
9493     ByteCount = GSHORT(pd, offset);
9494
9495     if (tree) {
9496
9497       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9498
9499     }
9500
9501     offset += 2; /* Skip Byte Count (BCC) */
9502
9503   }
9504
9505 }
9506
9507 void
9508 dissect_find_close2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
9509
9510 {
9511   guint8        WordCount;
9512   guint8        ByteCount;
9513   guint16       FID;
9514
9515   if (si.request) {
9516     /* Request(s) dissect code */
9517
9518     /* Build display for: Word Count (WTC) */
9519
9520     WordCount = GBYTE(pd, offset);
9521
9522     if (tree) {
9523
9524       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WTC): %u", WordCount);
9525
9526     }
9527
9528     offset += 1; /* Skip Word Count (WTC) */
9529
9530     /* Build display for: FID */
9531
9532     FID = GSHORT(pd, offset);
9533
9534     if (tree) {
9535
9536       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
9537
9538     }
9539
9540     offset += 2; /* Skip FID */
9541
9542     /* Build display for: Byte Count (BCC) */
9543
9544     ByteCount = GSHORT(pd, offset);
9545
9546     if (tree) {
9547
9548       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9549
9550     }
9551
9552     offset += 2; /* Skip Byte Count (BCC) */
9553
9554   } else {
9555     /* Response(s) dissect code */
9556
9557     /* Build display for: Word Count (WCT) */
9558
9559     WordCount = GBYTE(pd, offset);
9560
9561     if (tree) {
9562
9563       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9564
9565     }
9566
9567     offset += 1; /* Skip Word Count (WCT) */
9568
9569     /* Build display for: Byte Count (BCC) */
9570
9571     ByteCount = GBYTE(pd, offset);
9572
9573     if (tree) {
9574
9575       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
9576
9577     }
9578
9579     offset += 1; /* Skip Byte Count (BCC) */
9580
9581   }
9582
9583 }
9584
9585 static const value_string trans2_cmd_vals[] = {
9586   { 0x00, "TRANS2_OPEN" },
9587   { 0x01, "TRANS2_FIND_FIRST2" },
9588   { 0x02, "TRANS2_FIND_NEXT2" },
9589   { 0x03, "TRANS2_QUERY_FS_INFORMATION" },
9590   { 0x05, "TRANS2_QUERY_PATH_INFORMATION" },
9591   { 0x06, "TRANS2_SET_PATH_INFORMATION" },
9592   { 0x07, "TRANS2_QUERY_FILE_INFORMATION" },
9593   { 0x08, "TRANS2_SET_FILE_INFORMATION" },
9594   { 0x09, "TRANS2_FSCTL" },
9595   { 0x0A, "TRANS2_IOCTL2" },
9596   { 0x0B, "TRANS2_FIND_NOTIFY_FIRST" },
9597   { 0x0C, "TRANS2_FIND_NOTIFY_NEXT" },
9598   { 0x0D, "TRANS2_CREATE_DIRECTORY" },
9599   { 0x0E, "TRANS2_SESSION_SETUP" },
9600   { 0x10, "TRANS2_GET_DFS_REFERRAL" },
9601   { 0x11, "TRANS2_REPORT_DFS_INCONSISTENCY" },
9602   { 0,    NULL }
9603 };
9604
9605 void
9606 dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset)
9607
9608 {
9609   proto_tree    *Flags_tree;
9610   proto_item    *ti;
9611   guint8        WordCount;
9612   guint8        SetupCount;
9613   guint8        Reserved3;
9614   guint8        Reserved1;
9615   guint8        MaxSetupCount;
9616   guint8        Data;
9617   guint32       Timeout;
9618   guint16       TotalParameterCount;
9619   guint16       TotalDataCount;
9620   guint16       Setup;
9621   guint16       Reserved2;
9622   guint16       ParameterOffset;
9623   guint16       ParameterDisplacement;
9624   guint16       ParameterCount;
9625   guint16       MaxParameterCount;
9626   guint16       MaxDataCount;
9627   guint16       Flags;
9628   guint16       DataOffset;
9629   guint16       DataDisplacement;
9630   guint16       DataCount;
9631   guint16       ByteCount;
9632   conversation_t *conversation;
9633   struct smb_request_val *request_val;
9634   struct smb_continuation_val *continuation_val;
9635
9636   /*
9637    * Find out what conversation this packet is part of.
9638    * XXX - this should really be done by the transport-layer protocol,
9639    * although for connectionless transports, we may not want to do that
9640    * unless we know some higher-level protocol will want it - or we
9641    * may want to do it, so you can say e.g. "show only the packets in
9642    * this UDP 'connection'".
9643    *
9644    * Note that we don't have to worry about the direction this packet
9645    * was going - the conversation code handles that for us, treating
9646    * packets from A:X to B:Y as being part of the same conversation as
9647    * packets from B:Y to A:X.
9648    */
9649   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
9650                                 pi.srcport, pi.destport, 0);
9651   if (conversation == NULL) {
9652     /* It's not part of any conversation - create a new one. */
9653     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
9654                                 pi.srcport, pi.destport, 0);
9655   }
9656
9657   si.conversation = conversation;  /* Save this for later */
9658
9659   request_val = do_transaction_hashing(conversation, si, fd);
9660
9661   si.request_val = request_val;  /* Save this for later */
9662
9663   if (si.request) {
9664     /* Request(s) dissect code */
9665   
9666     /* Build display for: Word Count (WCT) */
9667
9668     WordCount = GBYTE(pd, offset);
9669
9670     if (tree) {
9671
9672       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9673
9674     }
9675
9676     offset += 1; /* Skip Word Count (WCT) */
9677
9678     /* Build display for: Total Parameter Count */
9679
9680     TotalParameterCount = GSHORT(pd, offset);
9681
9682     if (tree) {
9683
9684       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9685
9686     }
9687
9688     offset += 2; /* Skip Total Parameter Count */
9689
9690     /* Build display for: Total Data Count */
9691
9692     TotalDataCount = GSHORT(pd, offset);
9693
9694     if (tree) {
9695
9696       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
9697
9698     }
9699
9700     offset += 2; /* Skip Total Data Count */
9701
9702     /* Build display for: Max Parameter Count */
9703
9704     MaxParameterCount = GSHORT(pd, offset);
9705
9706     if (tree) {
9707
9708       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
9709
9710     }
9711
9712     offset += 2; /* Skip Max Parameter Count */
9713
9714     /* Build display for: Max Data Count */
9715
9716     MaxDataCount = GSHORT(pd, offset);
9717
9718     if (tree) {
9719
9720       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
9721
9722     }
9723
9724     offset += 2; /* Skip Max Data Count */
9725
9726     /* Build display for: Max Setup Count */
9727
9728     MaxSetupCount = GBYTE(pd, offset);
9729
9730     if (tree) {
9731
9732       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
9733
9734     }
9735
9736     offset += 1; /* Skip Max Setup Count */
9737
9738     /* Build display for: Reserved1 */
9739
9740     Reserved1 = GBYTE(pd, offset);
9741
9742     if (tree) {
9743
9744       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
9745
9746     }
9747
9748     offset += 1; /* Skip Reserved1 */
9749
9750     /* Build display for: Flags */
9751
9752     Flags = GSHORT(pd, offset);
9753
9754     if (tree) {
9755
9756       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
9757       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
9758       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9759                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
9760       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9761                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
9762     
9763     }
9764
9765     offset += 2; /* Skip Flags */
9766
9767     /* Build display for: Timeout */
9768
9769     Timeout = GWORD(pd, offset);
9770
9771     if (tree) {
9772
9773       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
9774
9775     }
9776
9777     offset += 4; /* Skip Timeout */
9778
9779     /* Build display for: Reserved2 */
9780
9781     Reserved2 = GSHORT(pd, offset);
9782
9783     if (tree) {
9784
9785       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9786
9787     }
9788
9789     offset += 2; /* Skip Reserved2 */
9790
9791     /* Build display for: Parameter Count */
9792
9793     if (!BYTES_ARE_IN_FRAME(offset, 2))
9794       return;
9795
9796     ParameterCount = GSHORT(pd, offset);
9797
9798     if (tree) {
9799
9800       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9801
9802     }
9803
9804     offset += 2; /* Skip Parameter Count */
9805
9806     /* Build display for: Parameter Offset */
9807
9808     if (!BYTES_ARE_IN_FRAME(offset, 2))
9809       return;
9810
9811     ParameterOffset = GSHORT(pd, offset);
9812
9813     if (tree) {
9814
9815       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9816
9817     }
9818
9819     offset += 2; /* Skip Parameter Offset */
9820
9821     /* Build display for: Data Count */
9822
9823     if (!BYTES_ARE_IN_FRAME(offset, 2))
9824       return;
9825
9826     DataCount = GSHORT(pd, offset);
9827
9828     if (tree) {
9829
9830       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9831
9832     }
9833
9834     offset += 2; /* Skip Data Count */
9835
9836     /* Build display for: Data Offset */
9837
9838     if (!BYTES_ARE_IN_FRAME(offset, 2))
9839       return;
9840
9841     DataOffset = GSHORT(pd, offset);
9842
9843     if (tree) {
9844
9845       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9846
9847     }
9848
9849     offset += 2; /* Skip Data Offset */
9850
9851     /* Build display for: Setup Count */
9852
9853     if (!BYTES_ARE_IN_FRAME(offset, 2))
9854       return;
9855
9856     SetupCount = GBYTE(pd, offset);
9857
9858     if (tree) {
9859
9860       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9861
9862     }
9863
9864     offset += 1; /* Skip Setup Count */
9865
9866     /* Build display for: Reserved3 */
9867
9868     Reserved3 = GBYTE(pd, offset);
9869
9870     if (tree) {
9871
9872       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9873
9874     }
9875
9876     offset += 1; /* Skip Reserved3 */
9877
9878     /* Build display for: Setup */
9879
9880     if (SetupCount != 0) {
9881
9882       int i;
9883
9884       if (!BYTES_ARE_IN_FRAME(offset, 2))
9885         return;
9886
9887       /*
9888        * First Setup word is transaction code.
9889        */
9890       Setup = GSHORT(pd, offset);
9891
9892       if (!fd->flags.visited) {
9893         /*
9894          * This is the first time this frame has been seen; remember
9895          * the transaction code.
9896          */
9897         g_assert(request_val -> last_transact2_command == -1);
9898         request_val -> last_transact2_command = Setup;  /* Save for later */
9899       }
9900
9901       if (check_col(fd, COL_INFO)) {
9902
9903         col_add_fstr(fd, COL_INFO, "%s Request",
9904                      val_to_str(Setup, trans2_cmd_vals, "Unknown (0x%02X)"));
9905
9906       }
9907
9908       if (tree) {
9909
9910         proto_tree_add_text(tree, NullTVB, offset, 2, "Setup1: %s",
9911                           val_to_str(Setup, trans2_cmd_vals, "Unknown (0x%02X)"));
9912
9913       }
9914
9915       offset += 2; /* Skip Setup word */
9916
9917       for (i = 2; i <= SetupCount; i++) {
9918
9919         if (!BYTES_ARE_IN_FRAME(offset, 2))
9920           return;
9921
9922         Setup = GSHORT(pd, offset);
9923
9924         if (tree) {
9925
9926           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
9927
9928         }
9929
9930         offset += 2; /* Skip Setup word */
9931
9932       }
9933
9934     }
9935
9936     /* Build display for: Byte Count (BCC) */
9937
9938     if (!BYTES_ARE_IN_FRAME(offset, 2))
9939       return;
9940
9941     ByteCount = GSHORT(pd, offset);
9942
9943     if (tree) {
9944
9945       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9946
9947     }
9948
9949     offset += 2; /* Skip Byte Count (BCC) */
9950
9951     if (offset < (SMB_offset + ParameterOffset)) {
9952
9953       int pad1Count = SMB_offset + ParameterOffset - offset;
9954
9955       /* Build display for: Pad1 */
9956
9957       if (tree) {
9958
9959         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s",
9960                             bytes_to_str(pd + offset, pad1Count));
9961       }
9962
9963       offset += pad1Count; /* Skip Pad1 */
9964
9965     }
9966
9967     if (ParameterCount > 0) {
9968
9969       /* Build display for: Parameters */
9970
9971       if (tree) {
9972
9973         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset,
9974                             ParameterCount, "Parameters: %s",
9975                             bytes_to_str(pd + SMB_offset + ParameterOffset,
9976                                          ParameterCount));
9977
9978       }
9979
9980       offset += ParameterCount; /* Skip Parameters */
9981
9982     }
9983
9984     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
9985
9986       int pad2Count = SMB_offset + DataOffset - offset;
9987         
9988       /* Build display for: Pad2 */
9989
9990       if (tree) {
9991
9992         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s",
9993                             bytes_to_str(pd + offset, pad2Count));
9994
9995       }
9996
9997       offset += pad2Count; /* Skip Pad2 */
9998
9999     }
10000
10001     if (DataCount > 0) {
10002
10003       /* Build display for: Data */
10004
10005       Data = GBYTE(pd, offset);
10006
10007       if (tree) {
10008
10009         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset,
10010                             DataCount, "Data: %s",
10011                             bytes_to_str(pd + offset, DataCount));
10012
10013       }
10014
10015       offset += DataCount; /* Skip Data */
10016
10017     }
10018   } else {
10019     /* Response(s) dissect code */
10020
10021     /* Pick up the last transact2 command and put it in the right places */
10022
10023     if (check_col(fd, COL_INFO)) {
10024
10025       if (request_val == NULL)
10026         col_set_str(fd, COL_INFO, "Response to unknown SMBtrans2");
10027       else if (request_val -> last_transact2_command == -1)
10028         col_set_str(fd, COL_INFO, "Response to SMBtrans2 of unknown type");
10029       else
10030         col_add_fstr(fd, COL_INFO, "%s Response",
10031                      val_to_str(request_val -> last_transact2_command,
10032                                 trans2_cmd_vals, "Unknown (0x%02X)"));
10033
10034     }
10035
10036     /* Build display for: Word Count (WCT) */
10037
10038     WordCount = GBYTE(pd, offset);
10039
10040     if (tree) {
10041
10042       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
10043
10044     }
10045
10046     offset += 1; /* Skip Word Count (WCT) */
10047
10048     if (WordCount == 0) {
10049
10050       /* Interim response. */
10051
10052       if (check_col(fd, COL_INFO)) {
10053
10054         if (request_val == NULL)
10055           col_set_str(fd, COL_INFO, "Interim response to unknown SMBtrans2");
10056         else if (request_val -> last_transact2_command == -1)
10057           col_set_str(fd, COL_INFO, "Interim response to SMBtrans2 of unknown type");
10058         else
10059           col_add_fstr(fd, COL_INFO, "%s interim response",
10060                        val_to_str(request_val -> last_transact2_command,
10061                                   trans2_cmd_vals, "Unknown (0x%02X)"));
10062
10063       }
10064
10065       /* Build display for: Byte Count (BCC) */
10066
10067       ByteCount = GSHORT(pd, offset);
10068
10069       if (tree) {
10070
10071         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
10072
10073       }
10074
10075       offset += 2; /* Skip Byte Count (BCC) */
10076
10077       return;
10078
10079     }
10080
10081     /* Build display for: Total Parameter Count */
10082
10083     TotalParameterCount = GSHORT(pd, offset);
10084
10085     if (tree) {
10086
10087       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
10088
10089     }
10090
10091     offset += 2; /* Skip Total Parameter Count */
10092
10093     /* Build display for: Total Data Count */
10094
10095     TotalDataCount = GSHORT(pd, offset);
10096
10097     if (tree) {
10098
10099       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
10100
10101     }
10102
10103     offset += 2; /* Skip Total Data Count */
10104
10105     /* Build display for: Reserved2 */
10106
10107     Reserved2 = GSHORT(pd, offset);
10108
10109     if (tree) {
10110
10111       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
10112
10113     }
10114
10115     offset += 2; /* Skip Reserved2 */
10116
10117     /* Build display for: Parameter Count */
10118
10119     ParameterCount = GSHORT(pd, offset);
10120
10121     if (tree) {
10122
10123       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
10124
10125     }
10126
10127     offset += 2; /* Skip Parameter Count */
10128
10129     /* Build display for: Parameter Offset */
10130
10131     ParameterOffset = GSHORT(pd, offset);
10132
10133     if (tree) {
10134
10135       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
10136
10137     }
10138
10139     offset += 2; /* Skip Parameter Offset */
10140
10141     /* Build display for: Parameter Displacement */
10142
10143     ParameterDisplacement = GSHORT(pd, offset);
10144
10145     if (tree) {
10146
10147       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
10148
10149     }
10150
10151     offset += 2; /* Skip Parameter Displacement */
10152
10153     /* Build display for: Data Count */
10154
10155     DataCount = GSHORT(pd, offset);
10156
10157     if (tree) {
10158
10159       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
10160
10161     }
10162
10163     offset += 2; /* Skip Data Count */
10164
10165     /* Build display for: Data Offset */
10166
10167     DataOffset = GSHORT(pd, offset);
10168
10169     if (tree) {
10170
10171       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
10172
10173     }
10174
10175     offset += 2; /* Skip Data Offset */
10176
10177     /* Build display for: Data Displacement */
10178
10179     if (!BYTES_ARE_IN_FRAME(offset, 2))
10180       return;
10181
10182     DataDisplacement = GSHORT(pd, offset);
10183     si.ddisp = DataDisplacement;
10184
10185     if (tree) {
10186
10187       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
10188
10189     }
10190
10191     offset += 2; /* Skip Data Displacement */
10192
10193     /* Build display for: Setup Count */
10194
10195     SetupCount = GBYTE(pd, offset);
10196
10197     if (tree) {
10198
10199       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
10200
10201     }
10202
10203     offset += 1; /* Skip Setup Count */
10204
10205     /* Build display for: Reserved3 */
10206
10207     Reserved3 = GBYTE(pd, offset);
10208
10209     if (tree) {
10210
10211       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
10212
10213     }
10214
10215     offset += 1; /* Skip Reserved3 */
10216
10217     if (SetupCount != 0) {
10218
10219       int i;
10220
10221       for (i = 1; i <= SetupCount; i++) {
10222         
10223         Setup = GSHORT(pd, offset);
10224
10225         if (tree) {
10226
10227           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
10228
10229         }
10230
10231         offset += 2; /* Skip Setup */
10232
10233       }
10234     }
10235
10236     /* Build display for: Byte Count (BCC) */
10237
10238     ByteCount = GSHORT(pd, offset);
10239
10240     if (tree) {
10241
10242       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
10243
10244     }
10245
10246     offset += 2; /* Skip Byte Count (BCC) */
10247
10248     if (offset < (SMB_offset + ParameterOffset)) {
10249
10250       int pad1Count = SMB_offset + ParameterOffset - offset;
10251
10252       /* Build display for: Pad1 */
10253
10254       if (tree) {
10255
10256         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s",
10257                             bytes_to_str(pd + offset, pad1Count));
10258       }
10259
10260       offset += pad1Count; /* Skip Pad1 */
10261
10262     }
10263
10264     /* Build display for: Parameters */
10265
10266     if (ParameterCount > 0) {
10267
10268       if (tree) {
10269
10270         proto_tree_add_text(tree, NullTVB, offset, ParameterCount,
10271                             "Parameters: %s",
10272                             bytes_to_str(pd + offset, ParameterCount));
10273
10274       }
10275
10276       offset += ParameterCount; /* Skip Parameters */
10277
10278     }
10279
10280     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
10281
10282       int pad2Count = SMB_offset + DataOffset - offset;
10283         
10284       /* Build display for: Pad2 */
10285
10286       if (tree) {
10287
10288         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s",
10289                             bytes_to_str(pd + offset, pad2Count));
10290
10291       }
10292
10293       offset += pad2Count; /* Skip Pad2 */
10294
10295     }
10296
10297     /* Build display for: Data */
10298
10299     if (DataCount > 0) {
10300
10301       if (tree) {
10302
10303         proto_tree_add_text(tree, NullTVB, offset, DataCount,
10304                             "Data: %s",
10305                             bytes_to_str(pd + offset, DataCount));
10306
10307       }
10308
10309       offset += DataCount; /* Skip Data */
10310
10311     }
10312
10313   }
10314
10315 }
10316
10317
10318 static void 
10319 dissect_transact_params(const u_char *pd, int offset, frame_data *fd,
10320     proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data,
10321     int SMB_offset, int DataOffset, int DataCount,
10322     int ParameterOffset, int ParameterCount, int SetupAreaOffset,
10323     int SetupCount, const char *TransactName)
10324 {
10325   char             *TransactNameCopy;
10326   char             *trans_type = NULL, *trans_cmd, *loc_of_slash = NULL;
10327   int              index;
10328   const gchar      *Data;
10329   packet_info      *pinfo;
10330   tvbuff_t         *next_tvb;
10331   tvbuff_t         *setup_tvb;
10332
10333   if (TransactName != NULL) {
10334     /* Should check for error here ... */
10335
10336     TransactNameCopy = g_strdup(TransactName);
10337
10338     if (TransactNameCopy[0] == '\\') {
10339       trans_type = TransactNameCopy + 1;  /* Skip the slash */
10340       loc_of_slash = trans_type ? strchr(trans_type, '\\') : NULL;
10341     }
10342
10343     if (loc_of_slash) {
10344       index = loc_of_slash - trans_type;  /* Make it a real index */
10345       trans_cmd = trans_type + index + 1;
10346       trans_type[index] = '\0';
10347     }
10348     else
10349       trans_cmd = NULL;
10350   } else
10351     trans_cmd = NULL;
10352
10353   pinfo = &pi;
10354
10355   /*
10356    * Number of bytes of parameter.
10357    */
10358   si.parameter_count = ParameterCount;
10359
10360   if (DataOffset < 0) {
10361     /*
10362      * This is an interim response, so there're no parameters or data
10363      * to dissect.
10364      */
10365     si.is_interim_response = TRUE;
10366
10367     /*
10368      * Create a zero-length tvbuff.
10369      */
10370     next_tvb = tvb_create_from_top(pi.captured_len);
10371   } else {
10372     /*
10373      * This isn't an interim response.
10374      */
10375     si.is_interim_response = FALSE;
10376
10377     /*
10378      * Create a tvbuff for the parameters and data.
10379      */
10380     next_tvb = tvb_create_from_top(SMB_offset + ParameterOffset);
10381   }
10382
10383   /*
10384    * Offset of beginning of data from beginning of next_tvb.
10385    */
10386   si.data_offset = DataOffset - ParameterOffset;
10387
10388   /*
10389    * Number of bytes of data.
10390    */
10391   si.data_count = DataCount;
10392
10393   /*
10394    * Command.
10395    */
10396   si.trans_cmd = trans_cmd;
10397
10398   /*
10399    * Pass "si" to the subdissector.
10400    */
10401   pinfo->private = &si;
10402
10403   /*
10404    * Tvbuff for setup area, for mailslot call.
10405    */
10406   /*
10407    * Is there a setup area?
10408    */
10409   if (SetupAreaOffset < 0) {
10410     /*
10411      * No - create a zero-length tvbuff.
10412      */
10413     setup_tvb = tvb_create_from_top(pi.captured_len);
10414   } else {
10415     /*
10416      * Create a tvbuff for the setup area.
10417      */
10418     setup_tvb = tvb_create_from_top(SetupAreaOffset);
10419   }
10420
10421   if ((trans_cmd == NULL) ||
10422       (((trans_type == NULL || strcmp(trans_type, "MAILSLOT") != 0) ||
10423        !dissect_mailslot_smb(setup_tvb, next_tvb, pinfo, parent)) &&
10424       ((trans_type == NULL || strcmp(trans_type, "PIPE") != 0) ||
10425        !dissect_pipe_smb(next_tvb, pinfo, parent)))) {
10426
10427     if (ParameterCount > 0) {
10428
10429       /* Build display for: Parameters */
10430       
10431       if (tree) {
10432
10433         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset,
10434                             ParameterCount, "Parameters: %s",
10435                             bytes_to_str(pd + SMB_offset + ParameterOffset,
10436                                          ParameterCount));
10437           
10438       }
10439         
10440       offset = SMB_offset + ParameterOffset + ParameterCount; /* Skip Parameters */
10441
10442     }
10443
10444     if (DataCount > 0 && offset < (SMB_offset + DataOffset)) {
10445
10446       int pad2Count = SMB_offset + DataOffset - offset;
10447         
10448       /* Build display for: Pad2 */
10449
10450       if (tree) {
10451
10452         proto_tree_add_text(tree, NullTVB, offset, pad2Count, "Pad2: %s",
10453                             bytes_to_str(pd + offset, pad2Count));
10454
10455       }
10456
10457       offset += pad2Count; /* Skip Pad2 */
10458
10459     }
10460
10461     if (DataCount > 0) {
10462
10463       /* Build display for: Data */
10464
10465       Data = pd + SMB_offset + DataOffset;
10466
10467       if (tree) {
10468
10469         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset, DataCount,
10470                             "Data: %s",
10471                             bytes_to_str(pd + SMB_offset + DataOffset, DataCount));
10472
10473       }
10474
10475       offset += DataCount; /* Skip Data */
10476
10477     }
10478   }
10479
10480 }
10481
10482 void
10483 dissect_transact_smb(const u_char *pd, int offset, frame_data *fd,
10484                      proto_tree *parent, proto_tree *tree,
10485                      struct smb_info si, int max_data, int SMB_offset)
10486 {
10487   proto_tree    *Flags_tree;
10488   proto_item    *ti;
10489   guint8        WordCount;
10490   guint8        SetupCount;
10491   guint8        Reserved3;
10492   guint8        Reserved1;
10493   guint8        MaxSetupCount;
10494   guint32       Timeout;
10495   guint16       TotalParameterCount;
10496   guint16       TotalDataCount;
10497   guint16       Setup = 0;
10498   guint16       Reserved2;
10499   guint16       ParameterOffset;
10500   guint16       ParameterDisplacement;
10501   guint16       ParameterCount;
10502   guint16       MaxParameterCount;
10503   guint16       MaxDataCount;
10504   guint16       Flags;
10505   guint16       DataOffset;
10506   guint16       DataDisplacement;
10507   guint16       DataCount;
10508   guint16       ByteCount;
10509   int           TNlen;
10510   const char    *TransactName;
10511   conversation_t *conversation;
10512   struct smb_request_val *request_val;
10513   guint16       SetupAreaOffset;
10514
10515   /*
10516    * Find out what conversation this packet is part of
10517    */
10518
10519   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
10520                                    pi.srcport, pi.destport, 0);
10521
10522   if (conversation == NULL) {  /* Create a new conversation */
10523
10524     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
10525                                     pi.srcport, pi.destport, 0);
10526
10527   }
10528
10529   si.conversation = conversation;  /* Save this */
10530
10531   request_val = do_transaction_hashing(conversation, si, fd);
10532
10533   si.request_val = request_val;  /* Save this for later */
10534
10535   if (si.request) {
10536     /* Request(s) dissect code */
10537
10538     /* Build display for: Word Count (WCT) */
10539
10540     WordCount = GBYTE(pd, offset);
10541
10542     if (tree) {
10543
10544       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
10545
10546     }
10547
10548     offset += 1; /* Skip Word Count (WCT) */
10549
10550     /* Build display for: Total Parameter Count */
10551
10552     TotalParameterCount = GSHORT(pd, offset);
10553
10554     if (tree) {
10555
10556       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
10557
10558     }
10559
10560     offset += 2; /* Skip Total Parameter Count */
10561
10562     /* Build display for: Total Data Count */
10563
10564     if (!BYTES_ARE_IN_FRAME(offset, 2))
10565       return;
10566
10567     TotalDataCount = GSHORT(pd, offset);
10568
10569     if (tree) {
10570
10571       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
10572
10573     }
10574
10575     offset += 2; /* Skip Total Data Count */
10576
10577     /* Build display for: Max Parameter Count */
10578
10579     MaxParameterCount = GSHORT(pd, offset);
10580
10581     if (tree) {
10582
10583       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
10584
10585     }
10586
10587     offset += 2; /* Skip Max Parameter Count */
10588
10589     /* Build display for: Max Data Count */
10590
10591     MaxDataCount = GSHORT(pd, offset);
10592
10593     if (tree) {
10594
10595       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
10596
10597     }
10598
10599     offset += 2; /* Skip Max Data Count */
10600
10601     /* Build display for: Max Setup Count */
10602
10603     MaxSetupCount = GBYTE(pd, offset);
10604
10605     if (tree) {
10606
10607       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
10608
10609     }
10610
10611     offset += 1; /* Skip Max Setup Count */
10612
10613     /* Build display for: Reserved1 */
10614
10615     Reserved1 = GBYTE(pd, offset);
10616
10617     if (tree) {
10618
10619       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
10620
10621     }
10622
10623     offset += 1; /* Skip Reserved1 */
10624
10625     /* Build display for: Flags */
10626
10627     Flags = GSHORT(pd, offset);
10628
10629     if (tree) {
10630
10631       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
10632       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
10633       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
10634                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
10635       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
10636                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
10637     
10638     }
10639
10640     offset += 2; /* Skip Flags */
10641
10642     /* Build display for: Timeout */
10643
10644     Timeout = GWORD(pd, offset);
10645
10646     if (tree) {
10647
10648       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
10649
10650     }
10651
10652     offset += 4; /* Skip Timeout */
10653
10654     /* Build display for: Reserved2 */
10655
10656     Reserved2 = GSHORT(pd, offset);
10657
10658     if (tree) {
10659
10660       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
10661
10662     }
10663
10664     offset += 2; /* Skip Reserved2 */
10665
10666     /* Build display for: Parameter Count */
10667
10668     if (!BYTES_ARE_IN_FRAME(offset, 2))
10669       return;
10670
10671     ParameterCount = GSHORT(pd, offset);
10672
10673     if (tree) {
10674
10675       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
10676
10677     }
10678
10679     offset += 2; /* Skip Parameter Count */
10680
10681     /* Build display for: Parameter Offset */
10682
10683     if (!BYTES_ARE_IN_FRAME(offset, 2))
10684       return;
10685
10686     ParameterOffset = GSHORT(pd, offset);
10687
10688     if (tree) {
10689
10690       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
10691
10692     }
10693
10694     offset += 2; /* Skip Parameter Offset */
10695
10696     /* Build display for: Data Count */
10697
10698     if (!BYTES_ARE_IN_FRAME(offset, 2))
10699       return;
10700
10701     DataCount = GSHORT(pd, offset);
10702
10703     if (tree) {
10704
10705       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
10706
10707     }
10708
10709     offset += 2; /* Skip Data Count */
10710
10711     /* Build display for: Data Offset */
10712
10713     if (!BYTES_ARE_IN_FRAME(offset, 2))
10714       return;
10715
10716     DataOffset = GSHORT(pd, offset);
10717
10718     if (tree) {
10719
10720       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
10721
10722     }
10723
10724     offset += 2; /* Skip Data Offset */
10725
10726     /* Build display for: Setup Count */
10727
10728     if (!BYTES_ARE_IN_FRAME(offset, 2))
10729       return;
10730
10731     SetupCount = GBYTE(pd, offset);
10732
10733     if (tree) {
10734
10735       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
10736
10737     }
10738
10739     offset += 1; /* Skip Setup Count */
10740
10741     /* Build display for: Reserved3 */
10742
10743     Reserved3 = GBYTE(pd, offset);
10744
10745     if (tree) {
10746
10747       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
10748     }
10749
10750     offset += 1; /* Skip Reserved3 */
10751  
10752     SetupAreaOffset = offset;
10753
10754     /* Build display for: Setup */
10755
10756     if (SetupCount > 0) {
10757
10758       int i = SetupCount;
10759
10760       if (!BYTES_ARE_IN_FRAME(offset, 2))
10761         return;
10762
10763       Setup = GSHORT(pd, offset);
10764
10765       for (i = 1; i <= SetupCount; i++) {
10766         
10767         if (!BYTES_ARE_IN_FRAME(offset, 2))
10768           return;
10769
10770         Setup = GSHORT(pd, offset);
10771
10772         if (tree) {
10773
10774           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
10775
10776         }
10777
10778         offset += 2; /* Skip Setup */
10779
10780       }
10781
10782     }
10783
10784     /* Build display for: Byte Count (BCC) */
10785
10786     if (!BYTES_ARE_IN_FRAME(offset, 2))
10787       return;
10788
10789     ByteCount = GSHORT(pd, offset);
10790
10791     if (tree) {
10792
10793       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
10794
10795     }
10796
10797     offset += 2; /* Skip Byte Count (BCC) */
10798
10799     /* Build display for: Transact Name */
10800
10801     TransactName = get_unicode_or_ascii_string(pd, &offset, SMB_offset, si.unicode, &TNlen);
10802
10803     if (!fd->flags.visited) {
10804       /*
10805        * This is the first time this frame has been seen; remember
10806        * the transaction name.
10807        */
10808       g_assert(request_val -> last_transact_command == NULL);
10809       request_val -> last_transact_command = g_strdup(TransactName);
10810     }
10811
10812     if (check_col(fd, COL_INFO)) {
10813
10814       col_add_fstr(fd, COL_INFO, "%s Request", TransactName);
10815
10816     }
10817
10818     if (tree) {
10819
10820       proto_tree_add_text(tree, NullTVB, offset, TNlen, "Transact Name: %s", TransactName);
10821
10822     }
10823
10824     offset += TNlen; /* Skip Transact Name */
10825     if (si.unicode) offset += 2;   /* There are two more extraneous bytes there*/
10826
10827     if (offset < (SMB_offset + ParameterOffset)) {
10828
10829       int pad1Count = SMB_offset + ParameterOffset - offset;
10830
10831       /* Build display for: Pad1 */
10832
10833       if (tree) {
10834
10835         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s",
10836                             bytes_to_str(pd + offset, pad1Count));
10837       }
10838
10839       offset += pad1Count; /* Skip Pad1 */
10840
10841     }
10842
10843     /* Let's see if we can decode this */
10844
10845     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data,
10846                             SMB_offset, DataOffset, DataCount,
10847                             ParameterOffset, ParameterCount,
10848                             SetupAreaOffset, SetupCount, TransactName);
10849
10850   } else {
10851     /* Response(s) dissect code */
10852
10853     if (check_col(fd, COL_INFO)) {
10854       if ( request_val == NULL )
10855         col_set_str(fd, COL_INFO, "Response to unknown SMBtrans");
10856       else if (request_val -> last_transact_command == NULL)
10857         col_set_str(fd, COL_INFO, "Response to SMBtrans of unknown type");
10858       else
10859         col_add_fstr(fd, COL_INFO, "%s Response",
10860                      request_val -> last_transact_command);
10861
10862     }
10863
10864     /* Build display for: Word Count (WCT) */
10865
10866     WordCount = GBYTE(pd, offset);
10867
10868     if (tree) {
10869
10870       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
10871
10872     }
10873
10874     offset += 1; /* Skip Word Count (WCT) */
10875
10876     if (WordCount == 0) {
10877
10878       /* Interim response. */
10879
10880       if (check_col(fd, COL_INFO)) {
10881         if ( request_val == NULL )
10882           col_set_str(fd, COL_INFO, "Interim response to unknown SMBtrans");
10883         else if (request_val -> last_transact_command == NULL)
10884           col_set_str(fd, COL_INFO, "Interim response to SMBtrans of unknown type");
10885         else
10886           col_add_fstr(fd, COL_INFO, "%s interim response",
10887                        request_val -> last_transact_command);
10888
10889       }
10890
10891       /* Build display for: Byte Count (BCC) */
10892
10893       ByteCount = GSHORT(pd, offset);
10894
10895       if (tree) {
10896
10897         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
10898
10899       }
10900
10901       offset += 2; /* Skip Byte Count (BCC) */
10902
10903       /* Dissect the interim response by showing the type of request to
10904          which it's a reply, if we have that information. */
10905       if (request_val != NULL) {
10906         dissect_transact_params(pd, offset, fd, parent, tree, si, max_data,
10907                                 SMB_offset, -1, -1, -1, -1, -1, -1,
10908                                 request_val -> last_transact_command);
10909       }
10910
10911       return;
10912
10913     }
10914
10915     /* Build display for: Total Parameter Count */
10916
10917     TotalParameterCount = GSHORT(pd, offset);
10918
10919     if (tree) {
10920
10921       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
10922
10923     }
10924
10925     offset += 2; /* Skip Total Parameter Count */
10926
10927     /* Build display for: Total Data Count */
10928
10929     TotalDataCount = GSHORT(pd, offset);
10930
10931     if (tree) {
10932
10933       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
10934
10935     }
10936
10937     offset += 2; /* Skip Total Data Count */
10938
10939     /* Build display for: Reserved2 */
10940
10941     Reserved2 = GSHORT(pd, offset);
10942
10943     if (tree) {
10944
10945       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
10946
10947     }
10948
10949     offset += 2; /* Skip Reserved2 */
10950
10951     /* Build display for: Parameter Count */
10952
10953     ParameterCount = GSHORT(pd, offset);
10954
10955     if (tree) {
10956
10957       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
10958
10959     }
10960
10961     offset += 2; /* Skip Parameter Count */
10962
10963     /* Build display for: Parameter Offset */
10964
10965     ParameterOffset = GSHORT(pd, offset);
10966
10967     if (tree) {
10968
10969       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
10970
10971     }
10972
10973     offset += 2; /* Skip Parameter Offset */
10974
10975     /* Build display for: Parameter Displacement */
10976
10977     ParameterDisplacement = GSHORT(pd, offset);
10978
10979     if (tree) {
10980
10981       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
10982
10983     }
10984
10985     offset += 2; /* Skip Parameter Displacement */
10986
10987     /* Build display for: Data Count */
10988
10989     DataCount = GSHORT(pd, offset);
10990
10991     if (tree) {
10992
10993       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
10994
10995     }
10996
10997     offset += 2; /* Skip Data Count */
10998
10999     /* Build display for: Data Offset */
11000
11001     DataOffset = GSHORT(pd, offset);
11002
11003     if (tree) {
11004
11005       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
11006
11007     }
11008
11009     offset += 2; /* Skip Data Offset */
11010
11011     /* Build display for: Data Displacement */
11012
11013     if (!BYTES_ARE_IN_FRAME(offset, 2))
11014       return;
11015
11016     DataDisplacement = GSHORT(pd, offset);
11017     si.ddisp = DataDisplacement;
11018
11019     if (tree) {
11020
11021       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
11022
11023     }
11024
11025     offset += 2; /* Skip Data Displacement */
11026
11027     /* Build display for: Setup Count */
11028
11029     SetupCount = GBYTE(pd, offset);
11030
11031     if (tree) {
11032
11033       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
11034
11035     }
11036
11037     offset += 1; /* Skip Setup Count */
11038
11039  
11040     /* Build display for: Reserved3 */
11041
11042     Reserved3 = GBYTE(pd, offset);
11043
11044     if (tree) {
11045
11046       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
11047
11048     }
11049
11050
11051     offset += 1; /* Skip Reserved3 */
11052  
11053     SetupAreaOffset = offset;   
11054
11055     /* Build display for: Setup */
11056
11057     if (SetupCount > 0) {
11058
11059       int i = SetupCount;
11060
11061       Setup = GSHORT(pd, offset);
11062
11063       for (i = 1; i <= SetupCount; i++) {
11064         
11065         Setup = GSHORT(pd, offset);
11066
11067         if (tree) {
11068
11069           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
11070
11071         }
11072
11073         offset += 2; /* Skip Setup */
11074
11075       }
11076
11077     }
11078
11079     /* Build display for: Byte Count (BCC) */
11080
11081     ByteCount = GSHORT(pd, offset);
11082
11083     if (tree) {
11084
11085       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
11086
11087     }
11088
11089     offset += 2; /* Skip Byte Count (BCC) */
11090
11091     /* Build display for: Pad1 */
11092
11093     if (offset < (SMB_offset + ParameterOffset)) {
11094
11095       int pad1Count = SMB_offset + ParameterOffset - offset;
11096
11097       /* Build display for: Pad1 */
11098
11099       if (tree) {
11100
11101         proto_tree_add_text(tree, NullTVB, offset, pad1Count, "Pad1: %s",
11102                             bytes_to_str(pd + offset, pad1Count));
11103       }
11104
11105       offset += pad1Count; /* Skip Pad1 */
11106
11107     }
11108
11109     if (request_val != NULL)
11110       TransactName = request_val -> last_transact_command;
11111     else
11112       TransactName = NULL;
11113
11114     /*
11115      * Make an entry for this, if it's continued; get the entry for
11116      * the message of which it's a continuation, and get the transaction
11117      * name for that message, if it's a continuation.
11118      *
11119      * XXX - eventually, do reassembly of all the continuations, so
11120      * we can dissect the entire reply.
11121      */
11122     si.continuation_val = do_continuation_hashing(conversation, si, fd,
11123                                                   TotalDataCount, DataCount,
11124                                                   &TransactName);
11125     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data,
11126                             SMB_offset, DataOffset, DataCount,
11127                             ParameterOffset, ParameterCount,
11128                             SetupAreaOffset, SetupCount, TransactName);
11129
11130   }
11131
11132 }
11133
11134
11135
11136
11137
11138 static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int) = {
11139
11140   dissect_createdir_smb,    /* unknown SMB 0x00 */
11141   dissect_deletedir_smb,    /* unknown SMB 0x01 */
11142   dissect_unknown_smb,      /* SMBopen open a file */
11143   dissect_create_file_smb,  /* SMBcreate create a file */
11144   dissect_close_smb,        /* SMBclose close a file */
11145   dissect_flush_file_smb,   /* SMBflush flush a file */
11146   dissect_delete_file_smb,  /* SMBunlink delete a file */
11147   dissect_rename_file_smb,  /* SMBmv rename a file */
11148   dissect_get_file_attr_smb,/* SMBgetatr get file attributes */
11149   dissect_set_file_attr_smb,/* SMBsetatr set file attributes */
11150   dissect_read_file_smb,    /* SMBread read from a file */
11151   dissect_write_file_smb,   /* SMBwrite write to a file */
11152   dissect_lock_bytes_smb,   /* SMBlock lock a byte range */
11153   dissect_unlock_bytes_smb, /* SMBunlock unlock a byte range */
11154   dissect_create_temporary_file_smb,/* SMBctemp create a temporary file */
11155   dissect_unknown_smb,      /* SMBmknew make a new file */
11156   dissect_checkdir_smb,     /* SMBchkpth check a directory path */
11157   dissect_process_exit_smb,      /* SMBexit process exit */
11158   dissect_unknown_smb,      /* SMBlseek seek */
11159   dissect_lock_and_read_smb,/* SMBlockread Lock a range and read it */
11160   dissect_write_and_unlock_smb,/* SMBwriteunlock Unlock a range and then write */
11161   dissect_unknown_smb,      /* unknown SMB 0x15 */
11162   dissect_unknown_smb,      /* unknown SMB 0x16 */
11163   dissect_unknown_smb,      /* unknown SMB 0x17 */
11164   dissect_unknown_smb,      /* unknown SMB 0x18 */
11165   dissect_unknown_smb,      /* unknown SMB 0x19 */
11166   dissect_read_raw_smb,     /* SMBreadBraw read block raw */
11167   dissect_read_mpx_smb,     /* SMBreadBmpx read block multiplexed */
11168   dissect_unknown_smb,      /* SMBreadBs read block (secondary response) */
11169   dissect_write_raw_smb,    /* SMBwriteBraw write block raw */
11170   dissect_write_mpx_smb,    /* SMBwriteBmpx write block multiplexed */
11171   dissect_unknown_smb,      /* SMBwriteBs write block (secondary request) */
11172   dissect_unknown_smb,      /* SMBwriteC write complete response */
11173   dissect_unknown_smb,      /* unknown SMB 0x21 */
11174   dissect_set_info2_smb,    /* SMBsetattrE set file attributes expanded */
11175   dissect_query_info2_smb,  /* SMBgetattrE get file attributes expanded */
11176   dissect_locking_andx_smb, /* SMBlockingX lock/unlock byte ranges and X */
11177   dissect_transact_smb,      /* SMBtrans transaction - name, bytes in/out */
11178   dissect_unknown_smb,      /* SMBtranss transaction (secondary request/response) */
11179   dissect_unknown_smb,      /* SMBioctl IOCTL */
11180   dissect_unknown_smb,      /* SMBioctls IOCTL (secondary request/response) */
11181   dissect_unknown_smb,      /* SMBcopy copy */
11182   dissect_move_smb,      /* SMBmove move */
11183   dissect_unknown_smb,      /* SMBecho echo */
11184   dissect_unknown_smb,      /* SMBwriteclose write a file and then close it */
11185   dissect_open_andx_smb,      /* SMBopenX open and X */
11186   dissect_read_andx_smb,    /* SMBreadX read and X */
11187   dissect_unknown_smb,      /* SMBwriteX write and X */
11188   dissect_unknown_smb,      /* unknown SMB 0x30 */
11189   dissect_unknown_smb,      /* unknown SMB 0x31 */
11190   dissect_transact2_smb,    /* unknown SMB 0x32 */
11191   dissect_unknown_smb,      /* unknown SMB 0x33 */
11192   dissect_find_close2_smb,  /* unknown SMB 0x34 */
11193   dissect_unknown_smb,      /* unknown SMB 0x35 */
11194   dissect_unknown_smb,      /* unknown SMB 0x36 */
11195   dissect_unknown_smb,      /* unknown SMB 0x37 */
11196   dissect_unknown_smb,      /* unknown SMB 0x38 */
11197   dissect_unknown_smb,      /* unknown SMB 0x39 */
11198   dissect_unknown_smb,      /* unknown SMB 0x3a */
11199   dissect_unknown_smb,      /* unknown SMB 0x3b */
11200   dissect_unknown_smb,      /* unknown SMB 0x3c */
11201   dissect_unknown_smb,      /* unknown SMB 0x3d */
11202   dissect_unknown_smb,      /* unknown SMB 0x3e */
11203   dissect_unknown_smb,      /* unknown SMB 0x3f */
11204   dissect_unknown_smb,      /* unknown SMB 0x40 */
11205   dissect_unknown_smb,      /* unknown SMB 0x41 */
11206   dissect_unknown_smb,      /* unknown SMB 0x42 */
11207   dissect_unknown_smb,      /* unknown SMB 0x43 */
11208   dissect_unknown_smb,      /* unknown SMB 0x44 */
11209   dissect_unknown_smb,      /* unknown SMB 0x45 */
11210   dissect_unknown_smb,      /* unknown SMB 0x46 */
11211   dissect_unknown_smb,      /* unknown SMB 0x47 */
11212   dissect_unknown_smb,      /* unknown SMB 0x48 */
11213   dissect_unknown_smb,      /* unknown SMB 0x49 */
11214   dissect_unknown_smb,      /* unknown SMB 0x4a */
11215   dissect_unknown_smb,      /* unknown SMB 0x4b */
11216   dissect_unknown_smb,      /* unknown SMB 0x4c */
11217   dissect_unknown_smb,      /* unknown SMB 0x4d */
11218   dissect_unknown_smb,      /* unknown SMB 0x4e */
11219   dissect_unknown_smb,      /* unknown SMB 0x4f */
11220   dissect_unknown_smb,      /* unknown SMB 0x50 */
11221   dissect_unknown_smb,      /* unknown SMB 0x51 */
11222   dissect_unknown_smb,      /* unknown SMB 0x52 */
11223   dissect_unknown_smb,      /* unknown SMB 0x53 */
11224   dissect_unknown_smb,      /* unknown SMB 0x54 */
11225   dissect_unknown_smb,      /* unknown SMB 0x55 */
11226   dissect_unknown_smb,      /* unknown SMB 0x56 */
11227   dissect_unknown_smb,      /* unknown SMB 0x57 */
11228   dissect_unknown_smb,      /* unknown SMB 0x58 */
11229   dissect_unknown_smb,      /* unknown SMB 0x59 */
11230   dissect_unknown_smb,      /* unknown SMB 0x5a */
11231   dissect_unknown_smb,      /* unknown SMB 0x5b */
11232   dissect_unknown_smb,      /* unknown SMB 0x5c */
11233   dissect_unknown_smb,      /* unknown SMB 0x5d */
11234   dissect_unknown_smb,      /* unknown SMB 0x5e */
11235   dissect_unknown_smb,      /* unknown SMB 0x5f */
11236   dissect_unknown_smb,      /* unknown SMB 0x60 */
11237   dissect_unknown_smb,      /* unknown SMB 0x61 */
11238   dissect_unknown_smb,      /* unknown SMB 0x62 */
11239   dissect_unknown_smb,      /* unknown SMB 0x63 */
11240   dissect_unknown_smb,      /* unknown SMB 0x64 */
11241   dissect_unknown_smb,      /* unknown SMB 0x65 */
11242   dissect_unknown_smb,      /* unknown SMB 0x66 */
11243   dissect_unknown_smb,      /* unknown SMB 0x67 */
11244   dissect_unknown_smb,      /* unknown SMB 0x68 */
11245   dissect_unknown_smb,      /* unknown SMB 0x69 */
11246   dissect_unknown_smb,      /* unknown SMB 0x6a */
11247   dissect_unknown_smb,      /* unknown SMB 0x6b */
11248   dissect_unknown_smb,      /* unknown SMB 0x6c */
11249   dissect_unknown_smb,      /* unknown SMB 0x6d */
11250   dissect_unknown_smb,      /* unknown SMB 0x6e */
11251   dissect_unknown_smb,      /* unknown SMB 0x6f */
11252   dissect_treecon_smb,      /* SMBtcon tree connect */
11253   dissect_tdis_smb,         /* SMBtdis tree disconnect */
11254   dissect_negprot_smb,      /* SMBnegprot negotiate a protocol */
11255   dissect_ssetup_andx_smb,  /* SMBsesssetupX Session Set Up & X (including User Logon) */
11256   dissect_logoff_andx_smb,  /* SMBlogof Logoff & X */
11257   dissect_tcon_andx_smb,    /* SMBtconX tree connect and X */
11258   dissect_unknown_smb,      /* unknown SMB 0x76 */
11259   dissect_unknown_smb,      /* unknown SMB 0x77 */
11260   dissect_unknown_smb,      /* unknown SMB 0x78 */
11261   dissect_unknown_smb,      /* unknown SMB 0x79 */
11262   dissect_unknown_smb,      /* unknown SMB 0x7a */
11263   dissect_unknown_smb,      /* unknown SMB 0x7b */
11264   dissect_unknown_smb,      /* unknown SMB 0x7c */
11265   dissect_unknown_smb,      /* unknown SMB 0x7d */
11266   dissect_unknown_smb,      /* unknown SMB 0x7e */
11267   dissect_unknown_smb,      /* unknown SMB 0x7f */
11268   dissect_get_disk_attr_smb,/* SMBdskattr get disk attributes */
11269   dissect_search_dir_smb,   /* SMBsearch search a directory */
11270   dissect_unknown_smb,      /* SMBffirst find first */
11271   dissect_unknown_smb,      /* SMBfunique find unique */
11272   dissect_unknown_smb,      /* SMBfclose find close */
11273   dissect_unknown_smb,      /* unknown SMB 0x85 */
11274   dissect_unknown_smb,      /* unknown SMB 0x86 */
11275   dissect_unknown_smb,      /* unknown SMB 0x87 */
11276   dissect_unknown_smb,      /* unknown SMB 0x88 */
11277   dissect_unknown_smb,      /* unknown SMB 0x89 */
11278   dissect_unknown_smb,      /* unknown SMB 0x8a */
11279   dissect_unknown_smb,      /* unknown SMB 0x8b */
11280   dissect_unknown_smb,      /* unknown SMB 0x8c */
11281   dissect_unknown_smb,      /* unknown SMB 0x8d */
11282   dissect_unknown_smb,      /* unknown SMB 0x8e */
11283   dissect_unknown_smb,      /* unknown SMB 0x8f */
11284   dissect_unknown_smb,      /* unknown SMB 0x90 */
11285   dissect_unknown_smb,      /* unknown SMB 0x91 */
11286   dissect_unknown_smb,      /* unknown SMB 0x92 */
11287   dissect_unknown_smb,      /* unknown SMB 0x93 */
11288   dissect_unknown_smb,      /* unknown SMB 0x94 */
11289   dissect_unknown_smb,      /* unknown SMB 0x95 */
11290   dissect_unknown_smb,      /* unknown SMB 0x96 */
11291   dissect_unknown_smb,      /* unknown SMB 0x97 */
11292   dissect_unknown_smb,      /* unknown SMB 0x98 */
11293   dissect_unknown_smb,      /* unknown SMB 0x99 */
11294   dissect_unknown_smb,      /* unknown SMB 0x9a */
11295   dissect_unknown_smb,      /* unknown SMB 0x9b */
11296   dissect_unknown_smb,      /* unknown SMB 0x9c */
11297   dissect_unknown_smb,      /* unknown SMB 0x9d */
11298   dissect_unknown_smb,      /* unknown SMB 0x9e */
11299   dissect_unknown_smb,      /* unknown SMB 0x9f */
11300   dissect_unknown_smb,      /* unknown SMB 0xa0 */
11301   dissect_unknown_smb,      /* unknown SMB 0xa1 */
11302   dissect_unknown_smb,      /* unknown SMB 0xa2 */
11303   dissect_unknown_smb,      /* unknown SMB 0xa3 */
11304   dissect_unknown_smb,      /* unknown SMB 0xa4 */
11305   dissect_unknown_smb,      /* unknown SMB 0xa5 */
11306   dissect_unknown_smb,      /* unknown SMB 0xa6 */
11307   dissect_unknown_smb,      /* unknown SMB 0xa7 */
11308   dissect_unknown_smb,      /* unknown SMB 0xa8 */
11309   dissect_unknown_smb,      /* unknown SMB 0xa9 */
11310   dissect_unknown_smb,      /* unknown SMB 0xaa */
11311   dissect_unknown_smb,      /* unknown SMB 0xab */
11312   dissect_unknown_smb,      /* unknown SMB 0xac */
11313   dissect_unknown_smb,      /* unknown SMB 0xad */
11314   dissect_unknown_smb,      /* unknown SMB 0xae */
11315   dissect_unknown_smb,      /* unknown SMB 0xaf */
11316   dissect_unknown_smb,      /* unknown SMB 0xb0 */
11317   dissect_unknown_smb,      /* unknown SMB 0xb1 */
11318   dissect_unknown_smb,      /* unknown SMB 0xb2 */
11319   dissect_unknown_smb,      /* unknown SMB 0xb3 */
11320   dissect_unknown_smb,      /* unknown SMB 0xb4 */
11321   dissect_unknown_smb,      /* unknown SMB 0xb5 */
11322   dissect_unknown_smb,      /* unknown SMB 0xb6 */
11323   dissect_unknown_smb,      /* unknown SMB 0xb7 */
11324   dissect_unknown_smb,      /* unknown SMB 0xb8 */
11325   dissect_unknown_smb,      /* unknown SMB 0xb9 */
11326   dissect_unknown_smb,      /* unknown SMB 0xba */
11327   dissect_unknown_smb,      /* unknown SMB 0xbb */
11328   dissect_unknown_smb,      /* unknown SMB 0xbc */
11329   dissect_unknown_smb,      /* unknown SMB 0xbd */
11330   dissect_unknown_smb,      /* unknown SMB 0xbe */
11331   dissect_unknown_smb,      /* unknown SMB 0xbf */
11332   dissect_unknown_smb,      /* SMBsplopen open a print spool file */
11333   dissect_write_print_file_smb,/* SMBsplwr write to a print spool file */
11334   dissect_close_print_file_smb,/* SMBsplclose close a print spool file */
11335   dissect_get_print_queue_smb, /* SMBsplretq return print queue */
11336   dissect_unknown_smb,      /* unknown SMB 0xc4 */
11337   dissect_unknown_smb,      /* unknown SMB 0xc5 */
11338   dissect_unknown_smb,      /* unknown SMB 0xc6 */
11339   dissect_unknown_smb,      /* unknown SMB 0xc7 */
11340   dissect_unknown_smb,      /* unknown SMB 0xc8 */
11341   dissect_unknown_smb,      /* unknown SMB 0xc9 */
11342   dissect_unknown_smb,      /* unknown SMB 0xca */
11343   dissect_unknown_smb,      /* unknown SMB 0xcb */
11344   dissect_unknown_smb,      /* unknown SMB 0xcc */
11345   dissect_unknown_smb,      /* unknown SMB 0xcd */
11346   dissect_unknown_smb,      /* unknown SMB 0xce */
11347   dissect_unknown_smb,      /* unknown SMB 0xcf */
11348   dissect_unknown_smb,      /* SMBsends send a single block message */
11349   dissect_unknown_smb,      /* SMBsendb send a broadcast message */
11350   dissect_unknown_smb,      /* SMBfwdname forward user name */
11351   dissect_unknown_smb,      /* SMBcancelf cancel forward */
11352   dissect_unknown_smb,      /* SMBgetmac get a machine name */
11353   dissect_unknown_smb,      /* SMBsendstrt send start of multi-block message */
11354   dissect_unknown_smb,      /* SMBsendend send end of multi-block message */
11355   dissect_unknown_smb,      /* SMBsendtxt send text of multi-block message */
11356   dissect_unknown_smb,      /* unknown SMB 0xd8 */
11357   dissect_unknown_smb,      /* unknown SMB 0xd9 */
11358   dissect_unknown_smb,      /* unknown SMB 0xda */
11359   dissect_unknown_smb,      /* unknown SMB 0xdb */
11360   dissect_unknown_smb,      /* unknown SMB 0xdc */
11361   dissect_unknown_smb,      /* unknown SMB 0xdd */
11362   dissect_unknown_smb,      /* unknown SMB 0xde */
11363   dissect_unknown_smb,      /* unknown SMB 0xdf */
11364   dissect_unknown_smb,      /* unknown SMB 0xe0 */
11365   dissect_unknown_smb,      /* unknown SMB 0xe1 */
11366   dissect_unknown_smb,      /* unknown SMB 0xe2 */
11367   dissect_unknown_smb,      /* unknown SMB 0xe3 */
11368   dissect_unknown_smb,      /* unknown SMB 0xe4 */
11369   dissect_unknown_smb,      /* unknown SMB 0xe5 */
11370   dissect_unknown_smb,      /* unknown SMB 0xe6 */
11371   dissect_unknown_smb,      /* unknown SMB 0xe7 */
11372   dissect_unknown_smb,      /* unknown SMB 0xe8 */
11373   dissect_unknown_smb,      /* unknown SMB 0xe9 */
11374   dissect_unknown_smb,      /* unknown SMB 0xea */
11375   dissect_unknown_smb,      /* unknown SMB 0xeb */
11376   dissect_unknown_smb,      /* unknown SMB 0xec */
11377   dissect_unknown_smb,      /* unknown SMB 0xed */
11378   dissect_unknown_smb,      /* unknown SMB 0xee */
11379   dissect_unknown_smb,      /* unknown SMB 0xef */
11380   dissect_unknown_smb,      /* unknown SMB 0xf0 */
11381   dissect_unknown_smb,      /* unknown SMB 0xf1 */
11382   dissect_unknown_smb,      /* unknown SMB 0xf2 */
11383   dissect_unknown_smb,      /* unknown SMB 0xf3 */
11384   dissect_unknown_smb,      /* unknown SMB 0xf4 */
11385   dissect_unknown_smb,      /* unknown SMB 0xf5 */
11386   dissect_unknown_smb,      /* unknown SMB 0xf6 */
11387   dissect_unknown_smb,      /* unknown SMB 0xf7 */
11388   dissect_unknown_smb,      /* unknown SMB 0xf8 */
11389   dissect_unknown_smb,      /* unknown SMB 0xf9 */
11390   dissect_unknown_smb,      /* unknown SMB 0xfa */
11391   dissect_unknown_smb,      /* unknown SMB 0xfb */
11392   dissect_unknown_smb,      /* unknown SMB 0xfc */
11393   dissect_unknown_smb,      /* unknown SMB 0xfd */
11394   dissect_unknown_smb,      /* SMBinvalid invalid command */
11395   dissect_unknown_smb       /* unknown SMB 0xff */
11396
11397 };
11398
11399 static const value_string errcls_types[] = {
11400   { SMB_SUCCESS, "Success"},
11401   { SMB_ERRDOS, "DOS Error"},
11402   { SMB_ERRSRV, "Server Error"},
11403   { SMB_ERRHRD, "Hardware Error"},
11404   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
11405   { 0, NULL }
11406 };
11407
11408 char *decode_smb_name(unsigned char cmd)
11409 {
11410
11411   return(SMB_names[cmd]);
11412
11413 }
11414
11415 static const value_string DOS_errors[] = {
11416   {SMBE_badfunc, "Invalid function (or system call)"},
11417   {SMBE_badfile, "File not found (pathname error)"},
11418   {SMBE_badpath, "Directory not found"},
11419   {SMBE_nofids, "Too many open files"},
11420   {SMBE_noaccess, "Access denied"},
11421   {SMBE_badfid, "Invalid fid"},
11422   {SMBE_nomem,  "Out of memory"},
11423   {SMBE_badmem, "Invalid memory block address"},
11424   {SMBE_badenv, "Invalid environment"},
11425   {SMBE_badaccess, "Invalid open mode"},
11426   {SMBE_baddata, "Invalid data (only from ioctl call)"},
11427   {SMBE_res, "Reserved error code?"}, 
11428   {SMBE_baddrive, "Invalid drive"},
11429   {SMBE_remcd, "Attempt to delete current directory"},
11430   {SMBE_diffdevice, "Rename/move across different filesystems"},
11431   {SMBE_nofiles, "no more files found in file search"},
11432   {SMBE_badshare, "Share mode on file conflict with open mode"},
11433   {SMBE_lock, "Lock request conflicts with existing lock"},
11434   {SMBE_unsup, "Request unsupported, returned by Win 95"},
11435   {SMBE_nosuchshare, "Requested share does not exist"},
11436   {SMBE_filexists, "File in operation already exists"},
11437   {SMBE_cannotopen, "Cannot open the file specified"},
11438   {SMBE_unknownlevel, "Unknown level??"},
11439   {SMBE_badpipe, "Named pipe invalid"},
11440   {SMBE_pipebusy, "All instances of pipe are busy"},
11441   {SMBE_pipeclosing, "Named pipe close in progress"},
11442   {SMBE_notconnected, "No process on other end of named pipe"},
11443   {SMBE_moredata, "More data to be returned"},
11444   {SMBE_baddirectory,  "Invalid directory name in a path."},
11445   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
11446   {SMBE_eas_nsup, "Extended attributes not supported"},
11447   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
11448   {SMBE_unknownipc, "Unknown IPC Operation"},
11449   {SMBE_noipc, "Don't support ipc"},
11450   {0, NULL}
11451   };
11452
11453 /* Error codes for the ERRSRV class */
11454
11455 static const value_string SRV_errors[] = {
11456   {SMBE_error, "Non specific error code"},
11457   {SMBE_badpw, "Bad password"},
11458   {SMBE_badtype, "Reserved"},
11459   {SMBE_access, "No permissions to perform the requested operation"},
11460   {SMBE_invnid, "TID invalid"},
11461   {SMBE_invnetname, "Invalid network name. Service not found"},
11462   {SMBE_invdevice, "Invalid device"},
11463   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
11464   {SMBE_qfull, "Print queue full"},
11465   {SMBE_qtoobig, "Queued item too big"},
11466   {SMBE_qeof, "EOF on print queue dump"},
11467   {SMBE_invpfid, "Invalid print file in smb_fid"},
11468   {SMBE_smbcmd, "Unrecognised command"},
11469   {SMBE_srverror, "SMB server internal error"},
11470   {SMBE_filespecs, "Fid and pathname invalid combination"},
11471   {SMBE_badlink, "Bad link in request ???"},
11472   {SMBE_badpermits, "Access specified for a file is not valid"},
11473   {SMBE_badpid, "Bad process id in request"},
11474   {SMBE_setattrmode, "Attribute mode invalid"},
11475   {SMBE_paused, "Message server paused"},
11476   {SMBE_msgoff, "Not receiving messages"},
11477   {SMBE_noroom, "No room for message"},
11478   {SMBE_rmuns, "Too many remote usernames"},
11479   {SMBE_timeout, "Operation timed out"},
11480   {SMBE_noresource, "No resources currently available for request."},
11481   {SMBE_toomanyuids, "Too many userids"},
11482   {SMBE_baduid, "Bad userid"},
11483   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
11484   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
11485   {SMBE_contMPX, "Resume MPX mode"},
11486   {SMBE_badPW, "Bad Password???"},
11487   {SMBE_nosupport, "Operation not supported"},
11488   { 0, NULL}
11489 };
11490
11491 /* Error codes for the ERRHRD class */
11492
11493 static const value_string HRD_errors[] = {
11494   {SMBE_nowrite, "read only media"},
11495   {SMBE_badunit, "Unknown device"},
11496   {SMBE_notready, "Drive not ready"},
11497   {SMBE_badcmd, "Unknown command"},
11498   {SMBE_data, "Data (CRC) error"},
11499   {SMBE_badreq, "Bad request structure length"},
11500   {SMBE_seek, "Seek error???"},
11501   {SMBE_badmedia, "Bad media???"},
11502   {SMBE_badsector, "Bad sector???"},
11503   {SMBE_nopaper, "No paper in printer???"},
11504   {SMBE_write, "Write error???"},
11505   {SMBE_read, "Read error???"},
11506   {SMBE_general, "General error???"},
11507   {SMBE_badshare, "A open conflicts with an existing open"},
11508   {SMBE_lock, "Lock/unlock error"},
11509   {SMBE_wrongdisk,  "Wrong disk???"},
11510   {SMBE_FCBunavail, "FCB unavailable???"},
11511   {SMBE_sharebufexc, "Share buffer excluded???"},
11512   {SMBE_diskfull, "Disk full???"},
11513   {0, NULL}
11514 };
11515
11516 char *decode_smb_error(guint8 errcls, guint16 errcode)
11517 {
11518
11519   switch (errcls) {
11520
11521   case SMB_SUCCESS:
11522
11523     return("No Error");   /* No error ??? */
11524     break;
11525
11526   case SMB_ERRDOS:
11527
11528     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
11529     break;
11530
11531   case SMB_ERRSRV:
11532
11533     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
11534     break;
11535
11536   case SMB_ERRHRD:
11537
11538     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
11539     break;
11540
11541   default:
11542
11543     return("Unknown error class!");
11544
11545   }
11546
11547 }
11548
11549 /*
11550  * NT error codes.
11551  *
11552  * From
11553  *
11554  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
11555  */
11556 static const value_string NT_errors[] = {
11557   { 0x00000000, "STATUS_SUCCESS" },
11558   { 0x00000000, "STATUS_WAIT_0" },
11559   { 0x00000001, "STATUS_WAIT_1" },
11560   { 0x00000002, "STATUS_WAIT_2" },
11561   { 0x00000003, "STATUS_WAIT_3" },
11562   { 0x0000003F, "STATUS_WAIT_63" },
11563   { 0x00000080, "STATUS_ABANDONED" },
11564   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
11565   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
11566   { 0x000000C0, "STATUS_USER_APC" },
11567   { 0x00000100, "STATUS_KERNEL_APC" },
11568   { 0x00000101, "STATUS_ALERTED" },
11569   { 0x00000102, "STATUS_TIMEOUT" },
11570   { 0x00000103, "STATUS_PENDING" },
11571   { 0x00000104, "STATUS_REPARSE" },
11572   { 0x00000105, "STATUS_MORE_ENTRIES" },
11573   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
11574   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
11575   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
11576   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
11577   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
11578   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
11579   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
11580   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
11581   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
11582   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
11583   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
11584   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
11585   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
11586   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
11587   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
11588   { 0x00000116, "STATUS_CRASH_DUMP" },
11589   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
11590   { 0x00000118, "STATUS_REPARSE_OBJECT" },
11591   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
11592   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
11593   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
11594   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
11595   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
11596   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
11597   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
11598   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
11599   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
11600   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
11601   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
11602   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
11603   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
11604   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
11605   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
11606   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
11607   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
11608   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
11609   { 0x40000012, "STATUS_EVENT_DONE" },
11610   { 0x40000013, "STATUS_EVENT_PENDING" },
11611   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
11612   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
11613   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
11614   { 0x40000017, "STATUS_WAS_UNLOCKED" },
11615   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
11616   { 0x40000019, "STATUS_WAS_LOCKED" },
11617   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
11618   { 0x4000001B, "STATUS_ALREADY_WIN32" },
11619   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
11620   { 0x4000001D, "STATUS_WX86_CONTINUE" },
11621   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
11622   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
11623   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
11624   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
11625   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
11626   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
11627   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
11628   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
11629   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
11630   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
11631   { 0x80000003, "STATUS_BREAKPOINT" },
11632   { 0x80000004, "STATUS_SINGLE_STEP" },
11633   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
11634   { 0x80000006, "STATUS_NO_MORE_FILES" },
11635   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
11636   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
11637   { 0x8000000B, "STATUS_NO_INHERITANCE" },
11638   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
11639   { 0x8000000D, "STATUS_PARTIAL_COPY" },
11640   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
11641   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
11642   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
11643   { 0x80000011, "STATUS_DEVICE_BUSY" },
11644   { 0x80000012, "STATUS_NO_MORE_EAS" },
11645   { 0x80000013, "STATUS_INVALID_EA_NAME" },
11646   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
11647   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
11648   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
11649   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
11650   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
11651   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
11652   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
11653   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
11654   { 0x8000001D, "STATUS_BUS_RESET" },
11655   { 0x8000001E, "STATUS_END_OF_MEDIA" },
11656   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
11657   { 0x80000020, "STATUS_MEDIA_CHECK" },
11658   { 0x80000021, "STATUS_SETMARK_DETECTED" },
11659   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
11660   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
11661   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
11662   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
11663   { 0x80000026, "STATUS_LONGJUMP" },
11664   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
11665   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
11666   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
11667   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
11668   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
11669   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
11670   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
11671   { 0xC0000008, "STATUS_INVALID_HANDLE" },
11672   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
11673   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
11674   { 0xC000000B, "STATUS_INVALID_CID" },
11675   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
11676   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
11677   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
11678   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
11679   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
11680   { 0xC0000011, "STATUS_END_OF_FILE" },
11681   { 0xC0000012, "STATUS_WRONG_VOLUME" },
11682   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
11683   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
11684   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
11685   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
11686   { 0xC0000017, "STATUS_NO_MEMORY" },
11687   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
11688   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
11689   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
11690   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
11691   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
11692   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
11693   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
11694   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
11695   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
11696   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
11697   { 0xC0000022, "STATUS_ACCESS_DENIED" },
11698   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
11699   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
11700   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
11701   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
11702   { 0xC0000027, "STATUS_UNWIND" },
11703   { 0xC0000028, "STATUS_BAD_STACK" },
11704   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
11705   { 0xC000002A, "STATUS_NOT_LOCKED" },
11706   { 0xC000002B, "STATUS_PARITY_ERROR" },
11707   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
11708   { 0xC000002D, "STATUS_NOT_COMMITTED" },
11709   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
11710   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
11711   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
11712   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
11713   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
11714   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
11715   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
11716   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
11717   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
11718   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
11719   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
11720   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
11721   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
11722   { 0xC000003C, "STATUS_DATA_OVERRUN" },
11723   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
11724   { 0xC000003E, "STATUS_DATA_ERROR" },
11725   { 0xC000003F, "STATUS_CRC_ERROR" },
11726   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
11727   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
11728   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
11729   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
11730   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
11731   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
11732   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
11733   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
11734   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
11735   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
11736   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
11737   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
11738   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
11739   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
11740   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
11741   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
11742   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
11743   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
11744   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
11745   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
11746   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
11747   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
11748   { 0xC0000056, "STATUS_DELETE_PENDING" },
11749   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
11750   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
11751   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
11752   { 0xC000005A, "STATUS_INVALID_OWNER" },
11753   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
11754   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
11755   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
11756   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
11757   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
11758   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
11759   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
11760   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
11761   { 0xC0000063, "STATUS_USER_EXISTS" },
11762   { 0xC0000064, "STATUS_NO_SUCH_USER" },
11763   { 0xC0000065, "STATUS_GROUP_EXISTS" },
11764   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
11765   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
11766   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
11767   { 0xC0000069, "STATUS_LAST_ADMIN" },
11768   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
11769   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
11770   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
11771   { 0xC000006D, "STATUS_LOGON_FAILURE" },
11772   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
11773   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
11774   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
11775   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
11776   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
11777   { 0xC0000073, "STATUS_NONE_MAPPED" },
11778   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
11779   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
11780   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
11781   { 0xC0000077, "STATUS_INVALID_ACL" },
11782   { 0xC0000078, "STATUS_INVALID_SID" },
11783   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
11784   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
11785   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
11786   { 0xC000007C, "STATUS_NO_TOKEN" },
11787   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
11788   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
11789   { 0xC000007F, "STATUS_DISK_FULL" },
11790   { 0xC0000080, "STATUS_SERVER_DISABLED" },
11791   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
11792   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
11793   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
11794   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
11795   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
11796   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
11797   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
11798   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
11799   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
11800   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
11801   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
11802   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
11803   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
11804   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
11805   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
11806   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
11807   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
11808   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
11809   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
11810   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
11811   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
11812   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
11813   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
11814   { 0xC0000098, "STATUS_FILE_INVALID" },
11815   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
11816   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
11817   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
11818   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
11819   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
11820   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
11821   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
11822   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
11823   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
11824   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
11825   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
11826   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
11827   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
11828   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
11829   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
11830   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
11831   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
11832   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
11833   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
11834   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
11835   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
11836   { 0xC00000AE, "STATUS_PIPE_BUSY" },
11837   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
11838   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
11839   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
11840   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
11841   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
11842   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
11843   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
11844   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
11845   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
11846   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
11847   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
11848   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
11849   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
11850   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
11851   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
11852   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
11853   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
11854   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
11855   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
11856   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
11857   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
11858   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
11859   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
11860   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
11861   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
11862   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
11863   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
11864   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
11865   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
11866   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
11867   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
11868   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
11869   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
11870   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
11871   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
11872   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
11873   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
11874   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
11875   { 0xC00000D5, "STATUS_FILE_RENAMED" },
11876   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
11877   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
11878   { 0xC00000D8, "STATUS_CANT_WAIT" },
11879   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
11880   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
11881   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
11882   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
11883   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
11884   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
11885   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
11886   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
11887   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
11888   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
11889   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
11890   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
11891   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
11892   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
11893   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
11894   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
11895   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
11896   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
11897   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
11898   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
11899   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
11900   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
11901   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
11902   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
11903   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
11904   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
11905   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
11906   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
11907   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
11908   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
11909   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
11910   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
11911   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
11912   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
11913   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
11914   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
11915   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
11916   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
11917   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
11918   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
11919   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
11920   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
11921   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
11922   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
11923   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
11924   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
11925   { 0xC0000107, "STATUS_FILES_OPEN" },
11926   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
11927   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
11928   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
11929   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
11930   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
11931   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
11932   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
11933   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
11934   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
11935   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
11936   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
11937   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
11938   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
11939   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
11940   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
11941   { 0xC0000117, "STATUS_NO_LDT" },
11942   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
11943   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
11944   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
11945   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
11946   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
11947   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
11948   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
11949   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
11950   { 0xC0000120, "STATUS_CANCELLED" },
11951   { 0xC0000121, "STATUS_CANNOT_DELETE" },
11952   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
11953   { 0xC0000123, "STATUS_FILE_DELETED" },
11954   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
11955   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
11956   { 0xC0000126, "STATUS_SPECIAL_USER" },
11957   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
11958   { 0xC0000128, "STATUS_FILE_CLOSED" },
11959   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
11960   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
11961   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
11962   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
11963   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
11964   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
11965   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
11966   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
11967   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
11968   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
11969   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
11970   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
11971   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
11972   { 0xC0000136, "STATUS_OPEN_FAILED" },
11973   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
11974   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
11975   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
11976   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
11977   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
11978   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
11979   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
11980   { 0xC000013E, "STATUS_LINK_FAILED" },
11981   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
11982   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
11983   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
11984   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
11985   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
11986   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
11987   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
11988   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
11989   { 0xC0000147, "STATUS_NO_PAGEFILE" },
11990   { 0xC0000148, "STATUS_INVALID_LEVEL" },
11991   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
11992   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
11993   { 0xC000014B, "STATUS_PIPE_BROKEN" },
11994   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
11995   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
11996   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
11997   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
11998   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
11999   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
12000   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
12001   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
12002   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
12003   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
12004   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
12005   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
12006   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
12007   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
12008   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
12009   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
12010   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
12011   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
12012   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
12013   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
12014   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
12015   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
12016   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
12017   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
12018   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
12019   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
12020   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
12021   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
12022   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
12023   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
12024   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
12025   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
12026   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
12027   { 0xC000016D, "STATUS_FT_ORPHANING" },
12028   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
12029   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
12030   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
12031   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
12032   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
12033   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
12034   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
12035   { 0xC0000178, "STATUS_NO_MEDIA" },
12036   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
12037   { 0xC000017B, "STATUS_INVALID_MEMBER" },
12038   { 0xC000017C, "STATUS_KEY_DELETED" },
12039   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
12040   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
12041   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
12042   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
12043   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
12044   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
12045   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
12046   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
12047   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
12048   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
12049   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
12050   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
12051   { 0xC0000189, "STATUS_TOO_LATE" },
12052   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
12053   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
12054   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
12055   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
12056   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
12057   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
12058   { 0xC0000190, "STATUS_TRUST_FAILURE" },
12059   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
12060   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
12061   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
12062   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
12063   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
12064   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
12065   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
12066   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
12067   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
12068   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
12069   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
12070   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
12071   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
12072   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
12073   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
12074   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
12075   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
12076   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
12077   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
12078   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
12079   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
12080   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
12081   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
12082   { 0xC000020D, "STATUS_CONNECTION_RESET" },
12083   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
12084   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
12085   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
12086   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
12087   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
12088   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
12089   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
12090   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
12091   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
12092   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
12093   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
12094   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
12095   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
12096   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
12097   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
12098   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
12099   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
12100   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
12101   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
12102   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
12103   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
12104   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
12105   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
12106   { 0xC0000225, "STATUS_NOT_FOUND" },
12107   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
12108   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
12109   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
12110   { 0xC0000229, "STATUS_FAIL_CHECK" },
12111   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
12112   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
12113   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
12114   { 0xC000022D, "STATUS_RETRY" },
12115   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
12116   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
12117   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
12118   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
12119   { 0xC0000232, "STATUS_INVALID_VARIANT" },
12120   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
12121   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
12122   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
12123   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
12124   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
12125   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
12126   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
12127   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
12128   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
12129   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
12130   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
12131   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
12132   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
12133   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
12134   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
12135   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
12136   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
12137   { 0xC0000244, "STATUS_AUDIT_FAILED" },
12138   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
12139   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
12140   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
12141   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
12142   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
12143   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
12144   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
12145   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
12146   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
12147   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
12148   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
12149   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
12150   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
12151   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
12152   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
12153   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
12154   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
12155   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
12156   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
12157   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
12158   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
12159   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
12160   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
12161   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
12162   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
12163   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
12164   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
12165   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
12166   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
12167   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
12168   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
12169   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
12170   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
12171   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
12172   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
12173   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
12174   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
12175   { 0xC0009898, "STATUS_WOW_ASSERTION" },
12176   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
12177   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
12178   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
12179   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
12180   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
12181   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
12182   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
12183   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
12184   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
12185   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
12186   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
12187   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
12188   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
12189   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
12190   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
12191   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
12192   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
12193   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
12194   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
12195   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
12196   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
12197   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
12198   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
12199   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
12200   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
12201   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
12202   { 0xC002001B, "RPC_NT_CALL_FAILED" },
12203   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
12204   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
12205   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
12206   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
12207   { 0xC0020022, "RPC_NT_INVALID_TAG" },
12208   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
12209   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
12210   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
12211   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
12212   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
12213   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
12214   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
12215   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
12216   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
12217   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
12218   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
12219   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
12220   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
12221   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
12222   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
12223   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
12224   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
12225   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
12226   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
12227   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
12228   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
12229   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
12230   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
12231   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
12232   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
12233   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
12234   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
12235   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
12236   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
12237   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
12238   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
12239   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
12240   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
12241   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
12242   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
12243   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
12244   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
12245   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
12246   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
12247   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
12248   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
12249   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
12250   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
12251   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
12252   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
12253   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
12254   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
12255   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
12256   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
12257   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
12258   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
12259   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
12260   { 0xC002004C, "EPT_NT_CANT_CREATE" },
12261   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
12262   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
12263   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
12264   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
12265   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
12266   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
12267   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
12268   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
12269   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
12270   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
12271   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
12272   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
12273   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
12274   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
12275   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
12276   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
12277   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
12278   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
12279   { 0,          NULL }
12280 };
12281
12282 #define SMB_FLAGS_DIRN 0x80
12283
12284 static gboolean
12285 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
12286 {
12287         int             offset = 0;
12288         struct          smb_info si;
12289         static const char smb_signature[4] = { 0xFF, 'S', 'M', 'B' };
12290         proto_tree      *smb_tree = tree, *smb_hdr_tree = NULL, *flags_tree, *flags2_tree;
12291         proto_item      *ti, *tf, *th;
12292         guint8          cmd, errcls, errcode1, flags;
12293         guint16         flags2, errcode, tid, pid, uid, mid;
12294         guint32         status;
12295         const u_char    *pd;
12296         int             SMB_offset;
12297
12298         /* OK, is this an SMB message? */
12299         if (!tvb_bytes_exist(tvb, 0, 4))
12300           return FALSE;
12301         if (memcmp(tvb_get_ptr(tvb, 0, 4), smb_signature, 4) != 0) {
12302           /* No. */
12303           return FALSE;
12304         }
12305
12306         /* Yes. */
12307         si.unicode = FALSE;
12308         si.ddisp = 0;
12309
12310         if (check_col(pinfo->fd, COL_PROTOCOL))
12311                 col_set_str(pinfo->fd, COL_PROTOCOL, "SMB");
12312         if (check_col(pinfo->fd, COL_INFO))
12313                 col_clear(pinfo->fd, COL_INFO);
12314
12315         cmd = tvb_get_guint8(tvb, SMB_hdr_com_offset);
12316         if (check_col(pinfo->fd, COL_INFO)) {
12317
12318           col_add_fstr(pinfo->fd, COL_INFO, "%s", decode_smb_name(cmd));
12319
12320         }
12321
12322         if (tree) {
12323
12324           ti = proto_tree_add_item(tree, proto_smb, tvb, offset, tvb_length(tvb), FALSE);
12325           smb_tree = proto_item_add_subtree(ti, ett_smb);
12326
12327           th = proto_tree_add_text(smb_tree, NullTVB, offset, 32, "SMB Header");
12328
12329           smb_hdr_tree = proto_item_add_subtree(th, ett_smb_hdr);
12330
12331           /* 0xFFSMB is actually a 1 byte msg type and 3 byte server
12332            * component ... SMB is only one used
12333            */
12334
12335           proto_tree_add_text(smb_hdr_tree, tvb, offset, 1, "Message Type: 0xFF");
12336           proto_tree_add_text(smb_hdr_tree, tvb, offset+1, 3, "Server Component: SMB");
12337
12338         }
12339
12340         offset += 4;  /* Skip the marker */
12341
12342         if (tree) {
12343
12344           proto_tree_add_uint(smb_hdr_tree, hf_smb_cmd, tvb, offset, 1, cmd);
12345
12346         }
12347
12348         offset += 1;
12349
12350         /* Get flags2; we need it to know whether the error code is
12351            an NT error code or a DOS error code. */
12352
12353         flags2 = tvb_get_letohs(tvb, 10);
12354
12355         /* Handle error code */
12356
12357         if (flags2 & 0x4000) {
12358
12359             /* handle NT 32 bit error code */
12360             status = tvb_get_letohl(tvb, offset); 
12361
12362             if (tree) {
12363
12364                 /*
12365                  * XXX - break the value down into severity code,
12366                  * customer code, facility, and error?
12367                  */
12368                 proto_tree_add_uint(smb_hdr_tree, hf_smb_status,
12369                                     tvb, offset, 4, status);
12370
12371             }
12372
12373             offset += 4;
12374
12375         }
12376         else {
12377             /* handle DOS error code & class */
12378
12379             /* Next, look at the error class, SMB_RETCLASS */
12380
12381             errcls = tvb_get_guint8(tvb, offset);
12382
12383             if (tree) {
12384
12385                 proto_tree_add_uint(smb_hdr_tree, hf_smb_errcls,
12386                                     tvb, offset, 1, errcls);
12387             }
12388
12389             offset += 1;
12390
12391             /* Error code, SMB_HEINFO ... */
12392
12393             errcode1 = tvb_get_guint8(tvb, offset);
12394
12395             if (tree) {
12396
12397                 proto_tree_add_text(smb_hdr_tree, tvb, offset, 1, "Reserved: %i", errcode1); 
12398
12399             }
12400
12401             offset += 1;
12402
12403             errcode = tvb_get_letohs(tvb, offset); 
12404
12405             if (tree) {
12406
12407                 /*
12408                  * XXX - the type of this field depends on the value of
12409                  * "errcls", so there isn't a single value_string array
12410                  * for it, so there can't be a single field for it.
12411                  */
12412                 proto_tree_add_text(smb_hdr_tree, tvb, offset, 2, "Error Code: %s",
12413                                     decode_smb_error(errcls, errcode));
12414
12415             }
12416
12417             offset += 2;
12418         }
12419
12420         /* Now for the flags: Bit 0 = 0 means cmd, 0 = 1 means resp */
12421
12422         flags = tvb_get_guint8(tvb, offset);
12423         si.request = !(flags&SMB_FLAGS_DIRN);
12424
12425         if (check_col(pinfo->fd, COL_INFO)) {
12426
12427           col_append_fstr(pinfo->fd, COL_INFO, " %s", si.request ? "Request" : "Response");
12428
12429         }
12430
12431         if (tree) {
12432
12433           tf = proto_tree_add_uint(smb_hdr_tree, hf_smb_flags, tvb, offset, 1, flags);
12434
12435           flags_tree = proto_item_add_subtree(tf, ett_smb_flags);
12436           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12437                               decode_boolean_bitfield(flags, 0x01, 8,
12438                                                       "Lock&Read, Write&Unlock supported",
12439                                                       "Lock&Read, Write&Unlock not supported"));
12440           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12441                               decode_boolean_bitfield(flags, 0x02, 8,
12442                                                       "Receive buffer posted",
12443                                                       "Receive buffer not posted"));
12444           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12445                               decode_boolean_bitfield(flags, 0x08, 8, 
12446                                                       "Path names caseless",
12447                                                       "Path names case sensitive"));
12448           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12449                               decode_boolean_bitfield(flags, 0x10, 8,
12450                                                       "Pathnames canonicalized",
12451                                                       "Pathnames not canonicalized"));
12452           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12453                               decode_boolean_bitfield(flags, 0x20, 8,
12454                                                       "OpLocks requested/granted",
12455                                                       "OpLocks not requested/granted"));
12456           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12457                               decode_boolean_bitfield(flags, 0x40, 8, 
12458                                                       "Notify all",
12459                                                       "Notify open only"));
12460
12461           proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
12462                               decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
12463                                                       8, "Response to client/redirector", "Request to server"));
12464
12465         }
12466
12467         offset += 1;
12468
12469         /* Now put flags2 into the tree */
12470
12471         if (tree) {
12472
12473           tf = proto_tree_add_uint(smb_hdr_tree, hf_smb_flags2, tvb, offset, 2, flags2);
12474
12475           flags2_tree = proto_item_add_subtree(tf, ett_smb_flags2);
12476           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12477                               decode_boolean_bitfield(flags2, 0x0001, 16,
12478                                                       "Long file names supported",
12479                                                       "Long file names not supported"));
12480           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12481                               decode_boolean_bitfield(flags2, 0x0002, 16,
12482                                                       "Extended attributes supported",
12483                                                       "Extended attributes not supported"));
12484           proto_tree_add_text(flags2_tree, tvb, offset, 1, "%s",
12485                               decode_boolean_bitfield(flags2, 0x0004, 16,
12486                                                       "Security signatures supported",
12487                                                       "Security signatures not supported"));
12488           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12489                               decode_boolean_bitfield(flags2, 0x0800, 16,
12490                                                       "Extended security negotiation supported",
12491                                                       "Extended security negotiation not supported"));
12492           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12493                               decode_boolean_bitfield(flags2, 0x1000, 16, 
12494                                                       "Resolve pathnames with DFS",
12495                                                       "Don't resolve pathnames with DFS"));
12496           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12497                               decode_boolean_bitfield(flags2, 0x2000, 16,
12498                                                       "Permit reads if execute-only",
12499                                                       "Don't permit reads if execute-only"));
12500           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12501                               decode_boolean_bitfield(flags2, 0x4000, 16,
12502                                                       "Error codes are NT error codes",
12503                                                       "Error codes are DOS error codes"));
12504           proto_tree_add_text(flags2_tree, tvb, offset, 2, "%s",
12505                               decode_boolean_bitfield(flags2, 0x8000, 16, 
12506                                                       "Strings are Unicode",
12507                                                       "Strings are ASCII"));
12508
12509         }
12510
12511         if (flags2 & 0x8000) si.unicode = TRUE; /* Mark them as Unicode */
12512
12513         offset += 2;
12514
12515         if (tree) {
12516
12517           /*
12518            * The document at
12519            *
12520            *    http://www.samba.org/samba/ftp/specs/smbpub.txt
12521            *
12522            * (a text version of "Microsoft Networks SMB FILE SHARING
12523            * PROTOCOL, Document Version 6.0p") says that:
12524            *
12525            *    the first 2 bytes of these 12 bytes are, for NT Create and X,
12526            *    the "High Part of PID";
12527            *
12528            *    the next four bytes are reserved;
12529            *
12530            *    the next four bytes are, for SMB-over-IPX (with no
12531            *    NetBIOS involved) two bytes of Session ID and two bytes
12532            *    of SequenceNumber.
12533            *
12534            * If we ever implement SMB-over-IPX (which I suspect goes over
12535            * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
12536            * document in question), we'd probably want to have some way
12537            * to determine whether this is SMB-over-IPX or not (which could
12538            * be done by adding a PT_IPXSOCKET port type, having the
12539            * IPX dissector set "pinfo->srcport" and "pinfo->destport",
12540            * and having the SMB dissector check for a port type of
12541            * PT_IPXSOCKET and for "pinfo->match_port" being either
12542            * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
12543            * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
12544            */
12545           proto_tree_add_text(smb_hdr_tree, tvb, offset, 12, "Reserved: 6 WORDS");
12546
12547         }
12548
12549         offset += 12;
12550
12551         /* Now the TID, tree ID */
12552
12553         tid = tvb_get_letohs(tvb, offset);
12554         si.tid = tid;
12555
12556         if (tree) {
12557
12558           proto_tree_add_uint(smb_hdr_tree, hf_smb_tid, tvb, offset, 2, tid); 
12559
12560         }
12561
12562         offset += 2;
12563
12564         /* Now the PID, Process ID */
12565
12566         pid = tvb_get_letohs(tvb, offset);
12567         si.pid = pid;
12568
12569         if (tree) {
12570
12571           proto_tree_add_uint(smb_hdr_tree, hf_smb_pid, tvb, offset, 2, pid); 
12572
12573         }
12574
12575         offset += 2;
12576
12577         /* Now the UID, User ID */
12578
12579         uid = tvb_get_letohs(tvb, offset);
12580         si.uid = uid;
12581
12582         if (tree) {
12583
12584           proto_tree_add_uint(smb_hdr_tree, hf_smb_uid, tvb, offset, 2, uid); 
12585
12586         }
12587         
12588         offset += 2;
12589
12590         /* Now the MID, Multiplex ID */
12591
12592         mid = tvb_get_letohs(tvb, offset);
12593         si.mid = mid;
12594
12595         if (tree) {
12596
12597           proto_tree_add_uint(smb_hdr_tree, hf_smb_mid, tvb, offset, 2, mid); 
12598
12599         }
12600
12601         offset += 2;
12602
12603         /*
12604          * Get old-style information from the tvbuff we've been handed.
12605          */
12606         tvb_compat(tvb, &pd, &SMB_offset);
12607         offset += SMB_offset;
12608
12609         /* Now vector through the table to dissect them */
12610
12611         (dissect[cmd])(pd, offset, pinfo->fd, tree, smb_tree, si,
12612                        tvb_length(tvb), SMB_offset);
12613
12614         return TRUE;
12615 }
12616
12617 /*** External routines called during the registration process */
12618
12619 extern void register_proto_smb_browse( void);
12620 extern void register_proto_smb_logon( void);
12621 extern void register_proto_smb_mailslot( void);
12622 extern void register_proto_smb_pipe( void);
12623 extern void register_proto_smb_mailslot( void);
12624
12625
12626 void
12627 proto_register_smb(void)
12628 {
12629         static hf_register_info hf[] = {
12630           { &hf_smb_cmd,
12631             { "SMB Command", "smb.cmd",
12632               FT_UINT8, BASE_HEX, VALS(smb_cmd_vals), 0x0, "", HFILL }},
12633           { &hf_smb_status,
12634             { "Status", "smb.status",
12635               FT_UINT32, BASE_HEX, VALS(NT_errors), 0x0, "", HFILL }},
12636           { &hf_smb_errcls,
12637             { "Error Class", "smb.errcls",
12638               FT_UINT8, BASE_HEX, VALS(errcls_types), 0x0, "", HFILL }},
12639           { &hf_smb_flags,
12640             { "Flags", "smb.flags",
12641               FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
12642           { &hf_smb_flags2,
12643             { "Flags2", "smb.flags2",
12644               FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
12645           { &hf_smb_tid,
12646             { "Network Path/Tree ID (TID)", "smb.tid",
12647               FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
12648           { &hf_smb_pid,
12649             { "Process ID (PID)", "smb.pid",
12650               FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
12651           { &hf_smb_uid,
12652             { "User ID (UID)", "smb.uid",
12653               FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
12654           { &hf_smb_mid,
12655             { "Multiplex ID (MID)", "smb.mid",
12656               FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
12657         };
12658         static gint *ett[] = {
12659                 &ett_smb,
12660                 &ett_smb_hdr,
12661                 &ett_smb_fileattributes,
12662                 &ett_smb_capabilities,
12663                 &ett_smb_aflags,
12664                 &ett_smb_dialects,
12665                 &ett_smb_mode,
12666                 &ett_smb_rawmode,
12667                 &ett_smb_flags,
12668                 &ett_smb_flags2,
12669                 &ett_smb_desiredaccess,
12670                 &ett_smb_search,
12671                 &ett_smb_file,
12672                 &ett_smb_openfunction,
12673                 &ett_smb_filetype,
12674                 &ett_smb_openaction,
12675                 &ett_smb_writemode,
12676                 &ett_smb_lock_type,
12677                 &ett_smb_ssetupandxaction,
12678                 &ett_smb_optionsup,
12679         };
12680
12681         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
12682             "SMB", "smb");
12683
12684         proto_register_subtree_array(ett, array_length(ett));
12685         proto_register_field_array(proto_smb, hf, array_length(hf));
12686         register_init_routine(&smb_init_protocol);
12687
12688         register_proto_smb_browse();
12689         register_proto_smb_logon();
12690         register_proto_smb_mailslot();
12691         register_proto_smb_pipe();
12692 }
12693
12694 void
12695 proto_reg_handoff_smb(void)
12696 {
12697         heur_dissector_add("netbios", dissect_smb, proto_smb);
12698 }