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