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