hivex: Don't die on valid registries which have bad declared data lengths.
[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 #include "full-read.h"
38 #include "full-write.h"
39
40 #ifndef O_CLOEXEC
41 #define O_CLOEXEC 0
42 #endif
43
44 #define STREQ(a,b) (strcmp((a),(b)) == 0)
45 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
46 //#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
47 //#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
48 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
49 //#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
50 //#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
51 //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
52 //#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
53
54 #include "hivex.h"
55 #include "byte_conversions.h"
56
57 static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len);
58
59 struct hive_h {
60   char *filename;
61   int fd;
62   size_t size;
63   int msglvl;
64   int writable;
65
66   /* Registry file, memory mapped if read-only, or malloc'd if writing. */
67   union {
68     char *addr;
69     struct ntreg_header *hdr;
70   };
71
72   /* Use a bitmap to store which file offsets are valid (point to a
73    * used block).  We only need to store 1 bit per 32 bits of the file
74    * (because blocks are 4-byte aligned).  We found that the average
75    * block size in a registry file is ~50 bytes.  So roughly 1 in 12
76    * bits in the bitmap will be set, making it likely a more efficient
77    * structure than a hash table.
78    */
79   char *bitmap;
80 #define BITMAP_SET(bitmap,off) (bitmap[(off)>>5] |= 1 << (((off)>>2)&7))
81 #define BITMAP_CLR(bitmap,off) (bitmap[(off)>>5] &= ~ (1 << (((off)>>2)&7)))
82 #define BITMAP_TST(bitmap,off) (bitmap[(off)>>5] & (1 << (((off)>>2)&7)))
83 #define IS_VALID_BLOCK(h,off)               \
84   (((off) & 3) == 0 &&                      \
85    (off) >= 0x1000 &&                       \
86    (off) < (h)->size &&                     \
87    BITMAP_TST((h)->bitmap,(off)))
88
89   /* Fields from the header, extracted from little-endianness hell. */
90   size_t rootoffs;              /* Root key offset (always an nk-block). */
91   size_t endpages;              /* Offset of end of pages. */
92
93   /* For writing. */
94   size_t endblocks;             /* Offset to next block allocation (0
95                                    if not allocated anything yet). */
96 };
97
98 /* NB. All fields are little endian. */
99 struct ntreg_header {
100   char magic[4];                /* "regf" */
101   uint32_t sequence1;
102   uint32_t sequence2;
103   char last_modified[8];
104   uint32_t major_ver;           /* 1 */
105   uint32_t minor_ver;           /* 3 */
106   uint32_t unknown5;            /* 0 */
107   uint32_t unknown6;            /* 1 */
108   uint32_t offset;              /* offset of root key record - 4KB */
109   uint32_t blocks;              /* pointer AFTER last hbin in file - 4KB */
110   uint32_t unknown7;            /* 1 */
111   /* 0x30 */
112   char name[64];                /* original file name of hive */
113   char unknown_guid1[16];
114   char unknown_guid2[16];
115   /* 0x90 */
116   uint32_t unknown8;
117   char unknown_guid3[16];
118   uint32_t unknown9;
119   /* 0xa8 */
120   char unknown10[340];
121   /* 0x1fc */
122   uint32_t csum;                /* checksum: xor of dwords 0-0x1fb. */
123   /* 0x200 */
124   char unknown11[3528];
125   /* 0xfc8 */
126   char unknown_guid4[16];
127   char unknown_guid5[16];
128   char unknown_guid6[16];
129   uint32_t unknown12;
130   uint32_t unknown13;
131   /* 0x1000 */
132 } __attribute__((__packed__));
133
134 struct ntreg_hbin_page {
135   char magic[4];                /* "hbin" */
136   uint32_t offset_first;        /* offset from 1st block */
137   uint32_t page_size;           /* size of this page (multiple of 4KB) */
138   char unknown[20];
139   /* Linked list of blocks follows here. */
140 } __attribute__((__packed__));
141
142 struct ntreg_hbin_block {
143   int32_t seg_len;              /* length of this block (-ve for used block) */
144   char id[2];                   /* the block type (eg. "nk" for nk record) */
145   /* Block data follows here. */
146 } __attribute__((__packed__));
147
148 #define BLOCK_ID_EQ(h,offs,eqid) \
149   (STREQLEN (((struct ntreg_hbin_block *)((h)->addr + (offs)))->id, (eqid), 2))
150
151 static size_t
152 block_len (hive_h *h, size_t blkoff, int *used)
153 {
154   struct ntreg_hbin_block *block;
155   block = (struct ntreg_hbin_block *) (h->addr + blkoff);
156
157   int32_t len = le32toh (block->seg_len);
158   if (len < 0) {
159     if (used) *used = 1;
160     len = -len;
161   } else {
162     if (used) *used = 0;
163   }
164
165   return (size_t) len;
166 }
167
168 struct ntreg_nk_record {
169   int32_t seg_len;              /* length (always -ve because used) */
170   char id[2];                   /* "nk" */
171   uint16_t flags;
172   char timestamp[8];
173   uint32_t unknown1;
174   uint32_t parent;              /* offset of owner/parent */
175   uint32_t nr_subkeys;          /* number of subkeys */
176   uint32_t nr_subkeys_volatile;
177   uint32_t subkey_lf;           /* lf record containing list of subkeys */
178   uint32_t subkey_lf_volatile;
179   uint32_t nr_values;           /* number of values */
180   uint32_t vallist;             /* value-list record */
181   uint32_t sk;                  /* offset of sk-record */
182   uint32_t classname;           /* offset of classname record */
183   uint16_t max_subkey_name_len; /* maximum length of a subkey name in bytes
184                                    if the subkey was reencoded as UTF-16LE */
185   uint16_t unknown2;
186   uint32_t unknown3;
187   uint32_t max_vk_name_len;     /* maximum length of any vk name in bytes
188                                    if the name was reencoded as UTF-16LE */
189   uint32_t max_vk_data_len;     /* maximum length of any vk data in bytes */
190   uint32_t unknown6;
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 hash[4];               /* hash 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   uint32_t data_type;           /* type of the data */
231   uint16_t flags;               /* bit 0 set => key name ASCII,
232                                    bit 0 clr => key name UTF-16.
233                                    Only seen ASCII here in the wild.
234                                    NB: this is CLEAR for default key. */
235   uint16_t unknown2;
236   char name[1];                 /* key name follows here */
237 } __attribute__((__packed__));
238
239 static uint32_t
240 header_checksum (const hive_h *h)
241 {
242   uint32_t *daddr = (uint32_t *) h->addr;
243   size_t i;
244   uint32_t sum = 0;
245
246   for (i = 0; i < 0x1fc / 4; ++i) {
247     sum ^= le32toh (*daddr);
248     daddr++;
249   }
250
251   return sum;
252 }
253
254 hive_h *
255 hivex_open (const char *filename, int flags)
256 {
257   hive_h *h = NULL;
258
259   assert (sizeof (struct ntreg_header) == 0x1000);
260   assert (offsetof (struct ntreg_header, csum) == 0x1fc);
261
262   h = calloc (1, sizeof *h);
263   if (h == NULL)
264     goto error;
265
266   h->msglvl = flags & HIVEX_OPEN_MSGLVL_MASK;
267
268   const char *debug = getenv ("HIVEX_DEBUG");
269   if (debug && STREQ (debug, "1"))
270     h->msglvl = 2;
271
272   if (h->msglvl >= 2)
273     fprintf (stderr, "hivex_open: created handle %p\n", h);
274
275   h->writable = !!(flags & HIVEX_OPEN_WRITE);
276   h->filename = strdup (filename);
277   if (h->filename == NULL)
278     goto error;
279
280   h->fd = open (filename, O_RDONLY | O_CLOEXEC);
281   if (h->fd == -1)
282     goto error;
283
284   struct stat statbuf;
285   if (fstat (h->fd, &statbuf) == -1)
286     goto error;
287
288   h->size = statbuf.st_size;
289
290   if (!h->writable) {
291     h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0);
292     if (h->addr == MAP_FAILED)
293       goto error;
294
295     if (h->msglvl >= 2)
296       fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
297   } else {
298     h->addr = malloc (h->size);
299     if (h->addr == NULL)
300       goto error;
301
302     if (full_read (h->fd, h->addr, h->size) < h->size)
303       goto error;
304   }
305
306   /* Check header. */
307   if (h->hdr->magic[0] != 'r' ||
308       h->hdr->magic[1] != 'e' ||
309       h->hdr->magic[2] != 'g' ||
310       h->hdr->magic[3] != 'f') {
311     fprintf (stderr, "hivex: %s: not a Windows NT Registry hive file\n",
312              filename);
313     errno = ENOTSUP;
314     goto error;
315   }
316
317   /* Check major version. */
318   uint32_t major_ver = le32toh (h->hdr->major_ver);
319   if (major_ver != 1) {
320     fprintf (stderr,
321              "hivex: %s: hive file major version %" PRIu32 " (expected 1)\n",
322              filename, major_ver);
323     errno = ENOTSUP;
324     goto error;
325   }
326
327   h->bitmap = calloc (1 + h->size / 32, 1);
328   if (h->bitmap == NULL)
329     goto error;
330
331   /* Header checksum. */
332   uint32_t sum = header_checksum (h);
333   if (sum != le32toh (h->hdr->csum)) {
334     fprintf (stderr, "hivex: %s: bad checksum in hive header\n", filename);
335     errno = EINVAL;
336     goto error;
337   }
338
339   if (h->msglvl >= 2) {
340     char *name = windows_utf16_to_utf8 (h->hdr->name, 64);
341
342     fprintf (stderr,
343              "hivex_open: header fields:\n"
344              "  file version             %" PRIu32 ".%" PRIu32 "\n"
345              "  sequence nos             %" PRIu32 " %" PRIu32 "\n"
346              "    (sequences nos should match if hive was synched at shutdown)\n"
347              "  original file name       %s\n"
348              "    (only 32 chars are stored, name is probably truncated)\n"
349              "  root offset              0x%x + 0x1000\n"
350              "  end of last page         0x%x + 0x1000 (total file size 0x%zx)\n"
351              "  checksum                 0x%x (calculated 0x%x)\n",
352              major_ver, le32toh (h->hdr->minor_ver),
353              le32toh (h->hdr->sequence1), le32toh (h->hdr->sequence2),
354              name ? name : "(conversion failed)",
355              le32toh (h->hdr->offset),
356              le32toh (h->hdr->blocks), h->size,
357              le32toh (h->hdr->csum), sum);
358     free (name);
359   }
360
361   h->rootoffs = le32toh (h->hdr->offset) + 0x1000;
362   h->endpages = le32toh (h->hdr->blocks) + 0x1000;
363
364   if (h->msglvl >= 2)
365     fprintf (stderr, "hivex_open: root offset = 0x%zx\n", h->rootoffs);
366
367   /* We'll set this flag when we see a block with the root offset (ie.
368    * the root block).
369    */
370   int seen_root_block = 0, bad_root_block = 0;
371
372   /* Collect some stats. */
373   size_t pages = 0;           /* Number of hbin pages read. */
374   size_t smallest_page = SIZE_MAX, largest_page = 0;
375   size_t blocks = 0;          /* Total number of blocks found. */
376   size_t smallest_block = SIZE_MAX, largest_block = 0, blocks_bytes = 0;
377   size_t used_blocks = 0;     /* Total number of used blocks found. */
378   size_t used_size = 0;       /* Total size (bytes) of used blocks. */
379
380   /* Read the pages and blocks.  The aim here is to be robust against
381    * corrupt or malicious registries.  So we make sure the loops
382    * always make forward progress.  We add the address of each block
383    * we read to a hash table so pointers will only reference the start
384    * of valid blocks.
385    */
386   size_t off;
387   struct ntreg_hbin_page *page;
388   for (off = 0x1000; off < h->size; off += le32toh (page->page_size)) {
389     if (off >= h->endpages)
390       break;
391
392     page = (struct ntreg_hbin_page *) (h->addr + off);
393     if (page->magic[0] != 'h' ||
394         page->magic[1] != 'b' ||
395         page->magic[2] != 'i' ||
396         page->magic[3] != 'n') {
397       fprintf (stderr, "hivex: %s: trailing garbage at end of file (at 0x%zx, after %zu pages)\n",
398                filename, off, pages);
399       errno = ENOTSUP;
400       goto error;
401     }
402
403     size_t page_size = le32toh (page->page_size);
404     if (h->msglvl >= 2)
405       fprintf (stderr, "hivex_open: page at 0x%zx, size %zu\n", off, page_size);
406     pages++;
407     if (page_size < smallest_page) smallest_page = page_size;
408     if (page_size > largest_page) largest_page = page_size;
409
410     if (page_size <= sizeof (struct ntreg_hbin_page) ||
411         (page_size & 0x0fff) != 0) {
412       fprintf (stderr, "hivex: %s: page size %zu at 0x%zx, bad registry\n",
413                filename, page_size, off);
414       errno = ENOTSUP;
415       goto error;
416     }
417
418     /* Read the blocks in this page. */
419     size_t blkoff;
420     struct ntreg_hbin_block *block;
421     size_t seg_len;
422     for (blkoff = off + 0x20;
423          blkoff < off + page_size;
424          blkoff += seg_len) {
425       blocks++;
426
427       int is_root = blkoff == h->rootoffs;
428       if (is_root)
429         seen_root_block = 1;
430
431       block = (struct ntreg_hbin_block *) (h->addr + blkoff);
432       int used;
433       seg_len = block_len (h, blkoff, &used);
434       if (seg_len <= 4 || (seg_len & 3) != 0) {
435         fprintf (stderr, "hivex: %s: block size %" PRIu32 " at 0x%zx, bad registry\n",
436                  filename, le32toh (block->seg_len), blkoff);
437         errno = ENOTSUP;
438         goto error;
439       }
440
441       if (h->msglvl >= 2)
442         fprintf (stderr, "hivex_open: %s block id %d,%d at 0x%zx size %zu%s\n",
443                  used ? "used" : "free", block->id[0], block->id[1], blkoff,
444                  seg_len, is_root ? " (root)" : "");
445
446       blocks_bytes += seg_len;
447       if (seg_len < smallest_block) smallest_block = seg_len;
448       if (seg_len > largest_block) largest_block = seg_len;
449
450       if (is_root && !used)
451         bad_root_block = 1;
452
453       if (used) {
454         used_blocks++;
455         used_size += seg_len;
456
457         /* Root block must be an nk-block. */
458         if (is_root && (block->id[0] != 'n' || block->id[1] != 'k'))
459           bad_root_block = 1;
460
461         /* Note this blkoff is a valid address. */
462         BITMAP_SET (h->bitmap, blkoff);
463       }
464     }
465   }
466
467   if (!seen_root_block) {
468     fprintf (stderr, "hivex: %s: no root block found\n", filename);
469     errno = ENOTSUP;
470     goto error;
471   }
472
473   if (bad_root_block) {
474     fprintf (stderr, "hivex: %s: bad root block (free or not nk)\n", filename);
475     errno = ENOTSUP;
476     goto error;
477   }
478
479   if (h->msglvl >= 1)
480     fprintf (stderr,
481              "hivex_open: successfully read Windows Registry hive file:\n"
482              "  pages:          %zu [sml: %zu, lge: %zu]\n"
483              "  blocks:         %zu [sml: %zu, avg: %zu, lge: %zu]\n"
484              "  blocks used:    %zu\n"
485              "  bytes used:     %zu\n",
486              pages, smallest_page, largest_page,
487              blocks, smallest_block, blocks_bytes / blocks, largest_block,
488              used_blocks, used_size);
489
490   return h;
491
492  error:;
493   int err = errno;
494   if (h) {
495     free (h->bitmap);
496     if (h->addr && h->size && h->addr != MAP_FAILED) {
497       if (!h->writable)
498         munmap (h->addr, h->size);
499       else
500         free (h->addr);
501     }
502     if (h->fd >= 0)
503       close (h->fd);
504     free (h->filename);
505     free (h);
506   }
507   errno = err;
508   return NULL;
509 }
510
511 int
512 hivex_close (hive_h *h)
513 {
514   int r;
515
516   free (h->bitmap);
517   if (!h->writable)
518     munmap (h->addr, h->size);
519   else
520     free (h->addr);
521   r = close (h->fd);
522   free (h->filename);
523   free (h);
524
525   return r;
526 }
527
528 /*----------------------------------------------------------------------
529  * Reading.
530  */
531
532 hive_node_h
533 hivex_root (hive_h *h)
534 {
535   hive_node_h ret = h->rootoffs;
536   if (!IS_VALID_BLOCK (h, ret)) {
537     errno = ENOKEY;
538     return 0;
539   }
540   return ret;
541 }
542
543 char *
544 hivex_node_name (hive_h *h, hive_node_h node)
545 {
546   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
547     errno = EINVAL;
548     return NULL;
549   }
550
551   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
552
553   /* AFAIK the node name is always plain ASCII, so no conversion
554    * to UTF-8 is necessary.  However we do need to nul-terminate
555    * the string.
556    */
557
558   /* nk->name_len is unsigned, 16 bit, so this is safe ...  However
559    * we have to make sure the length doesn't exceed the block length.
560    */
561   size_t len = le16toh (nk->name_len);
562   size_t seg_len = block_len (h, node, NULL);
563   if (sizeof (struct ntreg_nk_record) + len - 1 > seg_len) {
564     if (h->msglvl >= 2)
565       fprintf (stderr, "hivex_node_name: returning EFAULT because node name is too long (%zu, %zu)\n",
566               len, seg_len);
567     errno = EFAULT;
568     return NULL;
569   }
570
571   char *ret = malloc (len + 1);
572   if (ret == NULL)
573     return NULL;
574   memcpy (ret, nk->name, len);
575   ret[len] = '\0';
576   return ret;
577 }
578
579 #if 0
580 /* I think the documentation for the sk and classname fields in the nk
581  * record is wrong, or else the offset field is in the wrong place.
582  * Otherwise this makes no sense.  Disabled this for now -- it's not
583  * useful for reading the registry anyway.
584  */
585
586 hive_security_h
587 hivex_node_security (hive_h *h, hive_node_h node)
588 {
589   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
590     errno = EINVAL;
591     return 0;
592   }
593
594   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
595
596   hive_node_h ret = le32toh (nk->sk);
597   ret += 0x1000;
598   if (!IS_VALID_BLOCK (h, ret)) {
599     errno = EFAULT;
600     return 0;
601   }
602   return ret;
603 }
604
605 hive_classname_h
606 hivex_node_classname (hive_h *h, hive_node_h node)
607 {
608   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
609     errno = EINVAL;
610     return 0;
611   }
612
613   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
614
615   hive_node_h ret = le32toh (nk->classname);
616   ret += 0x1000;
617   if (!IS_VALID_BLOCK (h, ret)) {
618     errno = EFAULT;
619     return 0;
620   }
621   return ret;
622 }
623 #endif
624
625 /* Structure for returning 0-terminated lists of offsets (nodes,
626  * values, etc).
627  */
628 struct offset_list {
629   size_t *offsets;
630   size_t len;
631   size_t alloc;
632 };
633
634 static void
635 init_offset_list (struct offset_list *list)
636 {
637   list->len = 0;
638   list->alloc = 0;
639   list->offsets = NULL;
640 }
641
642 #define INIT_OFFSET_LIST(name) \
643   struct offset_list name; \
644   init_offset_list (&name)
645
646 /* Preallocates the offset_list, but doesn't make the contents longer. */
647 static int
648 grow_offset_list (struct offset_list *list, size_t alloc)
649 {
650   assert (alloc >= list->len);
651   size_t *p = realloc (list->offsets, alloc * sizeof (size_t));
652   if (p == NULL)
653     return -1;
654   list->offsets = p;
655   list->alloc = alloc;
656   return 0;
657 }
658
659 static int
660 add_to_offset_list (struct offset_list *list, size_t offset)
661 {
662   if (list->len >= list->alloc) {
663     if (grow_offset_list (list, list->alloc ? list->alloc * 2 : 4) == -1)
664       return -1;
665   }
666   list->offsets[list->len] = offset;
667   list->len++;
668   return 0;
669 }
670
671 static void
672 free_offset_list (struct offset_list *list)
673 {
674   free (list->offsets);
675 }
676
677 static size_t *
678 return_offset_list (struct offset_list *list)
679 {
680   if (add_to_offset_list (list, 0) == -1)
681     return NULL;
682   return list->offsets;         /* caller frees */
683 }
684
685 /* Iterate over children, returning child nodes and intermediate blocks. */
686 static int
687 get_children (hive_h *h, hive_node_h node,
688               hive_node_h **children_ret, size_t **blocks_ret)
689 {
690   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
691     errno = EINVAL;
692     return -1;
693   }
694
695   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
696
697   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
698
699   INIT_OFFSET_LIST (children);
700   INIT_OFFSET_LIST (blocks);
701
702   /* Deal with the common "no subkeys" case quickly. */
703   if (nr_subkeys_in_nk == 0)
704     goto ok;
705
706   /* Arbitrarily limit the number of subkeys we will ever deal with. */
707   if (nr_subkeys_in_nk > 1000000) {
708     errno = ERANGE;
709     goto error;
710   }
711
712   /* Preallocate space for the children. */
713   if (grow_offset_list (&children, nr_subkeys_in_nk) == -1)
714     goto error;
715
716   /* The subkey_lf field can point either to an lf-record, which is
717    * the common case, or if there are lots of subkeys, to an
718    * ri-record.
719    */
720   size_t subkey_lf = le32toh (nk->subkey_lf);
721   subkey_lf += 0x1000;
722   if (!IS_VALID_BLOCK (h, subkey_lf)) {
723     if (h->msglvl >= 2)
724       fprintf (stderr, "hivex_node_children: returning EFAULT because subkey_lf is not a valid block (%zu)\n",
725                subkey_lf);
726     errno = EFAULT;
727     goto error;
728   }
729
730   if (add_to_offset_list (&blocks, subkey_lf) == -1)
731     goto error;
732
733   struct ntreg_hbin_block *block =
734     (struct ntreg_hbin_block *) (h->addr + subkey_lf);
735
736   /* Points to lf-record?  (Note, also "lh" but that is basically the
737    * same as "lf" as far as we are concerned here).
738    */
739   if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
740     struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
741
742     /* Check number of subkeys in the nk-record matches number of subkeys
743      * in the lf-record.
744      */
745     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
746
747     if (h->msglvl >= 2)
748       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, nr_subkeys_in_lf = %zu\n",
749                nr_subkeys_in_nk, nr_subkeys_in_lf);
750
751     if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
752       errno = ENOTSUP;
753       goto error;
754     }
755
756     size_t len = block_len (h, subkey_lf, NULL);
757     if (8 + nr_subkeys_in_lf * 8 > len) {
758       if (h->msglvl >= 2)
759         fprintf (stderr, "hivex_node_children: returning EFAULT because too many subkeys (%zu, %zu)\n",
760                  nr_subkeys_in_lf, len);
761       errno = EFAULT;
762       goto error;
763     }
764
765     size_t i;
766     for (i = 0; i < nr_subkeys_in_lf; ++i) {
767       hive_node_h subkey = le32toh (lf->keys[i].offset);
768       subkey += 0x1000;
769       if (!IS_VALID_BLOCK (h, subkey)) {
770         if (h->msglvl >= 2)
771           fprintf (stderr, "hivex_node_children: returning EFAULT because subkey is not a valid block (0x%zx)\n",
772                    subkey);
773         errno = EFAULT;
774         goto error;
775       }
776       if (add_to_offset_list (&children, subkey) == -1)
777         goto error;
778     }
779     goto ok;
780   }
781   /* Points to ri-record? */
782   else if (block->id[0] == 'r' && block->id[1] == 'i') {
783     struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block;
784
785     size_t nr_offsets = le16toh (ri->nr_offsets);
786
787     /* Count total number of children. */
788     size_t i, count = 0;
789     for (i = 0; i < nr_offsets; ++i) {
790       hive_node_h offset = ri->offset[i];
791       offset += 0x1000;
792       if (!IS_VALID_BLOCK (h, offset)) {
793         if (h->msglvl >= 2)
794           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
795                    offset);
796         errno = EFAULT;
797         goto error;
798       }
799       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
800         errno = ENOTSUP;
801         goto error;
802       }
803
804       if (add_to_offset_list (&blocks, offset) == -1)
805         goto error;
806
807       struct ntreg_lf_record *lf =
808         (struct ntreg_lf_record *) (h->addr + offset);
809
810       count += le16toh (lf->nr_keys);
811     }
812
813     if (h->msglvl >= 2)
814       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, counted = %zu\n",
815                nr_subkeys_in_nk, count);
816
817     if (nr_subkeys_in_nk != count) {
818       errno = ENOTSUP;
819       goto error;
820     }
821
822     /* Copy list of children.  Note nr_subkeys_in_nk is limited to
823      * something reasonable above.
824      */
825     for (i = 0; i < nr_offsets; ++i) {
826       hive_node_h offset = ri->offset[i];
827       offset += 0x1000;
828       if (!IS_VALID_BLOCK (h, offset)) {
829         if (h->msglvl >= 2)
830           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
831                    offset);
832         errno = EFAULT;
833         goto error;
834       }
835       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
836         errno = ENOTSUP;
837         goto error;
838       }
839
840       struct ntreg_lf_record *lf =
841         (struct ntreg_lf_record *) (h->addr + offset);
842
843       size_t j;
844       for (j = 0; j < le16toh (lf->nr_keys); ++j) {
845         hive_node_h subkey = le32toh (lf->keys[j].offset);
846         subkey += 0x1000;
847         if (!IS_VALID_BLOCK (h, subkey)) {
848           if (h->msglvl >= 2)
849             fprintf (stderr, "hivex_node_children: returning EFAULT because indirect subkey is not a valid block (0x%zx)\n",
850                      subkey);
851           errno = EFAULT;
852           goto error;
853         }
854         if (add_to_offset_list (&children, subkey) == -1)
855           goto error;
856       }
857     }
858     goto ok;
859   }
860   /* else not supported, set errno and fall through */
861   errno = ENOTSUP;
862  error:
863   free_offset_list (&children);
864   free_offset_list (&blocks);
865   return -1;
866
867  ok:
868   *children_ret = return_offset_list (&children);
869   *blocks_ret = return_offset_list (&blocks);
870   if (!*children_ret || !*blocks_ret)
871     goto error;
872   return 0;
873 }
874
875 hive_node_h *
876 hivex_node_children (hive_h *h, hive_node_h node)
877 {
878   hive_node_h *children;
879   size_t *blocks;
880
881   if (get_children (h, node, &children, &blocks) == -1)
882     return NULL;
883
884   free (blocks);
885   return children;
886 }
887
888 /* Very inefficient, but at least having a separate API call
889  * allows us to make it more efficient in future.
890  */
891 hive_node_h
892 hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
893 {
894   hive_node_h *children = NULL;
895   char *name = NULL;
896   hive_node_h ret = 0;
897
898   children = hivex_node_children (h, node);
899   if (!children) goto error;
900
901   size_t i;
902   for (i = 0; children[i] != 0; ++i) {
903     name = hivex_node_name (h, children[i]);
904     if (!name) goto error;
905     if (STRCASEEQ (name, nname)) {
906       ret = children[i];
907       break;
908     }
909     free (name); name = NULL;
910   }
911
912  error:
913   free (children);
914   free (name);
915   return ret;
916 }
917
918 hive_node_h
919 hivex_node_parent (hive_h *h, hive_node_h node)
920 {
921   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
922     errno = EINVAL;
923     return 0;
924   }
925
926   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
927
928   hive_node_h ret = le32toh (nk->parent);
929   ret += 0x1000;
930   if (!IS_VALID_BLOCK (h, ret)) {
931     if (h->msglvl >= 2)
932       fprintf (stderr, "hivex_node_parent: returning EFAULT because parent is not a valid block (0x%zx)\n",
933               ret);
934     errno = EFAULT;
935     return 0;
936   }
937   return ret;
938 }
939
940 static int
941 get_values (hive_h *h, hive_node_h node,
942             hive_value_h **values_ret, size_t **blocks_ret)
943 {
944   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
945     errno = EINVAL;
946     return -1;
947   }
948
949   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
950
951   size_t nr_values = le32toh (nk->nr_values);
952
953   if (h->msglvl >= 2)
954     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
955
956   INIT_OFFSET_LIST (values);
957   INIT_OFFSET_LIST (blocks);
958
959   /* Deal with the common "no values" case quickly. */
960   if (nr_values == 0)
961     goto ok;
962
963   /* Arbitrarily limit the number of values we will ever deal with. */
964   if (nr_values > 100000) {
965     errno = ERANGE;
966     goto error;
967   }
968
969   /* Preallocate space for the values. */
970   if (grow_offset_list (&values, nr_values) == -1)
971     goto error;
972
973   /* Get the value list and check it looks reasonable. */
974   size_t vlist_offset = le32toh (nk->vallist);
975   vlist_offset += 0x1000;
976   if (!IS_VALID_BLOCK (h, vlist_offset)) {
977     if (h->msglvl >= 2)
978       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is not a valid block (0x%zx)\n",
979                vlist_offset);
980     errno = EFAULT;
981     goto error;
982   }
983
984   if (add_to_offset_list (&blocks, vlist_offset) == -1)
985     goto error;
986
987   struct ntreg_value_list *vlist =
988     (struct ntreg_value_list *) (h->addr + vlist_offset);
989
990   size_t len = block_len (h, vlist_offset, NULL);
991   if (4 + nr_values * 4 > len) {
992     if (h->msglvl >= 2)
993       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is too long (%zu, %zu)\n",
994                nr_values, len);
995     errno = EFAULT;
996     goto error;
997   }
998
999   size_t i;
1000   for (i = 0; i < nr_values; ++i) {
1001     hive_node_h value = vlist->offset[i];
1002     value += 0x1000;
1003     if (!IS_VALID_BLOCK (h, value)) {
1004       if (h->msglvl >= 2)
1005         fprintf (stderr, "hivex_node_values: returning EFAULT because value is not a valid block (0x%zx)\n",
1006                  value);
1007       errno = EFAULT;
1008       goto error;
1009     }
1010     if (add_to_offset_list (&values, value) == -1)
1011       goto error;
1012   }
1013
1014  ok:
1015   *values_ret = return_offset_list (&values);
1016   *blocks_ret = return_offset_list (&blocks);
1017   if (!*values_ret || !*blocks_ret)
1018     goto error;
1019   return 0;
1020
1021  error:
1022   free_offset_list (&values);
1023   free_offset_list (&blocks);
1024   return -1;
1025 }
1026
1027 hive_value_h *
1028 hivex_node_values (hive_h *h, hive_node_h node)
1029 {
1030   hive_value_h *values;
1031   size_t *blocks;
1032
1033   if (get_values (h, node, &values, &blocks) == -1)
1034     return NULL;
1035
1036   free (blocks);
1037   return values;
1038 }
1039
1040 /* Very inefficient, but at least having a separate API call
1041  * allows us to make it more efficient in future.
1042  */
1043 hive_value_h
1044 hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
1045 {
1046   hive_value_h *values = NULL;
1047   char *name = NULL;
1048   hive_value_h ret = 0;
1049
1050   values = hivex_node_values (h, node);
1051   if (!values) goto error;
1052
1053   size_t i;
1054   for (i = 0; values[i] != 0; ++i) {
1055     name = hivex_value_key (h, values[i]);
1056     if (!name) goto error;
1057     if (STRCASEEQ (name, key)) {
1058       ret = values[i];
1059       break;
1060     }
1061     free (name); name = NULL;
1062   }
1063
1064  error:
1065   free (values);
1066   free (name);
1067   return ret;
1068 }
1069
1070 char *
1071 hivex_value_key (hive_h *h, hive_value_h value)
1072 {
1073   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1074     errno = EINVAL;
1075     return 0;
1076   }
1077
1078   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1079
1080   /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
1081    * necessary.  However we do need to nul-terminate the string.
1082    */
1083
1084   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
1085    * we have to make sure the length doesn't exceed the block length.
1086    */
1087   size_t len = le16toh (vk->name_len);
1088   size_t seg_len = block_len (h, value, NULL);
1089   if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
1090     if (h->msglvl >= 2)
1091       fprintf (stderr, "hivex_value_key: returning EFAULT because key length is too long (%zu, %zu)\n",
1092                len, seg_len);
1093     errno = EFAULT;
1094     return NULL;
1095   }
1096
1097   char *ret = malloc (len + 1);
1098   if (ret == NULL)
1099     return NULL;
1100   memcpy (ret, vk->name, len);
1101   ret[len] = '\0';
1102   return ret;
1103 }
1104
1105 int
1106 hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
1107 {
1108   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1109     errno = EINVAL;
1110     return -1;
1111   }
1112
1113   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1114
1115   if (t)
1116     *t = le32toh (vk->data_type);
1117
1118   if (len) {
1119     *len = le32toh (vk->data_len);
1120     if (*len == 0x80000000) {   /* special case */
1121       *len = 4;
1122       if (t) *t = hive_t_dword;
1123     }
1124     *len &= 0x7fffffff;
1125   }
1126
1127   return 0;
1128 }
1129
1130 char *
1131 hivex_value_value (hive_h *h, hive_value_h value,
1132                    hive_type *t_rtn, size_t *len_rtn)
1133 {
1134   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1135     errno = EINVAL;
1136     return NULL;
1137   }
1138
1139   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1140
1141   hive_type t;
1142   size_t len;
1143
1144   t = le32toh (vk->data_type);
1145
1146   len = le32toh (vk->data_len);
1147   if (len == 0x80000000) {      /* special case */
1148     len = 4;
1149     t = hive_t_dword;
1150   }
1151   len &= 0x7fffffff;
1152
1153   if (h->msglvl >= 2)
1154     fprintf (stderr, "hivex_value_value: value=0x%zx, t=%d, len=%zu\n",
1155              value, t, len);
1156
1157   if (t_rtn)
1158     *t_rtn = t;
1159   if (len_rtn)
1160     *len_rtn = len;
1161
1162   /* Arbitrarily limit the length that we will read. */
1163   if (len > 1000000) {
1164     errno = ERANGE;
1165     return NULL;
1166   }
1167
1168   char *ret = malloc (len);
1169   if (ret == NULL)
1170     return NULL;
1171
1172   /* If length is <= 4 it's always stored inline. */
1173   if (len <= 4) {
1174     memcpy (ret, (char *) &vk->data_offset, len);
1175     return ret;
1176   }
1177
1178   size_t data_offset = le32toh (vk->data_offset);
1179   data_offset += 0x1000;
1180   if (!IS_VALID_BLOCK (h, data_offset)) {
1181     if (h->msglvl >= 2)
1182       fprintf (stderr, "hivex_value_value: returning EFAULT because data offset is not a valid block (0x%zx)\n",
1183                data_offset);
1184     errno = EFAULT;
1185     free (ret);
1186     return NULL;
1187   }
1188
1189   /* Check that the declared size isn't larger than the block its in.
1190    *
1191    * XXX Some apparently valid registries are seen to have this,
1192    * so turn this into a warning and substitute the smaller length
1193    * instead.
1194    */
1195   size_t blen = block_len (h, data_offset, NULL);
1196   if (len > blen - 4 /* subtract 4 for block header */) {
1197     if (h->msglvl >= 2)
1198       fprintf (stderr, "hivex_value_value: warning: declared data length is longer than the block it is in (data 0x%zx, data len %zu, block len %zu)\n",
1199                data_offset, len, blen);
1200     len = blen - 4;
1201   }
1202
1203   char *data = h->addr + data_offset + 4;
1204   memcpy (ret, data, len);
1205   return ret;
1206 }
1207
1208 static char *
1209 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1210 {
1211   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1212   if (ic == (iconv_t) -1)
1213     return NULL;
1214
1215   /* iconv(3) has an insane interface ... */
1216
1217   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1218   size_t outalloc = len;
1219
1220  again:;
1221   size_t inlen = len;
1222   size_t outlen = outalloc;
1223   char *out = malloc (outlen + 1);
1224   if (out == NULL) {
1225     int err = errno;
1226     iconv_close (ic);
1227     errno = err;
1228     return NULL;
1229   }
1230   char *inp = input;
1231   char *outp = out;
1232
1233   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1234   if (r == (size_t) -1) {
1235     if (errno == E2BIG) {
1236       size_t prev = outalloc;
1237       /* Try again with a larger output buffer. */
1238       free (out);
1239       outalloc *= 2;
1240       if (outalloc < prev)
1241         return NULL;
1242       goto again;
1243     }
1244     else {
1245       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1246       int err = errno;
1247       iconv_close (ic);
1248       free (out);
1249       errno = err;
1250       return NULL;
1251     }
1252   }
1253
1254   *outp = '\0';
1255   iconv_close (ic);
1256
1257   return out;
1258 }
1259
1260 char *
1261 hivex_value_string (hive_h *h, hive_value_h value)
1262 {
1263   hive_type t;
1264   size_t len;
1265   char *data = hivex_value_value (h, value, &t, &len);
1266
1267   if (data == NULL)
1268     return NULL;
1269
1270   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1271     free (data);
1272     errno = EINVAL;
1273     return NULL;
1274   }
1275
1276   char *ret = windows_utf16_to_utf8 (data, len);
1277   free (data);
1278   if (ret == NULL)
1279     return NULL;
1280
1281   return ret;
1282 }
1283
1284 static void
1285 free_strings (char **argv)
1286 {
1287   if (argv) {
1288     size_t i;
1289
1290     for (i = 0; argv[i] != NULL; ++i)
1291       free (argv[i]);
1292     free (argv);
1293   }
1294 }
1295
1296 /* Get the length of a UTF-16 format string.  Handle the string as
1297  * pairs of bytes, looking for the first \0\0 pair.
1298  */
1299 static size_t
1300 utf16_string_len_in_bytes (const char *str)
1301 {
1302   size_t ret = 0;
1303
1304   while (str[0] || str[1]) {
1305     str += 2;
1306     ret += 2;
1307   }
1308
1309   return ret;
1310 }
1311
1312 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1313 char **
1314 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1315 {
1316   hive_type t;
1317   size_t len;
1318   char *data = hivex_value_value (h, value, &t, &len);
1319
1320   if (data == NULL)
1321     return NULL;
1322
1323   if (t != hive_t_multiple_strings) {
1324     free (data);
1325     errno = EINVAL;
1326     return NULL;
1327   }
1328
1329   size_t nr_strings = 0;
1330   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1331   if (ret == NULL) {
1332     free (data);
1333     return NULL;
1334   }
1335   ret[0] = NULL;
1336
1337   char *p = data;
1338   size_t plen;
1339
1340   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1341     nr_strings++;
1342     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1343     if (ret2 == NULL) {
1344       free_strings (ret);
1345       free (data);
1346       return NULL;
1347     }
1348     ret = ret2;
1349
1350     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1351     ret[nr_strings] = NULL;
1352     if (ret[nr_strings-1] == NULL) {
1353       free_strings (ret);
1354       free (data);
1355       return NULL;
1356     }
1357
1358     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1359   }
1360
1361   free (data);
1362   return ret;
1363 }
1364
1365 int32_t
1366 hivex_value_dword (hive_h *h, hive_value_h value)
1367 {
1368   hive_type t;
1369   size_t len;
1370   char *data = hivex_value_value (h, value, &t, &len);
1371
1372   if (data == NULL)
1373     return -1;
1374
1375   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1376     free (data);
1377     errno = EINVAL;
1378     return -1;
1379   }
1380
1381   int32_t ret = *(int32_t*)data;
1382   free (data);
1383   if (t == hive_t_dword)        /* little endian */
1384     ret = le32toh (ret);
1385   else
1386     ret = be32toh (ret);
1387
1388   return ret;
1389 }
1390
1391 int64_t
1392 hivex_value_qword (hive_h *h, hive_value_h value)
1393 {
1394   hive_type t;
1395   size_t len;
1396   char *data = hivex_value_value (h, value, &t, &len);
1397
1398   if (data == NULL)
1399     return -1;
1400
1401   if (t != hive_t_qword || len != 8) {
1402     free (data);
1403     errno = EINVAL;
1404     return -1;
1405   }
1406
1407   int64_t ret = *(int64_t*)data;
1408   free (data);
1409   ret = le64toh (ret);          /* always little endian */
1410
1411   return ret;
1412 }
1413
1414 /*----------------------------------------------------------------------
1415  * Visiting.
1416  */
1417
1418 int
1419 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1420              void *opaque, int flags)
1421 {
1422   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1423 }
1424
1425 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1426
1427 int
1428 hivex_visit_node (hive_h *h, hive_node_h node,
1429                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1430                   int flags)
1431 {
1432   struct hivex_visitor vtor;
1433   memset (&vtor, 0, sizeof vtor);
1434
1435   /* Note that len might be larger *or smaller* than the expected size. */
1436   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1437   memcpy (&vtor, visitor, copysize);
1438
1439   /* This bitmap records unvisited nodes, so we don't loop if the
1440    * registry contains cycles.
1441    */
1442   char *unvisited = malloc (1 + h->size / 32);
1443   if (unvisited == NULL)
1444     return -1;
1445   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1446
1447   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1448   free (unvisited);
1449   return r;
1450 }
1451
1452 static int
1453 hivex__visit_node (hive_h *h, hive_node_h node,
1454                    const struct hivex_visitor *vtor, char *unvisited,
1455                    void *opaque, int flags)
1456 {
1457   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1458   char *name = NULL;
1459   hive_value_h *values = NULL;
1460   hive_node_h *children = NULL;
1461   char *key = NULL;
1462   char *str = NULL;
1463   char **strs = NULL;
1464   int i;
1465
1466   /* Return -1 on all callback errors.  However on internal errors,
1467    * check if skip_bad is set and suppress those errors if so.
1468    */
1469   int ret = -1;
1470
1471   if (!BITMAP_TST (unvisited, node)) {
1472     if (h->msglvl >= 2)
1473       fprintf (stderr, "hivex__visit_node: contains cycle: visited node 0x%zx already\n",
1474                node);
1475
1476     errno = ELOOP;
1477     return skip_bad ? 0 : -1;
1478   }
1479   BITMAP_CLR (unvisited, node);
1480
1481   name = hivex_node_name (h, node);
1482   if (!name) return skip_bad ? 0 : -1;
1483   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1484     goto error;
1485
1486   values = hivex_node_values (h, node);
1487   if (!values) {
1488     ret = skip_bad ? 0 : -1;
1489     goto error;
1490   }
1491
1492   for (i = 0; values[i] != 0; ++i) {
1493     hive_type t;
1494     size_t len;
1495
1496     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1497       ret = skip_bad ? 0 : -1;
1498       goto error;
1499     }
1500
1501     key = hivex_value_key (h, values[i]);
1502     if (key == NULL) {
1503       ret = skip_bad ? 0 : -1;
1504       goto error;
1505     }
1506
1507     if (vtor->value_any) {
1508       str = hivex_value_value (h, values[i], &t, &len);
1509       if (str == NULL) {
1510         ret = skip_bad ? 0 : -1;
1511         goto error;
1512       }
1513       if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
1514         goto error;
1515       free (str); str = NULL;
1516     }
1517     else {
1518       switch (t) {
1519       case hive_t_none:
1520         str = hivex_value_value (h, values[i], &t, &len);
1521         if (str == NULL) {
1522           ret = skip_bad ? 0 : -1;
1523           goto error;
1524         }
1525         if (t != hive_t_none) {
1526           ret = skip_bad ? 0 : -1;
1527           goto error;
1528         }
1529         if (vtor->value_none &&
1530             vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1531           goto error;
1532         free (str); str = NULL;
1533         break;
1534
1535       case hive_t_string:
1536       case hive_t_expand_string:
1537       case hive_t_link:
1538         str = hivex_value_string (h, values[i]);
1539         if (str == NULL) {
1540           if (errno != EILSEQ && errno != EINVAL) {
1541             ret = skip_bad ? 0 : -1;
1542             goto error;
1543           }
1544           if (vtor->value_string_invalid_utf16) {
1545             str = hivex_value_value (h, values[i], &t, &len);
1546             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1547               goto error;
1548             free (str); str = NULL;
1549           }
1550           break;
1551         }
1552         if (vtor->value_string &&
1553             vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1554           goto error;
1555         free (str); str = NULL;
1556         break;
1557
1558       case hive_t_dword:
1559       case hive_t_dword_be: {
1560         int32_t i32 = hivex_value_dword (h, values[i]);
1561         if (vtor->value_dword &&
1562             vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1563           goto error;
1564         break;
1565       }
1566
1567       case hive_t_qword: {
1568         int64_t i64 = hivex_value_qword (h, values[i]);
1569         if (vtor->value_qword &&
1570             vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1571           goto error;
1572         break;
1573       }
1574
1575       case hive_t_binary:
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 (t != hive_t_binary) {
1582           ret = skip_bad ? 0 : -1;
1583           goto error;
1584         }
1585         if (vtor->value_binary &&
1586             vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1587           goto error;
1588         free (str); str = NULL;
1589         break;
1590
1591       case hive_t_multiple_strings:
1592         strs = hivex_value_multiple_strings (h, values[i]);
1593         if (strs == NULL) {
1594           if (errno != EILSEQ && errno != EINVAL) {
1595             ret = skip_bad ? 0 : -1;
1596             goto error;
1597           }
1598           if (vtor->value_string_invalid_utf16) {
1599             str = hivex_value_value (h, values[i], &t, &len);
1600             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1601               goto error;
1602             free (str); str = NULL;
1603           }
1604           break;
1605         }
1606         if (vtor->value_multiple_strings &&
1607             vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1608           goto error;
1609         free_strings (strs); strs = NULL;
1610         break;
1611
1612       case hive_t_resource_list:
1613       case hive_t_full_resource_description:
1614       case hive_t_resource_requirements_list:
1615       default:
1616         str = hivex_value_value (h, values[i], &t, &len);
1617         if (str == NULL) {
1618           ret = skip_bad ? 0 : -1;
1619           goto error;
1620         }
1621         if (vtor->value_other &&
1622             vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1623           goto error;
1624         free (str); str = NULL;
1625         break;
1626       }
1627     }
1628
1629     free (key); key = NULL;
1630   }
1631
1632   children = hivex_node_children (h, node);
1633   if (children == NULL) {
1634     ret = skip_bad ? 0 : -1;
1635     goto error;
1636   }
1637
1638   for (i = 0; children[i] != 0; ++i) {
1639     if (h->msglvl >= 2)
1640       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n",
1641                name, i, children[i]);
1642
1643     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1644       goto error;
1645   }
1646
1647   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1648     goto error;
1649
1650   ret = 0;
1651
1652  error:
1653   free (name);
1654   free (values);
1655   free (children);
1656   free (key);
1657   free (str);
1658   free_strings (strs);
1659   return ret;
1660 }
1661
1662 /*----------------------------------------------------------------------
1663  * Writing.
1664  */
1665
1666 /* Allocate an hbin (page), extending the malloc'd space if necessary,
1667  * and updating the hive handle fields (but NOT the hive disk header
1668  * -- the hive disk header is updated when we commit).  This function
1669  * also extends the bitmap if necessary.
1670  *
1671  * 'allocation_hint' is the size of the block allocation we would like
1672  * to make.  Normally registry blocks are very small (avg 50 bytes)
1673  * and are contained in standard-sized pages (4KB), but the registry
1674  * can support blocks which are larger than a standard page, in which
1675  * case it creates a page of 8KB, 12KB etc.
1676  *
1677  * Returns:
1678  * > 0 : offset of first usable byte of new page (after page header)
1679  * 0   : error (errno set)
1680  */
1681 static size_t
1682 allocate_page (hive_h *h, size_t allocation_hint)
1683 {
1684   /* In almost all cases this will be 1. */
1685   size_t nr_4k_pages =
1686     1 + (allocation_hint + sizeof (struct ntreg_hbin_page) - 1) / 4096;
1687   assert (nr_4k_pages >= 1);
1688
1689   /* 'extend' is the number of bytes to extend the file by.  Note that
1690    * hives found in the wild often contain slack between 'endpages'
1691    * and the actual end of the file, so we don't always need to make
1692    * the file larger.
1693    */
1694   ssize_t extend = h->endpages + nr_4k_pages * 4096 - h->size;
1695
1696   if (h->msglvl >= 2) {
1697     fprintf (stderr, "allocate_page: current endpages = 0x%zx, current size = 0x%zx\n",
1698              h->endpages, h->size);
1699     fprintf (stderr, "allocate_page: extending file by %zd bytes (<= 0 if no extension)\n",
1700              extend);
1701   }
1702
1703   if (extend > 0) {
1704     size_t oldsize = h->size;
1705     size_t newsize = h->size + extend;
1706     char *newaddr = realloc (h->addr, newsize);
1707     if (newaddr == NULL)
1708       return 0;
1709
1710     size_t oldbitmapsize = 1 + oldsize / 32;
1711     size_t newbitmapsize = 1 + newsize / 32;
1712     char *newbitmap = realloc (h->bitmap, newbitmapsize);
1713     if (newbitmap == NULL) {
1714       free (newaddr);
1715       return 0;
1716     }
1717
1718     h->addr = newaddr;
1719     h->size = newsize;
1720     h->bitmap = newbitmap;
1721
1722     memset (h->addr + oldsize, 0, newsize - oldsize);
1723     memset (h->bitmap + oldbitmapsize, 0, newbitmapsize - oldbitmapsize);
1724   }
1725
1726   size_t offset = h->endpages;
1727   h->endpages += nr_4k_pages * 4096;
1728
1729   if (h->msglvl >= 2)
1730     fprintf (stderr, "allocate_page: new endpages = 0x%zx, new size = 0x%zx\n",
1731              h->endpages, h->size);
1732
1733   /* Write the hbin header. */
1734   struct ntreg_hbin_page *page =
1735     (struct ntreg_hbin_page *) (h->addr + offset);
1736   page->magic[0] = 'h';
1737   page->magic[1] = 'b';
1738   page->magic[2] = 'i';
1739   page->magic[3] = 'n';
1740   page->offset_first = htole32 (offset - 0x1000);
1741   page->page_size = htole32 (nr_4k_pages * 4096);
1742   memset (page->unknown, 0, sizeof (page->unknown));
1743
1744   if (h->msglvl >= 2)
1745     fprintf (stderr, "allocate_page: new page at 0x%zx\n", offset);
1746
1747   /* Offset of first usable byte after the header. */
1748   return offset + sizeof (struct ntreg_hbin_page);
1749 }
1750
1751 /* Allocate a single block, first allocating an hbin (page) at the end
1752  * of the current file if necessary.  NB. To keep the implementation
1753  * simple and more likely to be correct, we do not reuse existing free
1754  * blocks.
1755  *
1756  * seg_len is the size of the block (this INCLUDES the block header).
1757  * The header of the block is initialized to -seg_len (negative to
1758  * indicate used).  id[2] is the block ID (type), eg. "nk" for nk-
1759  * record.  The block bitmap is updated to show this block as valid.
1760  * The rest of the contents of the block will be zero.
1761  *
1762  * Returns:
1763  * > 0 : offset of new block
1764  * 0   : error (errno set)
1765  */
1766 static size_t
1767 allocate_block (hive_h *h, size_t seg_len, const char id[2])
1768 {
1769   if (!h->writable) {
1770     errno = EROFS;
1771     return 0;
1772   }
1773
1774   if (seg_len < 4) {
1775     /* The caller probably forgot to include the header.  Note that
1776      * value lists have no ID field, so seg_len == 4 would be possible
1777      * for them, albeit unusual.
1778      */
1779     if (h->msglvl >= 2)
1780       fprintf (stderr, "allocate_block: refusing too small allocation (%zu), returning ERANGE\n",
1781                seg_len);
1782     errno = ERANGE;
1783     return 0;
1784   }
1785
1786   /* Refuse really large allocations. */
1787   if (seg_len > 1000000) {
1788     if (h->msglvl >= 2)
1789       fprintf (stderr, "allocate_block: refusing large allocation (%zu), returning ERANGE\n",
1790                seg_len);
1791     errno = ERANGE;
1792     return 0;
1793   }
1794
1795   /* Round up allocation to multiple of 8 bytes.  All blocks must be
1796    * on an 8 byte boundary.
1797    */
1798   seg_len = (seg_len + 7) & ~7;
1799
1800   /* Allocate a new page if necessary. */
1801   if (h->endblocks == 0 || h->endblocks + seg_len > h->endpages) {
1802     size_t newendblocks = allocate_page (h, seg_len);
1803     if (newendblocks == 0)
1804       return 0;
1805     h->endblocks = newendblocks;
1806   }
1807
1808   size_t offset = h->endblocks;
1809
1810   if (h->msglvl >= 2)
1811     fprintf (stderr, "allocate_block: new block at 0x%zx, size %zu\n",
1812              offset, seg_len);
1813
1814   struct ntreg_hbin_block *blockhdr =
1815     (struct ntreg_hbin_block *) (h->addr + offset);
1816
1817   blockhdr->seg_len = htole32 (- (int32_t) seg_len);
1818   if (id[0] && id[1] && seg_len >= 6) {
1819     blockhdr->id[0] = id[0];
1820     blockhdr->id[1] = id[1];
1821   }
1822
1823   h->endblocks += seg_len;
1824
1825   /* If there is space after the last block in the last page, then we
1826    * have to put a dummy free block header here to mark the rest of
1827    * the page as free.
1828    */
1829   ssize_t rem = h->endpages - h->endblocks;
1830   if (rem > 0) {
1831     if (h->msglvl >= 2)
1832       fprintf (stderr, "allocate_block: marking remainder of page free starting at 0x%zx, size %zd\n",
1833                h->endblocks, rem);
1834
1835     assert (rem >= 4);
1836
1837     blockhdr = (struct ntreg_hbin_block *) (h->addr + h->endblocks);
1838     blockhdr->seg_len = htole32 ((int32_t) rem);
1839   }
1840
1841   return offset;
1842 }
1843
1844 /* 'offset' must point to a valid, used block.  This function marks
1845  * the block unused (by updating the seg_len field) and invalidates
1846  * the bitmap.  It does NOT do this recursively, so to avoid creating
1847  * unreachable used blocks, callers may have to recurse over the hive
1848  * structures.  Also callers must ensure there are no references to
1849  * this block from other parts of the hive.
1850  */
1851 static void
1852 mark_block_unused (hive_h *h, size_t offset)
1853 {
1854   assert (h->writable);
1855   assert (IS_VALID_BLOCK (h, offset));
1856
1857   struct ntreg_hbin_block *blockhdr =
1858     (struct ntreg_hbin_block *) (h->addr + offset);
1859
1860   size_t seg_len = block_len (h, offset, NULL);
1861   blockhdr->seg_len = htole32 (seg_len);
1862
1863   BITMAP_CLR (h->bitmap, offset);
1864 }
1865
1866 /* Delete all existing values at this node. */
1867 static int
1868 delete_values (hive_h *h, hive_node_h node)
1869 {
1870   assert (h->writable);
1871
1872   hive_value_h *values;
1873   size_t *blocks;
1874   if (get_values (h, node, &values, &blocks) == -1)
1875     return -1;
1876
1877   size_t i;
1878   for (i = 0; blocks[i] != 0; ++i)
1879     mark_block_unused (h, blocks[i]);
1880
1881   free (blocks);
1882
1883   for (i = 0; values[i] != 0; ++i) {
1884     struct ntreg_vk_record *vk =
1885       (struct ntreg_vk_record *) (h->addr + values[i]);
1886
1887     size_t len;
1888     len = le32toh (vk->data_len);
1889     if (len == 0x80000000)      /* special case */
1890       len = 4;
1891     len &= 0x7fffffff;
1892
1893     if (len > 4) {              /* non-inline, so remove data block */
1894       size_t data_offset = le32toh (vk->data_offset);
1895       data_offset += 0x1000;
1896       mark_block_unused (h, data_offset);
1897     }
1898
1899     /* remove vk record */
1900     mark_block_unused (h, values[i]);
1901   }
1902
1903   free (values);
1904
1905   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1906   nk->nr_values = htole32 (0);
1907   nk->vallist = htole32 (0xffffffff);
1908
1909   return 0;
1910 }
1911
1912 int
1913 hivex_commit (hive_h *h, const char *filename, int flags)
1914 {
1915   if (flags != 0) {
1916     errno = EINVAL;
1917     return -1;
1918   }
1919
1920   if (!h->writable) {
1921     errno = EROFS;
1922     return -1;
1923   }
1924
1925   filename = filename ? : h->filename;
1926   int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
1927   if (fd == -1)
1928     return -1;
1929
1930   /* Update the header fields. */
1931   uint32_t sequence = le32toh (h->hdr->sequence1);
1932   sequence++;
1933   h->hdr->sequence1 = htole32 (sequence);
1934   h->hdr->sequence2 = htole32 (sequence);
1935   /* XXX Ought to update h->hdr->last_modified. */
1936   h->hdr->blocks = htole32 (h->endpages - 0x1000);
1937
1938   /* Recompute header checksum. */
1939   uint32_t sum = header_checksum (h);
1940   h->hdr->csum = htole32 (sum);
1941
1942   if (h->msglvl >= 2)
1943     fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum);
1944
1945   if (full_write (fd, h->addr, h->size) != h->size) {
1946     int err = errno;
1947     close (fd);
1948     errno = err;
1949     return -1;
1950   }
1951
1952   if (close (fd) == -1)
1953     return -1;
1954
1955   return 0;
1956 }
1957
1958 int
1959 hivex_node_set_values (hive_h *h, hive_node_h node,
1960                        size_t nr_values, const hive_set_value *values,
1961                        int flags)
1962 {
1963   if (!h->writable) {
1964     errno = EROFS;
1965     return -1;
1966   }
1967
1968   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
1969     errno = EINVAL;
1970     return -1;
1971   }
1972
1973   /* Delete all existing values. */
1974   if (delete_values (h, node) == -1)
1975     return -1;
1976
1977   if (nr_values == 0)
1978     return 0;
1979
1980   /* Allocate value list node.  Value lists have no id field. */
1981   static const char nul_id[2] = { 0, 0 };
1982   size_t seg_len =
1983     sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t);
1984   size_t vallist_offs = allocate_block (h, seg_len, nul_id);
1985   if (vallist_offs == 0)
1986     return -1;
1987
1988   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1989   nk->nr_values = htole32 (nr_values);
1990   nk->vallist = htole32 (vallist_offs - 0x1000);
1991
1992   struct ntreg_value_list *vallist =
1993     (struct ntreg_value_list *) (h->addr + vallist_offs);
1994
1995   size_t i;
1996   for (i = 0; i < nr_values; ++i) {
1997     /* Allocate vk record to store this (key, value) pair. */
1998     static const char vk_id[2] = { 'v', 'k' };
1999     seg_len = sizeof (struct ntreg_vk_record) + strlen (values[i].key);
2000     size_t vk_offs = allocate_block (h, seg_len, vk_id);
2001     if (vk_offs == 0)
2002       return -1;
2003
2004     vallist->offset[i] = htole32 (vk_offs - 0x1000);
2005
2006     struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + vk_offs);
2007     size_t name_len = strlen (values[i].key);
2008     vk->name_len = htole16 (name_len);
2009     strcpy (vk->name, values[i].key);
2010     vk->data_type = htole32 (values[i].t);
2011     vk->data_len = htole16 (values[i].len);
2012     vk->flags = name_len == 0 ? 0 : 1;
2013
2014     if (values[i].len <= 4)     /* Store data inline. */
2015       memcpy (&vk->data_offset, values[i].value, values[i].len);
2016     else {
2017       size_t offs = allocate_block (h, values[i].len + 4, nul_id);
2018       if (offs == 0)
2019         return -1;
2020       memcpy (h->addr + offs + 4, values[i].value, values[i].len);
2021       vk->data_offset = htole32 (offs - 0x1000);
2022     }
2023
2024     if (name_len * 2 > le32toh (nk->max_vk_name_len))
2025       nk->max_vk_name_len = htole32 (name_len * 2);
2026     if (values[i].len > le32toh (nk->max_vk_data_len))
2027       nk->max_vk_data_len = htole32 (values[i].len);
2028   }
2029
2030   return 0;
2031 }