f7dbd5fef315f2037bcd264a085c68ee0aa13129
[libguestfs.git] / hivex / hivex.c
1 /* hivex - Windows Registry "hive" extraction library.
2  * Copyright (C) 2009 Red Hat Inc.
3  * Derived from code by Petter Nordahl-Hagen under a compatible license:
4  *   Copyright (c) 1997-2007 Petter Nordahl-Hagen.
5  * Derived from code by Markus Stephany under a compatible license:
6  *   Copyright (c) 2000-2004, Markus Stephany.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation;
11  * version 2.1 of the License.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * See file LICENSE for the full license.
19  */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stddef.h>
27 #include <inttypes.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <iconv.h>
33 #include <sys/mman.h>
34 #include <sys/stat.h>
35 #include <assert.h>
36 #ifdef HAVE_ENDIAN_H
37 #include <endian.h>
38 #endif
39 #ifdef HAVE_BYTESWAP_H
40 #include <byteswap.h>
41 #endif
42
43 #define STREQ(a,b) (strcmp((a),(b)) == 0)
44 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
45 //#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
46 //#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
47 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
48 //#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
49 //#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
50 //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
51 //#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
52
53 #if __BYTE_ORDER == __LITTLE_ENDIAN
54 #ifndef be32toh
55 #define be32toh(x) __bswap_32 (x)
56 #endif
57 #ifndef be64toh
58 #define be64toh(x) __bswap_64 (x)
59 #endif
60 #ifndef le16toh
61 #define le16toh(x) (x)
62 #endif
63 #ifndef le32toh
64 #define le32toh(x) (x)
65 #endif
66 #ifndef le64toh
67 #define le64toh(x) (x)
68 #endif
69 #else
70 #ifndef be32toh
71 #define be32toh(x) (x)
72 #endif
73 #ifndef be64toh
74 #define be64toh(x) (x)
75 #endif
76 #ifndef le16toh
77 #define le16toh(x) __bswap_16 (x)
78 #endif
79 #ifndef le32toh
80 #define le32toh(x) __bswap_32 (x)
81 #endif
82 #ifndef le64toh
83 #define le64toh(x) __bswap_64 (x)
84 #endif
85 #endif
86
87 #include "hivex.h"
88
89 static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len);
90
91 struct hive_h {
92   char *filename;
93   int fd;
94   size_t size;
95   int msglvl;
96
97   /* Memory-mapped (readonly) registry file. */
98   union {
99     char *addr;
100     struct ntreg_header *hdr;
101   };
102
103   /* Use a bitmap to store which file offsets are valid (point to a
104    * used block).  We only need to store 1 bit per 32 bits of the file
105    * (because blocks are 4-byte aligned).  We found that the average
106    * block size in a registry file is ~50 bytes.  So roughly 1 in 12
107    * bits in the bitmap will be set, making it likely a more efficient
108    * structure than a hash table.
109    */
110   char *bitmap;
111 #define BITMAP_SET(bitmap,off) (bitmap[(off)>>5] |= 1 << (((off)>>2)&7))
112 #define BITMAP_CLR(bitmap,off) (bitmap[(off)>>5] &= ~ (1 << (((off)>>2)&7)))
113 #define BITMAP_TST(bitmap,off) (bitmap[(off)>>5] & (1 << (((off)>>2)&7)))
114 #define IS_VALID_BLOCK(h,off)               \
115   (((off) & 3) == 0 &&                      \
116    (off) >= 0x1000 &&                       \
117    (off) < (h)->size &&                     \
118    BITMAP_TST((h)->bitmap,(off)))
119
120   /* Fields from the header, extracted from little-endianness hell. */
121   size_t rootoffs;              /* Root key offset (always an nk-block). */
122   size_t endpages;              /* Offset of end of pages. */
123 };
124
125 /* NB. All fields are little endian. */
126 struct ntreg_header {
127   char magic[4];                /* "regf" */
128   uint32_t sequence1;
129   uint32_t sequence2;
130   char last_modified[8];
131   uint32_t major_ver;           /* 1 */
132   uint32_t minor_ver;           /* 3 */
133   uint32_t unknown5;            /* 0 */
134   uint32_t unknown6;            /* 1 */
135   uint32_t offset;              /* offset of root key record - 4KB */
136   uint32_t blocks;              /* pointer AFTER last hbin in file - 4KB */
137   uint32_t unknown7;            /* 1 */
138   /* 0x30 */
139   char name[64];                /* original file name of hive */
140   char unknown_guid1[16];
141   char unknown_guid2[16];
142   /* 0x90 */
143   uint32_t unknown8;
144   char unknown_guid3[16];
145   uint32_t unknown9;
146   /* 0xa8 */
147   char unknown10[340];
148   /* 0x1fc */
149   uint32_t csum;                /* checksum: xor of dwords 0-0x1fb. */
150   /* 0x200 */
151   char unknown11[3528];
152   /* 0xfc8 */
153   char unknown_guid4[16];
154   char unknown_guid5[16];
155   char unknown_guid6[16];
156   uint32_t unknown12;
157   uint32_t unknown13;
158   /* 0x1000 */
159 } __attribute__((__packed__));
160
161 struct ntreg_hbin_page {
162   char magic[4];                /* "hbin" */
163   uint32_t offset_first;        /* offset from 1st block */
164   uint32_t page_size;           /* size of this page (multiple of 4KB) */
165   char unknown[20];
166   /* Linked list of blocks follows here. */
167 } __attribute__((__packed__));
168
169 struct ntreg_hbin_block {
170   int32_t seg_len;              /* length of this block (-ve for used block) */
171   char id[2];                   /* the block type (eg. "nk" for nk record) */
172   /* Block data follows here. */
173 } __attribute__((__packed__));
174
175 #define BLOCK_ID_EQ(h,offs,eqid) \
176   (STREQLEN (((struct ntreg_hbin_block *)((h)->addr + (offs)))->id, (eqid), 2))
177
178 static size_t
179 block_len (hive_h *h, size_t blkoff, int *used)
180 {
181   struct ntreg_hbin_block *block;
182   block = (struct ntreg_hbin_block *) (h->addr + blkoff);
183
184   int32_t len = le32toh (block->seg_len);
185   if (len < 0) {
186     if (used) *used = 1;
187     len = -len;
188   } else {
189     if (used) *used = 0;
190   }
191
192   return (size_t) len;
193 }
194
195 struct ntreg_nk_record {
196   int32_t seg_len;              /* length (always -ve because used) */
197   char id[2];                   /* "nk" */
198   uint16_t flags;
199   char timestamp[12];
200   uint32_t parent;              /* offset of owner/parent */
201   uint32_t nr_subkeys;          /* number of subkeys */
202   uint32_t unknown1;
203   uint32_t subkey_lf;           /* lf record containing list of subkeys */
204   uint32_t unknown2;
205   uint32_t nr_values;           /* number of values */
206   uint32_t vallist;             /* value-list record */
207   uint32_t sk;                  /* offset of sk-record */
208   uint32_t classname;           /* offset of classname record */
209   char unknown3[16];
210   uint32_t unknown4;
211   uint16_t name_len;            /* length of name */
212   uint16_t classname_len;       /* length of classname */
213   char name[1];                 /* name follows here */
214 } __attribute__((__packed__));
215
216 struct ntreg_lf_record {
217   int32_t seg_len;
218   char id[2];                   /* "lf" */
219   uint16_t nr_keys;             /* number of keys in this record */
220   struct {
221     uint32_t offset;            /* offset of nk-record for this subkey */
222     char name[4];               /* first 4 characters of subkey name */
223   } keys[1];
224 } __attribute__((__packed__));
225
226 struct ntreg_ri_record {
227   int32_t seg_len;
228   char id[2];                   /* "ri" */
229   uint16_t nr_offsets;          /* number of pointers to lh records */
230   uint32_t offset[1];           /* list of pointers to lh records */
231 } __attribute__((__packed__));
232
233 /* This has no ID header. */
234 struct ntreg_value_list {
235   int32_t seg_len;
236   uint32_t offset[1];           /* list of pointers to vk records */
237 } __attribute__((__packed__));
238
239 struct ntreg_vk_record {
240   int32_t seg_len;              /* length (always -ve because used) */
241   char id[2];                   /* "vk" */
242   uint16_t name_len;            /* length of name */
243   /* length of the data:
244    * If data_len is <= 4, then it's stored inline.
245    * If data_len is 0x80000000, then it's an inline dword.
246    * Top bit may be set or not set at random.
247    */
248   uint32_t data_len;
249   uint32_t data_offset;         /* pointer to the data (or data if inline) */
250   hive_type data_type;          /* type of the data */
251   uint16_t flags;               /* bit 0 set => key name ASCII,
252                                    bit 0 clr => key name UTF-16.
253                                    Only seen ASCII here in the wild. */
254   uint16_t unknown2;
255   char name[1];                 /* key name follows here */
256 } __attribute__((__packed__));
257
258 static uint32_t
259 header_checksum (hive_h *h)
260 {
261   uint32_t *daddr = (uint32_t *) h->addr;
262   size_t i;
263   uint32_t sum = 0;
264
265   for (i = 0; i < 0x1fc / 4; ++i) {
266     sum ^= le32toh (*daddr);
267     daddr++;
268   }
269
270   return sum;
271 }
272
273 hive_h *
274 hivex_open (const char *filename, int flags)
275 {
276   hive_h *h = NULL;
277
278   assert (sizeof (struct ntreg_header) == 0x1000);
279   assert (offsetof (struct ntreg_header, csum) == 0x1fc);
280
281   h = calloc (1, sizeof *h);
282   if (h == NULL)
283     goto error;
284
285   h->msglvl = flags & HIVEX_OPEN_MSGLVL_MASK;
286
287   const char *debug = getenv ("HIVEX_DEBUG");
288   if (debug && STREQ (debug, "1"))
289     h->msglvl = 2;
290
291   if (h->msglvl >= 2)
292     fprintf (stderr, "hivex_open: created handle %p\n", h);
293
294   h->filename = strdup (filename);
295   if (h->filename == NULL)
296     goto error;
297
298   h->fd = open (filename, O_RDONLY);
299   if (h->fd == -1)
300     goto error;
301
302   struct stat statbuf;
303   if (fstat (h->fd, &statbuf) == -1)
304     goto error;
305
306   h->size = statbuf.st_size;
307
308   h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0);
309   if (h->addr == MAP_FAILED)
310     goto error;
311
312   if (h->msglvl >= 2)
313     fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
314
315   /* Check header. */
316   if (h->hdr->magic[0] != 'r' ||
317       h->hdr->magic[1] != 'e' ||
318       h->hdr->magic[2] != 'g' ||
319       h->hdr->magic[3] != 'f') {
320     fprintf (stderr, "hivex: %s: not a Windows NT Registry hive file\n",
321              filename);
322     errno = ENOTSUP;
323     goto error;
324   }
325
326   /* Check major version. */
327   uint32_t major_ver = le32toh (h->hdr->major_ver);
328   if (major_ver != 1) {
329     fprintf (stderr,
330              "hivex: %s: hive file major version %" PRIu32 " (expected 1)\n",
331              filename, major_ver);
332     errno = ENOTSUP;
333     goto error;
334   }
335
336   h->bitmap = calloc (1 + h->size / 32, 1);
337   if (h->bitmap == NULL)
338     goto error;
339
340   /* Header checksum. */
341   uint32_t sum = header_checksum (h);
342   if (sum != le32toh (h->hdr->csum)) {
343     fprintf (stderr, "hivex: %s: bad checksum in hive header\n", filename);
344     errno = EINVAL;
345     goto error;
346   }
347
348   if (h->msglvl >= 2) {
349     char *name = windows_utf16_to_utf8 (h->hdr->name, 64);
350
351     fprintf (stderr,
352              "hivex_open: header fields:\n"
353              "  file version             %" PRIu32 ".%" PRIu32 "\n"
354              "  sequence nos             %" PRIu32 " %" PRIu32 "\n"
355              "    (sequences nos should match if hive was synched at shutdown)\n"
356              "  original file name       %s\n"
357              "    (only 32 chars are stored, name is probably truncated)\n"
358              "  root offset              0x%x + 0x1000\n"
359              "  end of last page         0x%x + 0x1000 (total file size 0x%zx)\n"
360              "  checksum                 0x%x (calculated 0x%x)\n",
361              major_ver, le32toh (h->hdr->minor_ver),
362              le32toh (h->hdr->sequence1), le32toh (h->hdr->sequence2),
363              name ? name : "(conversion failed)",
364              le32toh (h->hdr->offset),
365              le32toh (h->hdr->blocks), h->size,
366              le32toh (h->hdr->csum), sum);
367     free (name);
368   }
369
370   h->rootoffs = le32toh (h->hdr->offset) + 0x1000;
371   h->endpages = le32toh (h->hdr->blocks) + 0x1000;
372
373   if (h->msglvl >= 2)
374     fprintf (stderr, "hivex_open: root offset = 0x%zx\n", h->rootoffs);
375
376   /* We'll set this flag when we see a block with the root offset (ie.
377    * the root block).
378    */
379   int seen_root_block = 0, bad_root_block = 0;
380
381   /* Collect some stats. */
382   size_t pages = 0;           /* Number of hbin pages read. */
383   size_t smallest_page = SIZE_MAX, largest_page = 0;
384   size_t blocks = 0;          /* Total number of blocks found. */
385   size_t smallest_block = SIZE_MAX, largest_block = 0, blocks_bytes = 0;
386   size_t used_blocks = 0;     /* Total number of used blocks found. */
387   size_t used_size = 0;       /* Total size (bytes) of used blocks. */
388
389   /* Read the pages and blocks.  The aim here is to be robust against
390    * corrupt or malicious registries.  So we make sure the loops
391    * always make forward progress.  We add the address of each block
392    * we read to a hash table so pointers will only reference the start
393    * of valid blocks.
394    */
395   size_t off;
396   struct ntreg_hbin_page *page;
397   for (off = 0x1000; off < h->size; off += le32toh (page->page_size)) {
398     if (off >= h->endpages)
399       break;
400
401     page = (struct ntreg_hbin_page *) (h->addr + off);
402     if (page->magic[0] != 'h' ||
403         page->magic[1] != 'b' ||
404         page->magic[2] != 'i' ||
405         page->magic[3] != 'n') {
406       fprintf (stderr, "hivex: %s: trailing garbage at end of file (at 0x%zx, after %zu pages)\n",
407                filename, off, pages);
408       errno = ENOTSUP;
409       goto error;
410     }
411
412     size_t page_size = le32toh (page->page_size);
413     if (h->msglvl >= 2)
414       fprintf (stderr, "hivex_open: page at 0x%zx, size %zu\n", off, page_size);
415     pages++;
416     if (page_size < smallest_page) smallest_page = page_size;
417     if (page_size > largest_page) largest_page = page_size;
418
419     if (page_size <= sizeof (struct ntreg_hbin_page) ||
420         (page_size & 0x0fff) != 0) {
421       fprintf (stderr, "hivex: %s: page size %zu at 0x%zx, bad registry\n",
422                filename, page_size, off);
423       errno = ENOTSUP;
424       goto error;
425     }
426
427     /* Read the blocks in this page. */
428     size_t blkoff;
429     struct ntreg_hbin_block *block;
430     size_t seg_len;
431     for (blkoff = off + 0x20;
432          blkoff < off + page_size;
433          blkoff += seg_len) {
434       blocks++;
435
436       int is_root = blkoff == h->rootoffs;
437       if (is_root)
438         seen_root_block = 1;
439
440       block = (struct ntreg_hbin_block *) (h->addr + blkoff);
441       int used;
442       seg_len = block_len (h, blkoff, &used);
443       if (seg_len <= 4 || (seg_len & 3) != 0) {
444         fprintf (stderr, "hivex: %s: block size %d at %zu, bad registry\n",
445                  filename, le32toh (block->seg_len), blkoff);
446         errno = ENOTSUP;
447         goto error;
448       }
449
450       if (h->msglvl >= 2)
451         fprintf (stderr, "hivex_open: %s block id %d,%d at 0x%zx size %zu%s\n",
452                  used ? "used" : "free", block->id[0], block->id[1], blkoff,
453                  seg_len, is_root ? " (root)" : "");
454
455       blocks_bytes += seg_len;
456       if (seg_len < smallest_block) smallest_block = seg_len;
457       if (seg_len > largest_block) largest_block = seg_len;
458
459       if (is_root && !used)
460         bad_root_block = 1;
461
462       if (used) {
463         used_blocks++;
464         used_size += seg_len;
465
466         /* Root block must be an nk-block. */
467         if (is_root && (block->id[0] != 'n' || block->id[1] != 'k'))
468           bad_root_block = 1;
469
470         /* Note this blkoff is a valid address. */
471         BITMAP_SET (h->bitmap, blkoff);
472       }
473     }
474   }
475
476   if (!seen_root_block) {
477     fprintf (stderr, "hivex: %s: no root block found\n", filename);
478     errno = ENOTSUP;
479     goto error;
480   }
481
482   if (bad_root_block) {
483     fprintf (stderr, "hivex: %s: bad root block (free or not nk)\n", filename);
484     errno = ENOTSUP;
485     goto error;
486   }
487
488   if (h->msglvl >= 1)
489     fprintf (stderr,
490              "hivex_open: successfully read Windows Registry hive file:\n"
491              "  pages:          %zu [sml: %zu, lge: %zu]\n"
492              "  blocks:         %zu [sml: %zu, avg: %zu, lge: %zu]\n"
493              "  blocks used:    %zu\n"
494              "  bytes used:     %zu\n",
495              pages, smallest_page, largest_page,
496              blocks, smallest_block, blocks_bytes / blocks, largest_block,
497              used_blocks, used_size);
498
499   return h;
500
501  error:;
502   int err = errno;
503   if (h) {
504     free (h->bitmap);
505     if (h->addr && h->size && h->addr != MAP_FAILED)
506       munmap (h->addr, h->size);
507     if (h->fd >= 0)
508       close (h->fd);
509     free (h->filename);
510     free (h);
511   }
512   errno = err;
513   return NULL;
514 }
515
516 int
517 hivex_close (hive_h *h)
518 {
519   int r;
520
521   free (h->bitmap);
522   munmap (h->addr, h->size);
523   r = close (h->fd);
524   free (h->filename);
525   free (h);
526
527   return r;
528 }
529
530 hive_node_h
531 hivex_root (hive_h *h)
532 {
533   hive_node_h ret = h->rootoffs;
534   if (!IS_VALID_BLOCK (h, ret)) {
535     errno = ENOKEY;
536     return 0;
537   }
538   return ret;
539 }
540
541 char *
542 hivex_node_name (hive_h *h, hive_node_h node)
543 {
544   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
545     errno = EINVAL;
546     return NULL;
547   }
548
549   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
550
551   /* AFAIK the node name is always plain ASCII, so no conversion
552    * to UTF-8 is necessary.  However we do need to nul-terminate
553    * the string.
554    */
555
556   /* nk->name_len is unsigned, 16 bit, so this is safe ...  However
557    * we have to make sure the length doesn't exceed the block length.
558    */
559   size_t len = le16toh (nk->name_len);
560   size_t seg_len = block_len (h, node, NULL);
561   if (sizeof (struct ntreg_nk_record) + len - 1 > seg_len) {
562     if (h->msglvl >= 2)
563       fprintf (stderr, "hivex_node_name: returning EFAULT because node name is too long (%zu, %zu)\n",
564               len, seg_len);
565     errno = EFAULT;
566     return NULL;
567   }
568
569   char *ret = malloc (len + 1);
570   if (ret == NULL)
571     return NULL;
572   memcpy (ret, nk->name, len);
573   ret[len] = '\0';
574   return ret;
575 }
576
577 #if 0
578 /* I think the documentation for the sk and classname fields in the nk
579  * record is wrong, or else the offset field is in the wrong place.
580  * Otherwise this makes no sense.  Disabled this for now -- it's not
581  * useful for reading the registry anyway.
582  */
583
584 hive_security_h
585 hivex_node_security (hive_h *h, hive_node_h node)
586 {
587   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
588     errno = EINVAL;
589     return 0;
590   }
591
592   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
593
594   hive_node_h ret = le32toh (nk->sk);
595   ret += 0x1000;
596   if (!IS_VALID_BLOCK (h, ret)) {
597     errno = EFAULT;
598     return 0;
599   }
600   return ret;
601 }
602
603 hive_classname_h
604 hivex_node_classname (hive_h *h, hive_node_h node)
605 {
606   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
607     errno = EINVAL;
608     return 0;
609   }
610
611   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
612
613   hive_node_h ret = le32toh (nk->classname);
614   ret += 0x1000;
615   if (!IS_VALID_BLOCK (h, ret)) {
616     errno = EFAULT;
617     return 0;
618   }
619   return ret;
620 }
621 #endif
622
623 hive_node_h *
624 hivex_node_children (hive_h *h, hive_node_h node)
625 {
626   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
627     errno = EINVAL;
628     return NULL;
629   }
630
631   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
632
633   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
634
635   /* Deal with the common "no subkeys" case quickly. */
636   hive_node_h *ret;
637   if (nr_subkeys_in_nk == 0) {
638     ret = malloc (sizeof (hive_node_h));
639     if (ret == NULL)
640       return NULL;
641     ret[0] = 0;
642     return ret;
643   }
644
645   /* Arbitrarily limit the number of subkeys we will ever deal with. */
646   if (nr_subkeys_in_nk > 1000000) {
647     errno = ERANGE;
648     return NULL;
649   }
650
651   /* The subkey_lf field can point either to an lf-record, which is
652    * the common case, or if there are lots of subkeys, to an
653    * ri-record.
654    */
655   size_t subkey_lf = le32toh (nk->subkey_lf);
656   subkey_lf += 0x1000;
657   if (!IS_VALID_BLOCK (h, subkey_lf)) {
658     if (h->msglvl >= 2)
659       fprintf (stderr, "hivex_node_children: returning EFAULT because subkey_lf is not a valid block (%zu)\n",
660                subkey_lf);
661     errno = EFAULT;
662     return NULL;
663   }
664
665   struct ntreg_hbin_block *block =
666     (struct ntreg_hbin_block *) (h->addr + subkey_lf);
667
668   /* Points to lf-record?  (Note, also "lh" but that is basically the
669    * same as "lf" as far as we are concerned here).
670    */
671   if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
672     struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
673
674     /* Check number of subkeys in the nk-record matches number of subkeys
675      * in the lf-record.
676      */
677     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
678
679     if (h->msglvl >= 2)
680       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, nr_subkeys_in_lf = %zu\n",
681                nr_subkeys_in_nk, nr_subkeys_in_lf);
682
683     if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
684       errno = ENOTSUP;
685       return NULL;
686     }
687
688     size_t len = block_len (h, subkey_lf, NULL);
689     if (8 + nr_subkeys_in_lf * 8 > len) {
690       if (h->msglvl >= 2)
691         fprintf (stderr, "hivex_node_children: returning EFAULT because too many subkeys (%zu, %zu)\n",
692                  nr_subkeys_in_lf, len);
693       errno = EFAULT;
694       return NULL;
695     }
696
697     /* Allocate space for the returned values.  Note that
698      * nr_subkeys_in_lf is limited to a 16 bit value.
699      */
700     ret = malloc ((1 + nr_subkeys_in_lf) * sizeof (hive_node_h));
701     if (ret == NULL)
702       return NULL;
703
704     size_t i;
705     for (i = 0; i < nr_subkeys_in_lf; ++i) {
706       hive_node_h subkey = lf->keys[i].offset;
707       subkey += 0x1000;
708       if (!IS_VALID_BLOCK (h, subkey)) {
709         if (h->msglvl >= 2)
710           fprintf (stderr, "hivex_node_children: returning EFAULT because subkey is not a valid block (0x%zx)\n",
711                    subkey);
712         errno = EFAULT;
713         free (ret);
714         return NULL;
715       }
716       ret[i] = subkey;
717     }
718     ret[i] = 0;
719     return ret;
720   }
721   /* Points to ri-record? */
722   else if (block->id[0] == 'r' && block->id[1] == 'i') {
723     struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block;
724
725     size_t nr_offsets = le16toh (ri->nr_offsets);
726
727     /* Count total number of children. */
728     size_t i, count = 0;
729     for (i = 0; i < nr_offsets; ++i) {
730       hive_node_h offset = ri->offset[i];
731       offset += 0x1000;
732       if (!IS_VALID_BLOCK (h, offset)) {
733         if (h->msglvl >= 2)
734           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
735                    offset);
736         errno = EFAULT;
737         return NULL;
738       }
739       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
740         errno = ENOTSUP;
741         return NULL;
742       }
743
744       struct ntreg_lf_record *lf =
745         (struct ntreg_lf_record *) (h->addr + offset);
746
747       count += le16toh (lf->nr_keys);
748     }
749
750     if (h->msglvl >= 2)
751       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, counted = %zu\n",
752                nr_subkeys_in_nk, count);
753
754     if (nr_subkeys_in_nk != count) {
755       errno = ENOTSUP;
756       return NULL;
757     }
758
759     /* Copy list of children.  Note nr_subkeys_in_nk is limited to
760      * something reasonable above.
761      */
762     ret = malloc ((1 + nr_subkeys_in_nk) * sizeof (hive_node_h));
763     if (ret == NULL)
764       return NULL;
765
766     count = 0;
767     for (i = 0; i < nr_offsets; ++i) {
768       hive_node_h offset = ri->offset[i];
769       offset += 0x1000;
770       if (!IS_VALID_BLOCK (h, offset)) {
771         if (h->msglvl >= 2)
772           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
773                    offset);
774         errno = EFAULT;
775         return NULL;
776       }
777       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
778         errno = ENOTSUP;
779         return NULL;
780       }
781
782       struct ntreg_lf_record *lf =
783         (struct ntreg_lf_record *) (h->addr + offset);
784
785       size_t j;
786       for (j = 0; j < le16toh (lf->nr_keys); ++j) {
787         hive_node_h subkey = lf->keys[j].offset;
788         subkey += 0x1000;
789         if (!IS_VALID_BLOCK (h, subkey)) {
790           if (h->msglvl >= 2)
791             fprintf (stderr, "hivex_node_children: returning EFAULT because indirect subkey is not a valid block (0x%zx)\n",
792                      subkey);
793           errno = EFAULT;
794           free (ret);
795           return NULL;
796         }
797         ret[count++] = subkey;
798       }
799     }
800     ret[count] = 0;
801
802     return ret;
803   }
804   else {
805     errno = ENOTSUP;
806     return NULL;
807   }
808 }
809
810 /* Very inefficient, but at least having a separate API call
811  * allows us to make it more efficient in future.
812  */
813 hive_node_h
814 hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
815 {
816   hive_node_h *children = NULL;
817   char *name = NULL;
818   hive_node_h ret = 0;
819
820   children = hivex_node_children (h, node);
821   if (!children) goto error;
822
823   size_t i;
824   for (i = 0; children[i] != 0; ++i) {
825     name = hivex_node_name (h, children[i]);
826     if (!name) goto error;
827     if (STRCASEEQ (name, nname)) {
828       ret = children[i];
829       break;
830     }
831     free (name); name = NULL;
832   }
833
834  error:
835   free (children);
836   free (name);
837   return ret;
838 }
839
840 hive_node_h
841 hivex_node_parent (hive_h *h, hive_node_h node)
842 {
843   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
844     errno = EINVAL;
845     return 0;
846   }
847
848   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
849
850   hive_node_h ret = le32toh (nk->parent);
851   ret += 0x1000;
852   if (!IS_VALID_BLOCK (h, ret)) {
853     if (h->msglvl >= 2)
854       fprintf (stderr, "hivex_node_parent: returning EFAULT because parent is not a valid block (0x%zx)\n",
855               ret);
856     errno = EFAULT;
857     return 0;
858   }
859   return ret;
860 }
861
862 hive_value_h *
863 hivex_node_values (hive_h *h, hive_node_h node)
864 {
865   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
866     errno = EINVAL;
867     return 0;
868   }
869
870   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
871
872   size_t nr_values = le32toh (nk->nr_values);
873
874   if (h->msglvl >= 2)
875     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
876
877   /* Deal with the common "no values" case quickly. */
878   hive_node_h *ret;
879   if (nr_values == 0) {
880     ret = malloc (sizeof (hive_node_h));
881     if (ret == NULL)
882       return NULL;
883     ret[0] = 0;
884     return ret;
885   }
886
887   /* Arbitrarily limit the number of values we will ever deal with. */
888   if (nr_values > 100000) {
889     errno = ERANGE;
890     return NULL;
891   }
892
893   /* Get the value list and check it looks reasonable. */
894   size_t vlist_offset = le32toh (nk->vallist);
895   vlist_offset += 0x1000;
896   if (!IS_VALID_BLOCK (h, vlist_offset)) {
897     if (h->msglvl >= 2)
898       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is not a valid block (0x%zx)\n",
899                vlist_offset);
900     errno = EFAULT;
901     return NULL;
902   }
903
904   struct ntreg_value_list *vlist =
905     (struct ntreg_value_list *) (h->addr + vlist_offset);
906
907   size_t len = block_len (h, vlist_offset, NULL);
908   if (4 + nr_values * 4 > len) {
909     if (h->msglvl >= 2)
910       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is too long (%zu, %zu)\n",
911                nr_values, len);
912     errno = EFAULT;
913     return NULL;
914   }
915
916   /* Allocate return array and copy values in. */
917   ret = malloc ((1 + nr_values) * sizeof (hive_node_h));
918   if (ret == NULL)
919     return NULL;
920
921   size_t i;
922   for (i = 0; i < nr_values; ++i) {
923     hive_node_h value = vlist->offset[i];
924     value += 0x1000;
925     if (!IS_VALID_BLOCK (h, value)) {
926       if (h->msglvl >= 2)
927         fprintf (stderr, "hivex_node_values: returning EFAULT because value is not a valid block (0x%zx)\n",
928                  value);
929       errno = EFAULT;
930       free (ret);
931       return NULL;
932     }
933     ret[i] = value;
934   }
935
936   ret[i] = 0;
937   return ret;
938 }
939
940 /* Very inefficient, but at least having a separate API call
941  * allows us to make it more efficient in future.
942  */
943 hive_value_h
944 hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
945 {
946   hive_value_h *values = NULL;
947   char *name = NULL;
948   hive_value_h ret = 0;
949
950   values = hivex_node_values (h, node);
951   if (!values) goto error;
952
953   size_t i;
954   for (i = 0; values[i] != 0; ++i) {
955     name = hivex_value_key (h, values[i]);
956     if (!name) goto error;
957     if (STRCASEEQ (name, key)) {
958       ret = values[i];
959       break;
960     }
961     free (name); name = NULL;
962   }
963
964  error:
965   free (values);
966   free (name);
967   return ret;
968 }
969
970 char *
971 hivex_value_key (hive_h *h, hive_value_h value)
972 {
973   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
974     errno = EINVAL;
975     return 0;
976   }
977
978   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
979
980   /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
981    * necessary.  However we do need to nul-terminate the string.
982    */
983
984   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
985    * we have to make sure the length doesn't exceed the block length.
986    */
987   size_t len = le16toh (vk->name_len);
988   size_t seg_len = block_len (h, value, NULL);
989   if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
990     if (h->msglvl >= 2)
991       fprintf (stderr, "hivex_value_key: returning EFAULT because key length is too long (%zu, %zu)\n",
992                len, seg_len);
993     errno = EFAULT;
994     return NULL;
995   }
996
997   char *ret = malloc (len + 1);
998   if (ret == NULL)
999     return NULL;
1000   memcpy (ret, vk->name, len);
1001   ret[len] = '\0';
1002   return ret;
1003 }
1004
1005 int
1006 hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
1007 {
1008   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1009     errno = EINVAL;
1010     return -1;
1011   }
1012
1013   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1014
1015   if (t)
1016     *t = le32toh (vk->data_type);
1017
1018   if (len) {
1019     *len = le32toh (vk->data_len);
1020     if (*len == 0x80000000) {   /* special case */
1021       *len = 4;
1022       if (t) *t = hive_t_dword;
1023     }
1024     *len &= 0x7fffffff;
1025   }
1026
1027   return 0;
1028 }
1029
1030 char *
1031 hivex_value_value (hive_h *h, hive_value_h value,
1032                    hive_type *t_rtn, size_t *len_rtn)
1033 {
1034   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1035     errno = EINVAL;
1036     return NULL;
1037   }
1038
1039   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1040
1041   hive_type t;
1042   size_t len;
1043
1044   t = le32toh (vk->data_type);
1045
1046   len = le32toh (vk->data_len);
1047   if (len == 0x80000000) {      /* special case */
1048     len = 4;
1049     t = hive_t_dword;
1050   }
1051   len &= 0x7fffffff;
1052
1053   if (h->msglvl >= 2)
1054     fprintf (stderr, "hivex_value_value: value=0x%zx, t=%d, len=%zu\n",
1055              value, t, len);
1056
1057   if (t_rtn)
1058     *t_rtn = t;
1059   if (len_rtn)
1060     *len_rtn = len;
1061
1062   /* Arbitrarily limit the length that we will read. */
1063   if (len > 1000000) {
1064     errno = ERANGE;
1065     return NULL;
1066   }
1067
1068   char *ret = malloc (len);
1069   if (ret == NULL)
1070     return NULL;
1071
1072   /* If length is <= 4 it's always stored inline. */
1073   if (len <= 4) {
1074     memcpy (ret, (char *) &vk->data_offset, len);
1075     return ret;
1076   }
1077
1078   size_t data_offset = vk->data_offset;
1079   data_offset += 0x1000;
1080   if (!IS_VALID_BLOCK (h, data_offset)) {
1081     if (h->msglvl >= 2)
1082       fprintf (stderr, "hivex_value_value: returning EFAULT because data offset is not a valid block (0x%zx)\n",
1083                data_offset);
1084     errno = EFAULT;
1085     free (ret);
1086     return NULL;
1087   }
1088
1089   /* Check that the declared size isn't larger than the block its in. */
1090   size_t blen = block_len (h, data_offset, NULL);
1091   if (len > blen) {
1092     if (h->msglvl >= 2)
1093       fprintf (stderr, "hivex_value_value: returning EFAULT because data is longer than its block (data 0x%zx, data len %zu, block len %zu)\n",
1094                data_offset, len, blen);
1095     errno = EFAULT;
1096     free (ret);
1097     return NULL;
1098   }
1099
1100   char *data = h->addr + data_offset + 4;
1101   memcpy (ret, data, len);
1102   return ret;
1103 }
1104
1105 static char *
1106 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1107 {
1108   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1109   if (ic == (iconv_t) -1)
1110     return NULL;
1111
1112   /* iconv(3) has an insane interface ... */
1113
1114   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1115   size_t outalloc = len;
1116
1117  again:;
1118   size_t inlen = len;
1119   size_t outlen = outalloc;
1120   char *out = malloc (outlen + 1);
1121   if (out == NULL) {
1122     int err = errno;
1123     iconv_close (ic);
1124     errno = err;
1125     return NULL;
1126   }
1127   char *inp = input;
1128   char *outp = out;
1129
1130   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1131   if (r == (size_t) -1) {
1132     if (errno == E2BIG) {
1133       size_t prev = outalloc;
1134       /* Try again with a larger output buffer. */
1135       free (out);
1136       outalloc *= 2;
1137       if (outalloc < prev)
1138         return NULL;
1139       goto again;
1140     }
1141     else {
1142       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1143       int err = errno;
1144       iconv_close (ic);
1145       free (out);
1146       errno = err;
1147       return NULL;
1148     }
1149   }
1150
1151   *outp = '\0';
1152   iconv_close (ic);
1153
1154   return out;
1155 }
1156
1157 char *
1158 hivex_value_string (hive_h *h, hive_value_h value)
1159 {
1160   hive_type t;
1161   size_t len;
1162   char *data = hivex_value_value (h, value, &t, &len);
1163
1164   if (data == NULL)
1165     return NULL;
1166
1167   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1168     free (data);
1169     errno = EINVAL;
1170     return NULL;
1171   }
1172
1173   char *ret = windows_utf16_to_utf8 (data, len);
1174   free (data);
1175   if (ret == NULL)
1176     return NULL;
1177
1178   return ret;
1179 }
1180
1181 static void
1182 free_strings (char **argv)
1183 {
1184   if (argv) {
1185     size_t i;
1186
1187     for (i = 0; argv[i] != NULL; ++i)
1188       free (argv[i]);
1189     free (argv);
1190   }
1191 }
1192
1193 /* Get the length of a UTF-16 format string.  Handle the string as
1194  * pairs of bytes, looking for the first \0\0 pair.
1195  */
1196 static size_t
1197 utf16_string_len_in_bytes (const char *str)
1198 {
1199   size_t ret = 0;
1200
1201   while (str[0] || str[1]) {
1202     str += 2;
1203     ret += 2;
1204   }
1205
1206   return ret;
1207 }
1208
1209 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1210 char **
1211 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1212 {
1213   hive_type t;
1214   size_t len;
1215   char *data = hivex_value_value (h, value, &t, &len);
1216
1217   if (data == NULL)
1218     return NULL;
1219
1220   if (t != hive_t_multiple_strings) {
1221     free (data);
1222     errno = EINVAL;
1223     return NULL;
1224   }
1225
1226   size_t nr_strings = 0;
1227   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1228   if (ret == NULL) {
1229     free (data);
1230     return NULL;
1231   }
1232   ret[0] = NULL;
1233
1234   char *p = data;
1235   size_t plen;
1236
1237   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1238     nr_strings++;
1239     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1240     if (ret2 == NULL) {
1241       free_strings (ret);
1242       free (data);
1243       return NULL;
1244     }
1245     ret = ret2;
1246
1247     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1248     ret[nr_strings] = NULL;
1249     if (ret[nr_strings-1] == NULL) {
1250       free_strings (ret);
1251       free (data);
1252       return NULL;
1253     }
1254
1255     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1256   }
1257
1258   free (data);
1259   return ret;
1260 }
1261
1262 int32_t
1263 hivex_value_dword (hive_h *h, hive_value_h value)
1264 {
1265   hive_type t;
1266   size_t len;
1267   char *data = hivex_value_value (h, value, &t, &len);
1268
1269   if (data == NULL)
1270     return -1;
1271
1272   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1273     free (data);
1274     errno = EINVAL;
1275     return -1;
1276   }
1277
1278   int32_t ret = *(int32_t*)data;
1279   free (data);
1280   if (t == hive_t_dword)        /* little endian */
1281     ret = le32toh (ret);
1282   else
1283     ret = be32toh (ret);
1284
1285   return ret;
1286 }
1287
1288 int64_t
1289 hivex_value_qword (hive_h *h, hive_value_h value)
1290 {
1291   hive_type t;
1292   size_t len;
1293   char *data = hivex_value_value (h, value, &t, &len);
1294
1295   if (data == NULL)
1296     return -1;
1297
1298   if (t != hive_t_qword || len != 8) {
1299     free (data);
1300     errno = EINVAL;
1301     return -1;
1302   }
1303
1304   int64_t ret = *(int64_t*)data;
1305   free (data);
1306   ret = le64toh (ret);          /* always little endian */
1307
1308   return ret;
1309 }
1310
1311 int
1312 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1313              void *opaque, int flags)
1314 {
1315   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1316 }
1317
1318 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1319
1320 int
1321 hivex_visit_node (hive_h *h, hive_node_h node,
1322                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1323                   int flags)
1324 {
1325   struct hivex_visitor vtor;
1326   memset (&vtor, 0, sizeof vtor);
1327
1328   /* Note that len might be larger *or smaller* than the expected size. */
1329   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1330   memcpy (&vtor, visitor, copysize);
1331
1332   /* This bitmap records unvisited nodes, so we don't loop if the
1333    * registry contains cycles.
1334    */
1335   char *unvisited = malloc (1 + h->size / 32);
1336   if (unvisited == NULL)
1337     return -1;
1338   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1339
1340   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1341   free (unvisited);
1342   return r;
1343 }
1344
1345 static int
1346 hivex__visit_node (hive_h *h, hive_node_h node,
1347                    const struct hivex_visitor *vtor, char *unvisited,
1348                    void *opaque, int flags)
1349 {
1350   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1351   char *name = NULL;
1352   hive_value_h *values = NULL;
1353   hive_node_h *children = NULL;
1354   char *key = NULL;
1355   char *str = NULL;
1356   char **strs = NULL;
1357   int i;
1358
1359   /* Return -1 on all callback errors.  However on internal errors,
1360    * check if skip_bad is set and suppress those errors if so.
1361    */
1362   int ret = -1;
1363
1364   if (!BITMAP_TST (unvisited, node)) {
1365     if (h->msglvl >= 2)
1366       fprintf (stderr, "hivex__visit_node: contains cycle: visited node 0x%zx already\n",
1367                node);
1368
1369     errno = ELOOP;
1370     return skip_bad ? 0 : -1;
1371   }
1372   BITMAP_CLR (unvisited, node);
1373
1374   name = hivex_node_name (h, node);
1375   if (!name) return skip_bad ? 0 : -1;
1376   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1377     goto error;
1378
1379   values = hivex_node_values (h, node);
1380   if (!values) {
1381     ret = skip_bad ? 0 : -1;
1382     goto error;
1383   }
1384
1385   for (i = 0; values[i] != 0; ++i) {
1386     hive_type t;
1387     size_t len;
1388
1389     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1390       ret = skip_bad ? 0 : -1;
1391       goto error;
1392     }
1393
1394     key = hivex_value_key (h, values[i]);
1395     if (key == NULL) {
1396       ret = skip_bad ? 0 : -1;
1397       goto error;
1398     }
1399
1400     if (vtor->value_any) {
1401       str = hivex_value_value (h, values[i], &t, &len);
1402       if (str == NULL) {
1403         ret = skip_bad ? 0 : -1;
1404         goto error;
1405       }
1406       if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
1407         goto error;
1408       free (str); str = NULL;
1409     }
1410     else {
1411       switch (t) {
1412       case hive_t_none:
1413         str = hivex_value_value (h, values[i], &t, &len);
1414         if (str == NULL) {
1415           ret = skip_bad ? 0 : -1;
1416           goto error;
1417         }
1418         if (t != hive_t_none) {
1419           ret = skip_bad ? 0 : -1;
1420           goto error;
1421         }
1422         if (vtor->value_none &&
1423             vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1424           goto error;
1425         free (str); str = NULL;
1426         break;
1427
1428       case hive_t_string:
1429       case hive_t_expand_string:
1430       case hive_t_link:
1431         str = hivex_value_string (h, values[i]);
1432         if (str == NULL) {
1433           if (errno != EILSEQ && errno != EINVAL) {
1434             ret = skip_bad ? 0 : -1;
1435             goto error;
1436           }
1437           if (vtor->value_string_invalid_utf16) {
1438             str = hivex_value_value (h, values[i], &t, &len);
1439             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1440               goto error;
1441             free (str); str = NULL;
1442           }
1443           break;
1444         }
1445         if (vtor->value_string &&
1446             vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1447           goto error;
1448         free (str); str = NULL;
1449         break;
1450
1451       case hive_t_dword:
1452       case hive_t_dword_be: {
1453         int32_t i32 = hivex_value_dword (h, values[i]);
1454         if (vtor->value_dword &&
1455             vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1456           goto error;
1457         break;
1458       }
1459
1460       case hive_t_qword: {
1461         int64_t i64 = hivex_value_qword (h, values[i]);
1462         if (vtor->value_qword &&
1463             vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1464           goto error;
1465         break;
1466       }
1467
1468       case hive_t_binary:
1469         str = hivex_value_value (h, values[i], &t, &len);
1470         if (str == NULL) {
1471           ret = skip_bad ? 0 : -1;
1472           goto error;
1473         }
1474         if (t != hive_t_binary) {
1475           ret = skip_bad ? 0 : -1;
1476           goto error;
1477         }
1478         if (vtor->value_binary &&
1479             vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1480           goto error;
1481         free (str); str = NULL;
1482         break;
1483
1484       case hive_t_multiple_strings:
1485         strs = hivex_value_multiple_strings (h, values[i]);
1486         if (strs == NULL) {
1487           if (errno != EILSEQ && errno != EINVAL) {
1488             ret = skip_bad ? 0 : -1;
1489             goto error;
1490           }
1491           if (vtor->value_string_invalid_utf16) {
1492             str = hivex_value_value (h, values[i], &t, &len);
1493             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1494               goto error;
1495             free (str); str = NULL;
1496           }
1497           break;
1498         }
1499         if (vtor->value_multiple_strings &&
1500             vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1501           goto error;
1502         free_strings (strs); strs = NULL;
1503         break;
1504
1505       case hive_t_resource_list:
1506       case hive_t_full_resource_description:
1507       case hive_t_resource_requirements_list:
1508       default:
1509         str = hivex_value_value (h, values[i], &t, &len);
1510         if (str == NULL) {
1511           ret = skip_bad ? 0 : -1;
1512           goto error;
1513         }
1514         if (vtor->value_other &&
1515             vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1516           goto error;
1517         free (str); str = NULL;
1518         break;
1519       }
1520     }
1521
1522     free (key); key = NULL;
1523   }
1524
1525   children = hivex_node_children (h, node);
1526   if (children == NULL) {
1527     ret = skip_bad ? 0 : -1;
1528     goto error;
1529   }
1530
1531   for (i = 0; children[i] != 0; ++i) {
1532     if (h->msglvl >= 2)
1533       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n",
1534                name, i, children[i]);
1535
1536     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1537       goto error;
1538   }
1539
1540   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1541     goto error;
1542
1543   ret = 0;
1544
1545  error:
1546   free (name);
1547   free (values);
1548   free (children);
1549   free (key);
1550   free (str);
1551   free_strings (strs);
1552   return ret;
1553 }