55b1cbc9685f8ce707987415cdd582c5df1a2484
[obnox/wireshark/wip.git] / packet-dcerpc-reg.c
1 /* packet-dcerpc-reg.c
2  * Routines for SMB \PIPE\winreg packet disassembly
3  * Copyright 2001-2003 Tim Potter <tpot@samba.org>
4  *
5  * $Id: packet-dcerpc-reg.c,v 1.17 2003/06/05 04:22:03 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include "packet-dcerpc.h"
33 #include "packet-dcerpc-nt.h"
34 #include "packet-dcerpc-reg.h"
35 #include "smb.h"
36
37 /* Global hf index fields */
38
39 static int hf_rc = -1;
40 static int hf_hnd = -1;
41 static int hf_access_mask = -1;
42
43 /* OpenHKLM */
44
45 static int hf_openhklm_unknown1 = -1;
46 static int hf_openhklm_unknown2 = -1;
47
48 /* QueryKey */
49
50 static int hf_querykey_class = -1;
51 static int hf_querykey_num_subkeys = -1;
52 static int hf_querykey_max_subkey_len = -1;
53 static int hf_querykey_reserved = -1;
54 static int hf_querykey_num_values = -1;
55 static int hf_querykey_max_valname_len = -1;
56 static int hf_querykey_max_valbuf_size = -1;
57 static int hf_querykey_secdesc = -1;
58 static int hf_querykey_modtime = -1;
59
60 /* OpenEntry */
61
62 static int hf_keyname = -1;
63 static int hf_openentry_unknown1 = -1;
64
65 /* Unknown 0x1A */
66
67 static int hf_unknown1A_unknown1 = -1;
68
69 /* Data that is passed to a open call */
70
71 static int
72 dissect_open_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
73                   proto_tree *tree, char *drep)
74 {
75         offset = dissect_ndr_uint16(
76                 tvb, offset, pinfo, tree, drep,
77                 hf_openhklm_unknown1, NULL);
78
79         offset = dissect_ndr_uint16(
80                 tvb, offset, pinfo, tree, drep,
81                 hf_openhklm_unknown1, NULL);
82
83         offset = dissect_ndr_uint32(
84                 tvb, offset, pinfo, tree, drep,
85                 hf_access_mask, NULL);
86
87         return offset;
88 }
89
90 /*
91  * OpenHKLM
92  */
93
94 static int
95 RegOpenHKLM_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
96               proto_tree *tree, char *drep)
97 {
98         /* Parse packet */
99
100         offset = dissect_ndr_pointer(
101                 tvb, offset, pinfo, tree, drep,
102                 dissect_open_data,
103                 NDR_POINTER_UNIQUE, "Unknown", -1);
104
105         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
106
107         return offset;
108 }
109
110 static int
111 RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
112               proto_tree *tree, char *drep)
113 {
114         e_ctx_hnd policy_hnd;
115         proto_item *hnd_item;
116         guint32 status;
117
118         /* Parse packet */
119
120         offset = dissect_nt_policy_hnd(
121                 tvb, offset, pinfo, tree, drep,
122                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
123
124         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
125                                   hf_rc, &status);
126
127         if (status == 0) {
128                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKLM handle");
129                 if (hnd_item != NULL)
130                         proto_item_append_text(hnd_item, ": HKLM handle");
131         }
132
133         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
134
135         return offset;
136 }
137
138 /*
139  * OpenHKU
140  */
141
142 static int
143 RegOpenHKU_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
144              proto_tree *tree, char *drep)
145 {
146         /* Parse packet */
147
148         offset = dissect_ndr_pointer(
149                 tvb, offset, pinfo, tree, drep,
150                 dissect_open_data,
151                 NDR_POINTER_UNIQUE, "Unknown", -1);
152
153         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
154
155         return offset;
156 }
157
158 static int
159 RegOpenHKU_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
160              proto_tree *tree, char *drep)
161 {
162         e_ctx_hnd policy_hnd;
163         proto_item *hnd_item;
164         guint32 status;
165
166         /* Parse packet */
167
168         offset = dissect_nt_policy_hnd(
169                 tvb, offset, pinfo, tree, drep,
170                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
171
172         offset = dissect_ntstatus(
173                 tvb, offset, pinfo, tree, drep, hf_rc, &status);
174
175         if (status == 0) {
176                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKU handle");
177                 if (hnd_item != NULL)
178                         proto_item_append_text(hnd_item, ": HKU handle");
179         }
180
181         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
182
183         return offset;
184 }
185
186 /*
187  * OpenHKCR
188  */
189
190 static int
191 RegOpenHKCR_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
192               proto_tree *tree, char *drep)
193 {
194         /* Parse packet */
195
196         offset = dissect_ndr_pointer(
197                 tvb, offset, pinfo, tree, drep,
198                 dissect_open_data,
199                 NDR_POINTER_UNIQUE, "Unknown", -1);
200
201         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
202
203         return offset;
204 }
205
206 static int
207 RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
208               proto_tree *tree, char *drep)
209 {
210         e_ctx_hnd policy_hnd;
211         proto_item *hnd_item;
212         guint32 status;
213
214         /* Parse packet */
215
216         offset = dissect_nt_policy_hnd(
217                 tvb, offset, pinfo, tree, drep,
218                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
219
220         offset = dissect_ntstatus(
221                 tvb, offset, pinfo, tree, drep, hf_rc, &status);
222
223         if (status == 0) {
224                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKCR handle");
225                 if (hnd_item != NULL)
226                         proto_item_append_text(hnd_item, ": HKCR handle");
227         }
228
229         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
230
231         return offset;
232 }
233
234 /*
235  * RegClose
236  */
237
238 static int
239 RegClose_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
240            proto_tree *tree, char *drep)
241 {
242         /* Parse packet */
243
244         offset = dissect_nt_policy_hnd(
245                 tvb, offset, pinfo, tree, drep,
246                 hf_hnd, NULL, NULL, FALSE, TRUE);
247
248         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
249
250         return offset;
251 }
252
253 static int
254 RegClose_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
255            proto_tree *tree, char *drep)
256 {
257         /* Parse packet */
258
259         offset = dissect_nt_policy_hnd(
260                 tvb, offset, pinfo, tree, drep,
261                 hf_hnd, NULL, NULL, FALSE, FALSE);
262
263         offset = dissect_ntstatus(
264                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
265
266         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
267
268         return offset;
269 }
270
271 /*
272  * RegQueryKey
273  */
274
275 static int
276 RegQueryKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
277               proto_tree *tree, char *drep)
278 {
279         /* Parse packet */
280
281         offset = dissect_nt_policy_hnd(
282                 tvb, offset, pinfo, tree, drep,
283                 hf_hnd, NULL, NULL, FALSE, FALSE);
284
285         offset = dissect_ndr_counted_string(
286                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
287
288         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
289
290         return offset;
291 }
292
293 static int
294 RegQueryKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
295               proto_tree *tree, char *drep)
296 {
297         /* Parse packet */
298
299         offset = dissect_ndr_counted_string(
300                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
301
302         offset = dissect_ndr_uint32(
303                 tvb, offset, pinfo, tree, drep,
304                 hf_querykey_num_subkeys, NULL);
305
306         offset = dissect_ndr_uint32(
307                 tvb, offset, pinfo, tree, drep,
308                 hf_querykey_max_subkey_len, NULL);
309
310         offset = dissect_ndr_uint32(
311                 tvb, offset, pinfo, tree, drep,
312                 hf_querykey_reserved, NULL);
313
314         offset = dissect_ndr_uint32(
315                 tvb, offset, pinfo, tree, drep,
316                 hf_querykey_num_values, NULL);
317
318         offset = dissect_ndr_uint32(
319                 tvb, offset, pinfo, tree, drep,
320                 hf_querykey_max_valname_len, NULL);
321
322         offset = dissect_ndr_uint32(
323                 tvb, offset, pinfo, tree, drep,
324                 hf_querykey_max_valbuf_size, NULL);
325
326         offset = dissect_ndr_uint32(
327                 tvb, offset, pinfo, tree, drep,
328                 hf_querykey_secdesc, NULL);
329
330         offset = dissect_ndr_nt_NTTIME(
331                 tvb, offset, pinfo, tree, drep, hf_querykey_modtime);
332
333         offset = dissect_ntstatus(
334                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
335
336         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
337
338         return offset;
339 }
340
341 /*
342  * OpenEntry
343  */
344
345 static int
346 RegOpenEntry_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
347                proto_tree *tree, char *drep)
348 {
349         /* Parse packet */
350
351         offset = dissect_nt_policy_hnd(
352                 tvb, offset, pinfo, tree, drep,
353                 hf_hnd, NULL, NULL, FALSE, FALSE);
354
355         offset = dissect_ndr_counted_string(
356                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
357
358         offset = dissect_ndr_uint32(
359                 tvb, offset, pinfo, tree, drep,
360                 hf_openentry_unknown1, NULL);
361
362         offset = dissect_ndr_uint32(
363                 tvb, offset, pinfo, tree, drep,
364                 hf_access_mask, NULL);
365
366         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
367
368         return offset;
369 }
370
371 static int
372 RegOpenEntry_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
373                proto_tree *tree, char *drep)
374 {
375         e_ctx_hnd policy_hnd;
376         proto_item *hnd_item;
377         guint32 status;
378
379         /* Parse packet */
380
381         offset = dissect_nt_policy_hnd(
382                 tvb, offset, pinfo, tree, drep,
383                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
384
385         offset = dissect_ntstatus(
386                 tvb, offset, pinfo, tree, drep, hf_rc, &status);
387
388         if (status == 0) {
389                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
390                         "OpenEntry handle");
391                 if (hnd_item != NULL)
392                         proto_item_append_text(hnd_item, ": OpenEntry handle");
393         }
394
395         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
396
397         return offset;
398 }
399
400 /*
401  * Unknown1A
402  */
403
404 static int
405 RegUnknown1A_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
406                proto_tree *tree, char *drep)
407 {
408         /* Parse packet */
409
410         offset = dissect_nt_policy_hnd(
411                 tvb, offset, pinfo, tree, drep,
412                 hf_hnd, NULL, NULL, FALSE, FALSE);
413
414         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
415
416         return offset;
417 }
418
419 static int
420 RegUnknown1A_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
421                proto_tree *tree, char *drep)
422 {
423         /* Parse packet */
424
425         offset = dissect_ndr_uint32(
426                 tvb, offset, pinfo, tree, drep,
427                 hf_unknown1A_unknown1, NULL);
428
429         offset = dissect_ntstatus(
430                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
431
432         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
433
434         return offset;
435 }
436
437 /*
438  * EnumKey
439  */
440
441 static int
442 RegEnumKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
443              proto_tree *tree, char *drep)
444 {
445         /* Parse packet */
446
447         offset = dissect_nt_policy_hnd(
448                 tvb, offset, pinfo, tree, drep,
449                 hf_hnd, NULL, NULL, FALSE, FALSE);
450
451         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
452
453         return offset;
454 }
455
456 static int
457 RegEnumKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
458              proto_tree *tree, char *drep)
459 {
460         /* Parse packet */
461
462         offset = dissect_ntstatus(
463                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
464
465         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
466
467         return offset;
468 }
469
470 #if 0
471
472 /* Templates for new subdissectors */
473
474 /*
475  * FOO
476  */
477
478 static int
479 RegFoo_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
480          proto_tree *tree, char *drep)
481 {
482         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
483
484         /* Parse packet */
485
486         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
487
488         return offset;
489 }
490
491 static int
492 RegFoo_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
493          proto_tree *tree, char *drep)
494 {
495         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
496
497         /* Parse packet */
498
499         offset = dissect_ntstatus(
500                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
501
502         dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
503
504         return offset;
505 }
506
507 #endif
508
509 /* Registry data types */
510
511 const value_string reg_datatypes[] = {
512         { DCERPC_REG_NONE, "REG_NONE" },
513         { DCERPC_REG_SZ, "REG_SZ" },
514         { DCERPC_REG_EXPAND_SZ, "REG_EXPAND_SZ" },
515         { DCERPC_REG_BINARY, "REG_BINARY" },
516         { DCERPC_REG_DWORD, "REG_DWORD" },
517         { DCERPC_REG_DWORD_LE, "REG_DWORD_LE" },
518         { DCERPC_REG_DWORD_BE, "REG_DWORD_BE" },
519         { DCERPC_REG_LINK, "REG_LINK" },
520         { DCERPC_REG_MULTI_SZ, "REG_MULTI_SZ" },
521         { DCERPC_REG_RESOURCE_LIST, "REG_RESOURCE_LIST" },
522         { DCERPC_REG_FULL_RESOURCE_DESCRIPTOR, "REG_FULL_RESOURCE_DESCRIPTOR" },
523         { DCERPC_REG_RESOURCE_REQUIREMENTS_LIST, "REG_RESOURCE_REQUIREMENTS_LIST" },
524         {0, NULL }
525 };
526
527 static int proto_dcerpc_reg = -1;
528 static int hf_reg_opnum = -1;
529 static gint ett_dcerpc_reg = -1;
530
531 static e_uuid_t uuid_dcerpc_reg = {
532         0x338cd001, 0x2244, 0x31f1,
533         { 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03 }
534 };
535
536 static guint16 ver_dcerpc_reg = 1;
537
538 static dcerpc_sub_dissector dcerpc_reg_dissectors[] = {
539         { REG_OPEN_HKCR, "OpenHKCR", RegOpenHKCR_q, RegOpenHKCR_r },
540         { _REG_UNK_01, "Unknown01", NULL, NULL },
541         { REG_OPEN_HKLM, "OpenHKLM", RegOpenHKLM_q, RegOpenHKLM_r },
542         { _REG_UNK_03, "Unknown03", NULL, NULL },
543         { REG_OPEN_HKU, "OpenHKU", RegOpenHKU_q, RegOpenHKU_r },
544         { REG_CLOSE, "Close", RegClose_q, RegClose_r },
545         { REG_CREATE_KEY, "CreateKey", NULL, NULL },
546         { REG_DELETE_KEY, "DeleteKey", NULL, NULL },
547         { REG_DELETE_VALUE, "DeleteValue", NULL, NULL },
548         { REG_ENUM_KEY, "EnumKey", RegEnumKey_q, RegEnumKey_r },
549         { REG_ENUM_VALUE, "EnumValue", NULL, NULL },
550         { REG_FLUSH_KEY, "FlushKey", NULL, NULL },
551         { REG_GET_KEY_SEC, "GetKeySecurity", NULL, NULL },
552         { _REG_UNK_0D, "Unknown0d", NULL, NULL },
553         { _REG_UNK_0E, "Unknown0e", NULL, NULL },
554         { REG_OPEN_ENTRY, "OpenEntry", RegOpenEntry_q, RegOpenEntry_r },
555         { REG_QUERY_KEY, "QueryKey", RegQueryKey_q, RegQueryKey_r },
556         { REG_INFO, "Info", NULL, NULL },
557         { _REG_UNK_12, "Unknown12", NULL, NULL },
558         { _REG_UNK_13, "Unknown13", NULL, NULL },
559         { _REG_UNK_14, "Unknown14", NULL, NULL },
560         { REG_SET_KEY_SEC, "SetKeySecurity", NULL, NULL },
561         { REG_CREATE_VALUE, "CreateValue", NULL, NULL },
562         { _REG_UNK_17, "Unknown17", NULL, NULL },
563         { REG_SHUTDOWN, "Shutdown", NULL, NULL },
564         { REG_ABORT_SHUTDOWN, "AbortShutdown", NULL, NULL },
565         { _REG_UNK_1A, "Unknown1A", RegUnknown1A_q, RegUnknown1A_r },
566
567         { 0, NULL, NULL,  NULL }
568 };
569
570 static const value_string reg_opnum_vals[] = {
571         { REG_OPEN_HKCR, "OpenHKCR" },
572         { _REG_UNK_01, "Unknown01" },
573         { REG_OPEN_HKLM, "OpenHKLM" },
574         { _REG_UNK_03, "Unknown03" },
575         { REG_OPEN_HKU, "OpenHKU" },
576         { REG_CLOSE, "Close" },
577         { REG_CREATE_KEY, "CreateKey" },
578         { REG_DELETE_KEY, "DeleteKey" },
579         { REG_DELETE_VALUE, "DeleteValue" },
580         { REG_ENUM_KEY, "EnumKey" },
581         { REG_ENUM_VALUE, "EnumValue" },
582         { REG_FLUSH_KEY, "FlushKey" },
583         { REG_GET_KEY_SEC, "GetKeySecurity" },
584         { _REG_UNK_0D, "Unknown0d" },
585         { _REG_UNK_0E, "Unknown0e" },
586         { REG_OPEN_ENTRY, "OpenEntry" },
587         { REG_QUERY_KEY, "QueryKey" },
588         { REG_INFO, "Info" },
589         { _REG_UNK_12, "Unknown12" },
590         { _REG_UNK_13, "Unknown13" },
591         { _REG_UNK_14, "Unknown14" },
592         { REG_SET_KEY_SEC, "SetKeySecurity" },
593         { REG_CREATE_VALUE, "CreateValue" },
594         { _REG_UNK_17, "Unknown17" },
595         { REG_SHUTDOWN, "Shutdown" },
596         { REG_ABORT_SHUTDOWN, "AbortShutdown" },
597         { _REG_UNK_1A, "Unknown1A" },
598         { 0, NULL }
599 };
600
601 void
602 proto_register_dcerpc_reg(void)
603 {
604         static hf_register_info hf[] = {
605
606                 /* Global indexes */
607
608                 { &hf_hnd,
609                   { "Context handle", "reg.hnd", FT_BYTES, BASE_NONE,
610                     NULL, 0x0, "REG policy handle", HFILL }},
611
612                 { &hf_rc,
613                   { "Return code", "reg.rc", FT_UINT32, BASE_HEX,
614                     VALS(NT_errors), 0x0, "REG return code", HFILL }},
615
616                 { &hf_reg_opnum,
617                   { "Operation", "reg.opnum", FT_UINT16, BASE_DEC,
618                     VALS(reg_opnum_vals), 0x0, "Operation", HFILL }},
619
620                 { &hf_access_mask,
621                   { "Access mask", "reg.access_mask", FT_UINT32, BASE_HEX,
622                     NULL, 0x0, "Access mask", HFILL }},
623
624                 /* OpenHKLM */
625
626                 { &hf_openhklm_unknown1,
627                   { "Unknown 1", "reg.openhklm.unknown1", FT_UINT16, BASE_HEX,
628                     NULL, 0x0, "Unknown 1", HFILL }},
629
630                 { &hf_openhklm_unknown2,
631                   { "Unknown 2", "reg.openhklm.unknown2", FT_UINT16, BASE_HEX,
632                     NULL, 0x0, "Unknown 2", HFILL }},
633
634                 /* QueryClass */
635
636                 { &hf_querykey_class,
637                   { "Class", "reg.querykey.class", FT_STRING, BASE_NONE,
638                     NULL, 0, "Class", HFILL }},
639
640                 { &hf_querykey_num_subkeys,
641                   { "Num subkeys", "reg.querykey.num_subkeys", FT_UINT32, BASE_DEC,
642                     NULL, 0x0, "Num subkeys", HFILL }},
643
644                 { &hf_querykey_max_subkey_len,
645                   { "Max subkey len", "reg.querykey.max_subkey_len", FT_UINT32, BASE_DEC,
646                     NULL, 0x0, "Max subkey len", HFILL }},
647
648                 { &hf_querykey_reserved,
649                   { "Reserved", "reg.querykey.reserved", FT_UINT32, BASE_DEC,
650                     NULL, 0x0, "Reserved", HFILL }},
651
652                 { &hf_querykey_num_values,
653                   { "Num values", "reg.querykey.num_values", FT_UINT32, BASE_DEC,
654                     NULL, 0x0, "Num values", HFILL }},
655
656                 { &hf_querykey_max_valname_len,
657                   { "Max valnum len", "reg.querykey.max_valname_len", FT_UINT32, BASE_DEC,
658                     NULL, 0x0, "Max valname len", HFILL }},
659
660                 { &hf_querykey_max_valbuf_size,
661                   { "Max valbuf size", "reg.querykey.max_valbuf_size", FT_UINT32, BASE_DEC,
662                     NULL, 0x0, "Max valbuf size", HFILL }},
663
664                 { &hf_querykey_secdesc,
665                   { "Secdesc", "reg.querykey.secdesc", FT_UINT32, BASE_DEC,
666                     NULL, 0x0, "Secdesc", HFILL }},
667
668                 { &hf_querykey_modtime,
669                   { "Mod time", "reg.querykey.modtime", FT_ABSOLUTE_TIME, BASE_NONE,
670                     NULL, 0x0, "Secdesc", HFILL }},
671
672                 /* OpenEntry */
673
674                 { &hf_keyname,
675                   { "Key name", "reg.keyname", FT_STRING, BASE_NONE,
676                     NULL, 0x0, "Keyname", HFILL }},
677
678                 { &hf_openentry_unknown1,
679                   { "Unknown 1", "reg.openentry.unknown1", FT_UINT32, BASE_HEX,
680                     NULL, 0x0, "Unknown 1", HFILL }},
681
682                 /* Unknown1A */
683
684                 { &hf_unknown1A_unknown1,
685                   { "Unknown 1", "reg.unknown1A.unknown1", FT_UINT32, BASE_HEX,
686                     NULL, 0x0, "Unknown 1", HFILL }},
687
688         };
689
690         static gint *ett[] = {
691                 &ett_dcerpc_reg
692         };
693
694         proto_dcerpc_reg = proto_register_protocol(
695                 "Microsoft Registry", "WINREG", "winreg");
696
697         proto_register_field_array(proto_dcerpc_reg, hf, array_length(hf));
698
699         proto_register_subtree_array(ett, array_length(ett));
700 }
701
702 void
703 proto_reg_handoff_dcerpc_reg(void)
704 {
705         /* Register protocol as dcerpc */
706
707         dcerpc_init_uuid(proto_dcerpc_reg, ett_dcerpc_reg, &uuid_dcerpc_reg,
708                          ver_dcerpc_reg, dcerpc_reg_dissectors, hf_reg_opnum);
709 }