Change dissect_deferred_pointer()
[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.22 2003/09/28 11:35:20 tpot 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 static int hf_keytype = -1;
43 static int hf_keydata = -1;
44 static int hf_offered = -1;
45 static int hf_returned = -1;
46 static int hf_reserved = -1;
47 static int hf_unknown = -1;
48
49 /* OpenHKLM */
50
51 static int hf_openhklm_unknown1 = -1;
52 static int hf_openhklm_unknown2 = -1;
53
54 /* QueryInfoKey */
55
56 static int hf_querykey_class = -1;
57 static int hf_querykey_num_subkeys = -1;
58 static int hf_querykey_max_subkey_len = -1;
59 static int hf_querykey_reserved = -1;
60 static int hf_querykey_num_values = -1;
61 static int hf_querykey_max_valname_len = -1;
62 static int hf_querykey_max_valbuf_size = -1;
63 static int hf_querykey_secdesc = -1;
64 static int hf_querykey_modtime = -1;
65
66 /* OpenKey */
67
68 static int hf_keyname = -1;
69 static int hf_openkey_unknown1 = -1;
70
71 /* GetVersion */
72
73 static int hf_getversion_version = -1;
74
75 /* Data that is passed to a open call */
76
77 static int
78 dissect_open_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
79                   proto_tree *tree, char *drep)
80 {
81         offset = dissect_ndr_uint16(
82                 tvb, offset, pinfo, tree, drep,
83                 hf_openhklm_unknown1, NULL);
84
85         offset = dissect_ndr_uint16(
86                 tvb, offset, pinfo, tree, drep,
87                 hf_openhklm_unknown1, NULL);
88
89         offset = dissect_ndr_uint32(
90                 tvb, offset, pinfo, tree, drep,
91                 hf_access_mask, NULL);
92
93         return offset;
94 }
95
96 /*
97  * OpenHKLM
98  */
99
100 static int
101 RegOpenHKLM_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
102               proto_tree *tree, char *drep)
103 {
104         /* Parse packet */
105
106         offset = dissect_ndr_pointer(
107                 tvb, offset, pinfo, tree, drep,
108                 dissect_open_data,
109                 NDR_POINTER_UNIQUE, "Unknown", -1);
110
111         return offset;
112 }
113
114 static int
115 RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
116               proto_tree *tree, char *drep)
117 {
118         e_ctx_hnd policy_hnd;
119         proto_item *hnd_item;
120         guint32 status;
121
122         /* Parse packet */
123
124         offset = dissect_nt_policy_hnd(
125                 tvb, offset, pinfo, tree, drep,
126                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
127
128         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
129                                   hf_rc, &status);
130
131         if (status == 0) {
132                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKLM handle");
133                 if (hnd_item != NULL)
134                         proto_item_append_text(hnd_item, ": HKLM handle");
135         }
136
137         return offset;
138 }
139
140 /*
141  * OpenHKU
142  */
143
144 static int
145 RegOpenHKU_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
146              proto_tree *tree, char *drep)
147 {
148         /* Parse packet */
149
150         offset = dissect_ndr_pointer(
151                 tvb, offset, pinfo, tree, drep,
152                 dissect_open_data,
153                 NDR_POINTER_UNIQUE, "Unknown", -1);
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         return offset;
182 }
183
184 /*
185  * OpenHKCR
186  */
187
188 static int
189 RegOpenHKCR_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
190               proto_tree *tree, char *drep)
191 {
192         /* Parse packet */
193
194         offset = dissect_ndr_pointer(
195                 tvb, offset, pinfo, tree, drep,
196                 dissect_open_data,
197                 NDR_POINTER_UNIQUE, "Unknown", -1);
198
199         return offset;
200 }
201
202 static int
203 RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
204               proto_tree *tree, char *drep)
205 {
206         e_ctx_hnd policy_hnd;
207         proto_item *hnd_item;
208         guint32 status;
209
210         /* Parse packet */
211
212         offset = dissect_nt_policy_hnd(
213                 tvb, offset, pinfo, tree, drep,
214                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
215
216         offset = dissect_ntstatus(
217                 tvb, offset, pinfo, tree, drep, hf_rc, &status);
218
219         if (status == 0) {
220                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKCR handle");
221                 if (hnd_item != NULL)
222                         proto_item_append_text(hnd_item, ": HKCR handle");
223         }
224
225         return offset;
226 }
227
228 /*
229  * CloseKey
230  */
231
232 static int
233 RegCloseKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
234            proto_tree *tree, char *drep)
235 {
236         /* Parse packet */
237
238         offset = dissect_nt_policy_hnd(
239                 tvb, offset, pinfo, tree, drep,
240                 hf_hnd, NULL, NULL, FALSE, TRUE);
241
242         return offset;
243 }
244
245 static int
246 RegCloseKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
247            proto_tree *tree, char *drep)
248 {
249         /* Parse packet */
250
251         offset = dissect_nt_policy_hnd(
252                 tvb, offset, pinfo, tree, drep,
253                 hf_hnd, NULL, NULL, FALSE, FALSE);
254
255         offset = dissect_ntstatus(
256                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
257
258         return offset;
259 }
260
261 /*
262  * QueryInfoKey
263  */
264
265 static int
266 RegQueryInfoKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
267               proto_tree *tree, char *drep)
268 {
269         /* Parse packet */
270
271         offset = dissect_nt_policy_hnd(
272                 tvb, offset, pinfo, tree, drep,
273                 hf_hnd, NULL, NULL, FALSE, FALSE);
274
275         offset = dissect_ndr_counted_string(
276                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
277
278         return offset;
279 }
280
281 static int
282 RegQueryInfoKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
283               proto_tree *tree, char *drep)
284 {
285         /* Parse packet */
286
287         offset = dissect_ndr_counted_string(
288                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
289
290         offset = dissect_ndr_uint32(
291                 tvb, offset, pinfo, tree, drep,
292                 hf_querykey_num_subkeys, NULL);
293
294         offset = dissect_ndr_uint32(
295                 tvb, offset, pinfo, tree, drep,
296                 hf_querykey_max_subkey_len, NULL);
297
298         offset = dissect_ndr_uint32(
299                 tvb, offset, pinfo, tree, drep,
300                 hf_querykey_reserved, NULL);
301
302         offset = dissect_ndr_uint32(
303                 tvb, offset, pinfo, tree, drep,
304                 hf_querykey_num_values, NULL);
305
306         offset = dissect_ndr_uint32(
307                 tvb, offset, pinfo, tree, drep,
308                 hf_querykey_max_valname_len, NULL);
309
310         offset = dissect_ndr_uint32(
311                 tvb, offset, pinfo, tree, drep,
312                 hf_querykey_max_valbuf_size, NULL);
313
314         offset = dissect_ndr_uint32(
315                 tvb, offset, pinfo, tree, drep,
316                 hf_querykey_secdesc, NULL);
317
318         offset = dissect_ndr_nt_NTTIME(
319                 tvb, offset, pinfo, tree, drep, hf_querykey_modtime);
320
321         offset = dissect_ntstatus(
322                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
323
324         return offset;
325 }
326
327 /*
328  * OpenKey
329  */
330
331 static int
332 RegOpenKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
333                proto_tree *tree, char *drep)
334 {
335         /* Parse packet */
336
337         offset = dissect_nt_policy_hnd(
338                 tvb, offset, pinfo, tree, drep,
339                 hf_hnd, NULL, NULL, FALSE, FALSE);
340
341         offset = dissect_ndr_counted_string(
342                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
343
344         offset = dissect_ndr_uint32(
345                 tvb, offset, pinfo, tree, drep,
346                 hf_openkey_unknown1, NULL);
347
348         offset = dissect_ndr_uint32(
349                 tvb, offset, pinfo, tree, drep,
350                 hf_access_mask, NULL);
351
352         return offset;
353 }
354
355 static int
356 RegOpenKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
357                proto_tree *tree, char *drep)
358 {
359         e_ctx_hnd policy_hnd;
360         proto_item *hnd_item;
361         guint32 status;
362
363         /* Parse packet */
364
365         offset = dissect_nt_policy_hnd(
366                 tvb, offset, pinfo, tree, drep,
367                 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
368
369         offset = dissect_ntstatus(
370                 tvb, offset, pinfo, tree, drep, hf_rc, &status);
371
372         if (status == 0) {
373                 dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
374                         "OpenKey handle");
375                 if (hnd_item != NULL)
376                         proto_item_append_text(hnd_item, ": OpenKey handle");
377         }
378
379         return offset;
380 }
381
382 /*
383  * GetVersion
384  */
385
386 static int
387 RegGetVersion_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
388                proto_tree *tree, char *drep)
389 {
390         /* Parse packet */
391
392         offset = dissect_nt_policy_hnd(
393                 tvb, offset, pinfo, tree, drep,
394                 hf_hnd, NULL, NULL, FALSE, FALSE);
395
396         return offset;
397 }
398
399 static int
400 RegGetVersion_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
401                proto_tree *tree, char *drep)
402 {
403         /* Parse packet */
404
405         offset = dissect_ndr_uint32(
406                 tvb, offset, pinfo, tree, drep,
407                 hf_getversion_version, NULL);
408
409         offset = dissect_ntstatus(
410                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
411
412         return offset;
413 }
414
415 /*
416  * EnumKey
417  */
418
419 static int
420 RegEnumKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
421              proto_tree *tree, char *drep)
422 {
423         /* Parse packet */
424
425         offset = dissect_nt_policy_hnd(
426                 tvb, offset, pinfo, tree, drep,
427                 hf_hnd, NULL, NULL, FALSE, FALSE);
428
429         return offset;
430 }
431
432 static int
433 RegEnumKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
434              proto_tree *tree, char *drep)
435 {
436         /* Parse packet */
437
438         offset = dissect_ntstatus(
439                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
440
441         return offset;
442 }
443
444 /*
445  * RegQueryValue
446  */
447
448 static int
449 dissect_reserved(tvbuff_t *tvb, int offset, packet_info *pinfo,
450                  proto_tree *tree, char *drep)
451 {
452         offset = dissect_ndr_uint32(
453                 tvb, offset, pinfo, tree, drep, hf_reserved, NULL);
454
455         return offset;
456 }
457
458 static int
459 dissect_offered(tvbuff_t *tvb, int offset, packet_info *pinfo,
460                 proto_tree *tree, char *drep)
461 {
462         offset = dissect_ndr_uint32(
463                 tvb, offset, pinfo, tree, drep, hf_offered, NULL);
464
465         return offset;
466 }
467
468 static int
469 dissect_returned(tvbuff_t *tvb, int offset, packet_info *pinfo,
470                  proto_tree *tree, char *drep)
471 {
472         offset = dissect_ndr_uint32(
473                 tvb, offset, pinfo, tree, drep, hf_returned, NULL);
474
475         return offset;
476 }
477
478 static int
479 dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
480                 proto_tree *tree, char *drep)
481 {
482         offset = dissect_ndr_uint32(
483                 tvb, offset, pinfo, tree, drep, hf_unknown, NULL);
484
485         return offset;
486 }
487
488 static int
489 RegQueryValue_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
490                 proto_tree *tree, char *drep)
491 {
492         /* Parse packet */
493
494         offset = dissect_nt_policy_hnd(
495                 tvb, offset, pinfo, tree, drep,
496                 hf_hnd, NULL, NULL, FALSE, FALSE);
497
498         offset = dissect_ndr_counted_string(
499                 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
500
501         offset = dissect_ndr_pointer(
502                 tvb, offset, pinfo, tree, drep,
503                 dissect_reserved, NDR_POINTER_UNIQUE,
504                 "Reserved", -1);
505
506         offset = dissect_ndr_pointer(
507                 tvb, offset, pinfo, tree, drep,
508                 dissect_offered, NDR_POINTER_UNIQUE,
509                 "Offered", -1);
510
511         offset = dissect_ndr_pointer(
512                 tvb, offset, pinfo, tree, drep,
513                 dissect_unknown, NDR_POINTER_UNIQUE,
514                 "Unknown", -1);
515
516         offset = dissect_ndr_pointer(
517                 tvb, offset, pinfo, tree, drep,
518                 dissect_unknown, NDR_POINTER_UNIQUE,
519                 "Unknown", -1);
520
521         offset = dissect_ndr_pointer(
522                 tvb, offset, pinfo, tree, drep,
523                 dissect_offered, NDR_POINTER_UNIQUE,
524                 "Offered", -1);
525
526         offset = dissect_ndr_pointer(
527                 tvb, offset, pinfo, tree, drep,
528                 dissect_returned, NDR_POINTER_UNIQUE,
529                 "Returned", -1);
530
531         return offset;
532 }
533
534 static int
535 dissect_key_type(tvbuff_t *tvb, int offset, packet_info *pinfo,
536                  proto_tree *tree, char *drep)
537 {
538         offset = dissect_ndr_uint32(
539                 tvb, offset, pinfo, tree, drep, hf_keytype, NULL);
540
541         return offset;
542 }
543
544 static int
545 RegQueryValue_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
546                 proto_tree *tree, char *drep)
547 {
548         /* Parse packet */
549
550         offset = dissect_ndr_pointer(
551                 tvb, offset, pinfo, tree, drep,
552                 dissect_key_type, NDR_POINTER_UNIQUE,
553                 "Key Type", -1);        
554
555         offset = dissect_ndr_pointer(
556                 tvb, offset, pinfo, tree, drep,
557                 dissect_ndr_byte_array, NDR_POINTER_UNIQUE,
558                 "Key Data", -1);
559
560         offset = dissect_ndr_pointer(
561                 tvb, offset, pinfo, tree, drep,
562                 dissect_offered, NDR_POINTER_UNIQUE,
563                 "Offered", -1);
564
565         offset = dissect_ndr_pointer(
566                 tvb, offset, pinfo, tree, drep,
567                 dissect_returned, NDR_POINTER_UNIQUE,
568                 "Returned", -1);
569
570         offset = dissect_ntstatus(
571                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
572
573         return offset;
574 }
575
576 #if 0
577
578 /* Templates for new subdissectors */
579
580 /*
581  * FOO
582  */
583
584 static int
585 RegFoo_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
586          proto_tree *tree, char *drep)
587 {
588         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
589
590         /* Parse packet */
591
592         return offset;
593 }
594
595 static int
596 RegFoo_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
597          proto_tree *tree, char *drep)
598 {
599         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
600
601         /* Parse packet */
602
603         offset = dissect_ntstatus(
604                 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
605
606         return offset;
607 }
608
609 #endif
610
611 /* Registry data types */
612
613 const value_string reg_datatypes[] = {
614         { DCERPC_REG_NONE, "REG_NONE" },
615         { DCERPC_REG_SZ, "REG_SZ" },
616         { DCERPC_REG_EXPAND_SZ, "REG_EXPAND_SZ" },
617         { DCERPC_REG_BINARY, "REG_BINARY" },
618         { DCERPC_REG_DWORD, "REG_DWORD" },
619         { DCERPC_REG_DWORD_LE, "REG_DWORD_LE" },
620         { DCERPC_REG_DWORD_BE, "REG_DWORD_BE" },
621         { DCERPC_REG_LINK, "REG_LINK" },
622         { DCERPC_REG_MULTI_SZ, "REG_MULTI_SZ" },
623         { DCERPC_REG_RESOURCE_LIST, "REG_RESOURCE_LIST" },
624         { DCERPC_REG_FULL_RESOURCE_DESCRIPTOR, "REG_FULL_RESOURCE_DESCRIPTOR" },
625         { DCERPC_REG_RESOURCE_REQUIREMENTS_LIST, "REG_RESOURCE_REQUIREMENTS_LIST" },
626         {0, NULL }
627 };
628
629 static int proto_dcerpc_reg = -1;
630 static int hf_reg_opnum = -1;
631 static gint ett_dcerpc_reg = -1;
632
633 static e_uuid_t uuid_dcerpc_reg = {
634         0x338cd001, 0x2244, 0x31f1,
635         { 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03 }
636 };
637
638 static guint16 ver_dcerpc_reg = 1;
639
640 static dcerpc_sub_dissector dcerpc_reg_dissectors[] = {
641         { REG_OPEN_HKCR, "OpenHKCR", RegOpenHKCR_q, RegOpenHKCR_r },
642         { REG_OPEN_HKCU, "OpenHKCU", NULL, NULL },
643         { REG_OPEN_HKLM, "OpenHKLM", RegOpenHKLM_q, RegOpenHKLM_r },
644         { REG_OPEN_HKPD, "OpenHKPD", NULL, NULL },
645         { REG_OPEN_HKU, "OpenHKU", RegOpenHKU_q, RegOpenHKU_r },
646         { REG_CLOSE_KEY, "CloseKey", RegCloseKey_q, RegCloseKey_r },
647         { REG_CREATE_KEY, "CreateKey", NULL, NULL },
648         { REG_DELETE_KEY, "DeleteKey", NULL, NULL },
649         { REG_DELETE_VALUE, "DeleteValue", NULL, NULL },
650         { REG_ENUM_KEY, "EnumKey", RegEnumKey_q, RegEnumKey_r },
651         { REG_ENUM_VALUE, "EnumValue", NULL, NULL },
652         { REG_FLUSH_KEY, "FlushKey", NULL, NULL },
653         { REG_GET_KEY_SEC, "GetKeySecurity", NULL, NULL },
654         { REG_LOAD_KEY, "LoadKey", NULL, NULL },
655         { REG_NOTIFY_CHANGE_KEY_VALUE, "NotifyChangeKeyValue", NULL, NULL },
656         { REG_OPEN_KEY, "OpenKey", RegOpenKey_q, RegOpenKey_r },
657         { REG_QUERY_INFO_KEY, "QueryInfoKey", RegQueryInfoKey_q, RegQueryInfoKey_r },
658         { REG_QUERY_VALUE, "QueryValue", RegQueryValue_q, RegQueryValue_r },
659         { REG_REPLACE_KEY, "ReplaceKey", NULL, NULL },
660         { REG_RESTORE_KEY, "RestoreKey", NULL, NULL },
661         { REG_SAVE_KEY, "SaveKey", NULL, NULL },
662         { REG_SET_KEY_SEC, "SetKeySecurity", NULL, NULL },
663         { REG_SET_VALUE, "SetValue", NULL, NULL },
664         { REG_UNLOAD_KEY, "UnLoadKey", NULL, NULL },
665         { REG_INITIATE_SYSTEM_SHUTDOWN, "InitiateSystemShutdown", NULL, NULL },
666         { REG_ABORT_SYSTEM_SHUTDOWN, "AbortSystemShutdown", NULL, NULL },
667         { REG_GET_VERSION, "GetVersion", RegGetVersion_q, RegGetVersion_r },
668         { REG_OPEN_HKCC, "OpenHKCC", NULL, NULL },
669         { REG_OPEN_HKDD, "OpenHKDD", NULL, NULL },
670         { REG_QUERY_MULTIPLE_VALUES, "QueryMultipleValues", NULL, NULL },
671         { REG_INITIATE_SYSTEM_SHUTDOWN_EX, "InitiateSystemShutdownEx", 
672           NULL, NULL },
673         { REG_SAVE_KEY_EX, "SaveKeyEx", NULL, NULL },
674         { REG_OPEN_HKPT, "OpenHKPT", NULL, NULL },
675         { REG_OPEN_HKPN, "OpenHKPN", NULL, NULL },
676         { REG_QUERY_MULTIPLE_VALUES_2, "QueryMultipleValues2", NULL, NULL },
677         { 0, NULL, NULL,  NULL }
678 };
679
680 void
681 proto_register_dcerpc_reg(void)
682 {
683         static hf_register_info hf[] = {
684
685                 /* Global indexes */
686
687                 { &hf_hnd,
688                   { "Context handle", "reg.hnd", FT_BYTES, BASE_NONE,
689                     NULL, 0x0, "REG policy handle", HFILL }},
690
691                 { &hf_rc,
692                   { "Return code", "reg.rc", FT_UINT32, BASE_HEX,
693                     VALS(NT_errors), 0x0, "REG return code", HFILL }},
694
695                 { &hf_reg_opnum,
696                   { "Operation", "reg.opnum", FT_UINT16, BASE_DEC,
697                     NULL, 0x0, "Operation", HFILL }},
698
699                 { &hf_access_mask,
700                   { "Access mask", "reg.access_mask", FT_UINT32, BASE_HEX,
701                     NULL, 0x0, "Access mask", HFILL }},
702
703                 { &hf_keytype,
704                   { "Key type", "reg.type", FT_UINT32, BASE_DEC,
705                     VALS(reg_datatypes), 0x0, "Key type", HFILL }},
706
707                 { &hf_keydata,
708                   { "Key data", "reg.data", FT_BYTES, BASE_HEX,
709                     NULL, 0x0, "Key data", HFILL }},
710
711                 { &hf_offered,
712                   { "Offered", "reg.offered", FT_UINT32, BASE_DEC,
713                     NULL, 0x0, "Offered", HFILL }},
714
715                 { &hf_returned,
716                   { "Returned", "reg.returned", FT_UINT32, BASE_DEC,
717                     NULL, 0x0, "Returned", HFILL }},
718
719                 { &hf_reserved,
720                   { "Reserved", "reg.reserved", FT_UINT32, BASE_HEX,
721                     NULL, 0x0, "Reserved", HFILL }},
722
723                 { &hf_unknown,
724                   { "Unknown", "reg.unknown", FT_UINT32, BASE_HEX,
725                     NULL, 0x0, "Unknown", HFILL }},
726
727                 /* OpenHKLM */
728
729                 { &hf_openhklm_unknown1,
730                   { "Unknown 1", "reg.openhklm.unknown1", FT_UINT16, BASE_HEX,
731                     NULL, 0x0, "Unknown 1", HFILL }},
732
733                 { &hf_openhklm_unknown2,
734                   { "Unknown 2", "reg.openhklm.unknown2", FT_UINT16, BASE_HEX,
735                     NULL, 0x0, "Unknown 2", HFILL }},
736
737                 /* QueryClass */
738
739                 { &hf_querykey_class,
740                   { "Class", "reg.querykey.class", FT_STRING, BASE_NONE,
741                     NULL, 0, "Class", HFILL }},
742
743                 { &hf_querykey_num_subkeys,
744                   { "Num subkeys", "reg.querykey.num_subkeys", FT_UINT32, BASE_DEC,
745                     NULL, 0x0, "Num subkeys", HFILL }},
746
747                 { &hf_querykey_max_subkey_len,
748                   { "Max subkey len", "reg.querykey.max_subkey_len", FT_UINT32, BASE_DEC,
749                     NULL, 0x0, "Max subkey len", HFILL }},
750
751                 { &hf_querykey_reserved,
752                   { "Reserved", "reg.querykey.reserved", FT_UINT32, BASE_DEC,
753                     NULL, 0x0, "Reserved", HFILL }},
754
755                 { &hf_querykey_num_values,
756                   { "Num values", "reg.querykey.num_values", FT_UINT32, BASE_DEC,
757                     NULL, 0x0, "Num values", HFILL }},
758
759                 { &hf_querykey_max_valname_len,
760                   { "Max valnum len", "reg.querykey.max_valname_len", FT_UINT32, BASE_DEC,
761                     NULL, 0x0, "Max valname len", HFILL }},
762
763                 { &hf_querykey_max_valbuf_size,
764                   { "Max valbuf size", "reg.querykey.max_valbuf_size", FT_UINT32, BASE_DEC,
765                     NULL, 0x0, "Max valbuf size", HFILL }},
766
767                 { &hf_querykey_secdesc,
768                   { "Secdesc", "reg.querykey.secdesc", FT_UINT32, BASE_DEC,
769                     NULL, 0x0, "Secdesc", HFILL }},
770
771                 { &hf_querykey_modtime,
772                   { "Mod time", "reg.querykey.modtime", FT_ABSOLUTE_TIME, BASE_NONE,
773                     NULL, 0x0, "Secdesc", HFILL }},
774
775                 /* OpenKey */
776
777                 { &hf_keyname,
778                   { "Key name", "reg.keyname", FT_STRING, BASE_NONE,
779                     NULL, 0x0, "Keyname", HFILL }},
780
781                 { &hf_openkey_unknown1,
782                   { "Unknown 1", "reg.openkey.unknown1", FT_UINT32, BASE_HEX,
783                     NULL, 0x0, "Unknown 1", HFILL }},
784
785                 /* GetVersion */
786
787                 { &hf_getversion_version,
788                   { "Version", "reg.getversion.version", FT_UINT32, BASE_HEX,
789                     NULL, 0x0, "Version", HFILL }},
790
791         };
792
793         static gint *ett[] = {
794                 &ett_dcerpc_reg
795         };
796
797         proto_dcerpc_reg = proto_register_protocol(
798                 "Microsoft Registry", "WINREG", "winreg");
799
800         proto_register_field_array(proto_dcerpc_reg, hf, array_length(hf));
801
802         proto_register_subtree_array(ett, array_length(ett));
803 }
804
805 void
806 proto_reg_handoff_dcerpc_reg(void)
807 {
808         /* Register protocol as dcerpc */
809
810         dcerpc_init_uuid(proto_dcerpc_reg, ett_dcerpc_reg, &uuid_dcerpc_reg,
811                          ver_dcerpc_reg, dcerpc_reg_dissectors, hf_reg_opnum);
812 }