hivex: Add flags argument to internal get_children() function.
[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 #define GET_CHILDREN_NO_CHECK_NK 1
687
688 static int
689 get_children (hive_h *h, hive_node_h node,
690               hive_node_h **children_ret, size_t **blocks_ret,
691               int flags)
692 {
693   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
694     errno = EINVAL;
695     return -1;
696   }
697
698   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
699
700   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
701
702   INIT_OFFSET_LIST (children);
703   INIT_OFFSET_LIST (blocks);
704
705   /* Deal with the common "no subkeys" case quickly. */
706   if (nr_subkeys_in_nk == 0)
707     goto ok;
708
709   /* Arbitrarily limit the number of subkeys we will ever deal with. */
710   if (nr_subkeys_in_nk > 1000000) {
711     errno = ERANGE;
712     goto error;
713   }
714
715   /* Preallocate space for the children. */
716   if (grow_offset_list (&children, nr_subkeys_in_nk) == -1)
717     goto error;
718
719   /* The subkey_lf field can point either to an lf-record, which is
720    * the common case, or if there are lots of subkeys, to an
721    * ri-record.
722    */
723   size_t subkey_lf = le32toh (nk->subkey_lf);
724   subkey_lf += 0x1000;
725   if (!IS_VALID_BLOCK (h, subkey_lf)) {
726     if (h->msglvl >= 2)
727       fprintf (stderr, "hivex_node_children: returning EFAULT because subkey_lf is not a valid block (%zu)\n",
728                subkey_lf);
729     errno = EFAULT;
730     goto error;
731   }
732
733   if (add_to_offset_list (&blocks, subkey_lf) == -1)
734     goto error;
735
736   struct ntreg_hbin_block *block =
737     (struct ntreg_hbin_block *) (h->addr + subkey_lf);
738
739   /* Points to lf-record?  (Note, also "lh" but that is basically the
740    * same as "lf" as far as we are concerned here).
741    */
742   if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
743     struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
744
745     /* Check number of subkeys in the nk-record matches number of subkeys
746      * in the lf-record.
747      */
748     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
749
750     if (h->msglvl >= 2)
751       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, nr_subkeys_in_lf = %zu\n",
752                nr_subkeys_in_nk, nr_subkeys_in_lf);
753
754     if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
755       errno = ENOTSUP;
756       goto error;
757     }
758
759     size_t len = block_len (h, subkey_lf, NULL);
760     if (8 + nr_subkeys_in_lf * 8 > len) {
761       if (h->msglvl >= 2)
762         fprintf (stderr, "hivex_node_children: returning EFAULT because too many subkeys (%zu, %zu)\n",
763                  nr_subkeys_in_lf, len);
764       errno = EFAULT;
765       goto error;
766     }
767
768     size_t i;
769     for (i = 0; i < nr_subkeys_in_lf; ++i) {
770       hive_node_h subkey = le32toh (lf->keys[i].offset);
771       subkey += 0x1000;
772       if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
773         if (!IS_VALID_BLOCK (h, subkey)) {
774           if (h->msglvl >= 2)
775             fprintf (stderr, "hivex_node_children: returning EFAULT because subkey is not a valid block (0x%zx)\n",
776                      subkey);
777           errno = EFAULT;
778           goto error;
779         }
780       }
781       if (add_to_offset_list (&children, subkey) == -1)
782         goto error;
783     }
784     goto ok;
785   }
786   /* Points to ri-record? */
787   else if (block->id[0] == 'r' && block->id[1] == 'i') {
788     struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block;
789
790     size_t nr_offsets = le16toh (ri->nr_offsets);
791
792     /* Count total number of children. */
793     size_t i, count = 0;
794     for (i = 0; i < nr_offsets; ++i) {
795       hive_node_h offset = ri->offset[i];
796       offset += 0x1000;
797       if (!IS_VALID_BLOCK (h, offset)) {
798         if (h->msglvl >= 2)
799           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
800                    offset);
801         errno = EFAULT;
802         goto error;
803       }
804       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
805         errno = ENOTSUP;
806         goto error;
807       }
808
809       if (add_to_offset_list (&blocks, offset) == -1)
810         goto error;
811
812       struct ntreg_lf_record *lf =
813         (struct ntreg_lf_record *) (h->addr + offset);
814
815       count += le16toh (lf->nr_keys);
816     }
817
818     if (h->msglvl >= 2)
819       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, counted = %zu\n",
820                nr_subkeys_in_nk, count);
821
822     if (nr_subkeys_in_nk != count) {
823       errno = ENOTSUP;
824       goto error;
825     }
826
827     /* Copy list of children.  Note nr_subkeys_in_nk is limited to
828      * something reasonable above.
829      */
830     for (i = 0; i < nr_offsets; ++i) {
831       hive_node_h offset = ri->offset[i];
832       offset += 0x1000;
833       if (!IS_VALID_BLOCK (h, offset)) {
834         if (h->msglvl >= 2)
835           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
836                    offset);
837         errno = EFAULT;
838         goto error;
839       }
840       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
841         errno = ENOTSUP;
842         goto error;
843       }
844
845       struct ntreg_lf_record *lf =
846         (struct ntreg_lf_record *) (h->addr + offset);
847
848       size_t j;
849       for (j = 0; j < le16toh (lf->nr_keys); ++j) {
850         hive_node_h subkey = le32toh (lf->keys[j].offset);
851         subkey += 0x1000;
852         if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
853           if (!IS_VALID_BLOCK (h, subkey)) {
854             if (h->msglvl >= 2)
855               fprintf (stderr, "hivex_node_children: returning EFAULT because indirect subkey is not a valid block (0x%zx)\n",
856                        subkey);
857             errno = EFAULT;
858             goto error;
859           }
860         }
861         if (add_to_offset_list (&children, subkey) == -1)
862           goto error;
863       }
864     }
865     goto ok;
866   }
867   /* else not supported, set errno and fall through */
868   errno = ENOTSUP;
869  error:
870   free_offset_list (&children);
871   free_offset_list (&blocks);
872   return -1;
873
874  ok:
875   *children_ret = return_offset_list (&children);
876   *blocks_ret = return_offset_list (&blocks);
877   if (!*children_ret || !*blocks_ret)
878     goto error;
879   return 0;
880 }
881
882 hive_node_h *
883 hivex_node_children (hive_h *h, hive_node_h node)
884 {
885   hive_node_h *children;
886   size_t *blocks;
887
888   if (get_children (h, node, &children, &blocks, 0) == -1)
889     return NULL;
890
891   free (blocks);
892   return children;
893 }
894
895 /* Very inefficient, but at least having a separate API call
896  * allows us to make it more efficient in future.
897  */
898 hive_node_h
899 hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
900 {
901   hive_node_h *children = NULL;
902   char *name = NULL;
903   hive_node_h ret = 0;
904
905   children = hivex_node_children (h, node);
906   if (!children) goto error;
907
908   size_t i;
909   for (i = 0; children[i] != 0; ++i) {
910     name = hivex_node_name (h, children[i]);
911     if (!name) goto error;
912     if (STRCASEEQ (name, nname)) {
913       ret = children[i];
914       break;
915     }
916     free (name); name = NULL;
917   }
918
919  error:
920   free (children);
921   free (name);
922   return ret;
923 }
924
925 hive_node_h
926 hivex_node_parent (hive_h *h, hive_node_h node)
927 {
928   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
929     errno = EINVAL;
930     return 0;
931   }
932
933   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
934
935   hive_node_h ret = le32toh (nk->parent);
936   ret += 0x1000;
937   if (!IS_VALID_BLOCK (h, ret)) {
938     if (h->msglvl >= 2)
939       fprintf (stderr, "hivex_node_parent: returning EFAULT because parent is not a valid block (0x%zx)\n",
940               ret);
941     errno = EFAULT;
942     return 0;
943   }
944   return ret;
945 }
946
947 static int
948 get_values (hive_h *h, hive_node_h node,
949             hive_value_h **values_ret, size_t **blocks_ret)
950 {
951   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
952     errno = EINVAL;
953     return -1;
954   }
955
956   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
957
958   size_t nr_values = le32toh (nk->nr_values);
959
960   if (h->msglvl >= 2)
961     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
962
963   INIT_OFFSET_LIST (values);
964   INIT_OFFSET_LIST (blocks);
965
966   /* Deal with the common "no values" case quickly. */
967   if (nr_values == 0)
968     goto ok;
969
970   /* Arbitrarily limit the number of values we will ever deal with. */
971   if (nr_values > 100000) {
972     errno = ERANGE;
973     goto error;
974   }
975
976   /* Preallocate space for the values. */
977   if (grow_offset_list (&values, nr_values) == -1)
978     goto error;
979
980   /* Get the value list and check it looks reasonable. */
981   size_t vlist_offset = le32toh (nk->vallist);
982   vlist_offset += 0x1000;
983   if (!IS_VALID_BLOCK (h, vlist_offset)) {
984     if (h->msglvl >= 2)
985       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is not a valid block (0x%zx)\n",
986                vlist_offset);
987     errno = EFAULT;
988     goto error;
989   }
990
991   if (add_to_offset_list (&blocks, vlist_offset) == -1)
992     goto error;
993
994   struct ntreg_value_list *vlist =
995     (struct ntreg_value_list *) (h->addr + vlist_offset);
996
997   size_t len = block_len (h, vlist_offset, NULL);
998   if (4 + nr_values * 4 > len) {
999     if (h->msglvl >= 2)
1000       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is too long (%zu, %zu)\n",
1001                nr_values, len);
1002     errno = EFAULT;
1003     goto error;
1004   }
1005
1006   size_t i;
1007   for (i = 0; i < nr_values; ++i) {
1008     hive_node_h value = vlist->offset[i];
1009     value += 0x1000;
1010     if (!IS_VALID_BLOCK (h, value)) {
1011       if (h->msglvl >= 2)
1012         fprintf (stderr, "hivex_node_values: returning EFAULT because value is not a valid block (0x%zx)\n",
1013                  value);
1014       errno = EFAULT;
1015       goto error;
1016     }
1017     if (add_to_offset_list (&values, value) == -1)
1018       goto error;
1019   }
1020
1021  ok:
1022   *values_ret = return_offset_list (&values);
1023   *blocks_ret = return_offset_list (&blocks);
1024   if (!*values_ret || !*blocks_ret)
1025     goto error;
1026   return 0;
1027
1028  error:
1029   free_offset_list (&values);
1030   free_offset_list (&blocks);
1031   return -1;
1032 }
1033
1034 hive_value_h *
1035 hivex_node_values (hive_h *h, hive_node_h node)
1036 {
1037   hive_value_h *values;
1038   size_t *blocks;
1039
1040   if (get_values (h, node, &values, &blocks) == -1)
1041     return NULL;
1042
1043   free (blocks);
1044   return values;
1045 }
1046
1047 /* Very inefficient, but at least having a separate API call
1048  * allows us to make it more efficient in future.
1049  */
1050 hive_value_h
1051 hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
1052 {
1053   hive_value_h *values = NULL;
1054   char *name = NULL;
1055   hive_value_h ret = 0;
1056
1057   values = hivex_node_values (h, node);
1058   if (!values) goto error;
1059
1060   size_t i;
1061   for (i = 0; values[i] != 0; ++i) {
1062     name = hivex_value_key (h, values[i]);
1063     if (!name) goto error;
1064     if (STRCASEEQ (name, key)) {
1065       ret = values[i];
1066       break;
1067     }
1068     free (name); name = NULL;
1069   }
1070
1071  error:
1072   free (values);
1073   free (name);
1074   return ret;
1075 }
1076
1077 char *
1078 hivex_value_key (hive_h *h, hive_value_h value)
1079 {
1080   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1081     errno = EINVAL;
1082     return 0;
1083   }
1084
1085   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1086
1087   /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
1088    * necessary.  However we do need to nul-terminate the string.
1089    */
1090
1091   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
1092    * we have to make sure the length doesn't exceed the block length.
1093    */
1094   size_t len = le16toh (vk->name_len);
1095   size_t seg_len = block_len (h, value, NULL);
1096   if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
1097     if (h->msglvl >= 2)
1098       fprintf (stderr, "hivex_value_key: returning EFAULT because key length is too long (%zu, %zu)\n",
1099                len, seg_len);
1100     errno = EFAULT;
1101     return NULL;
1102   }
1103
1104   char *ret = malloc (len + 1);
1105   if (ret == NULL)
1106     return NULL;
1107   memcpy (ret, vk->name, len);
1108   ret[len] = '\0';
1109   return ret;
1110 }
1111
1112 int
1113 hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
1114 {
1115   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1116     errno = EINVAL;
1117     return -1;
1118   }
1119
1120   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1121
1122   if (t)
1123     *t = le32toh (vk->data_type);
1124
1125   if (len) {
1126     *len = le32toh (vk->data_len);
1127     if (*len == 0x80000000) {   /* special case */
1128       *len = 4;
1129       if (t) *t = hive_t_dword;
1130     }
1131     *len &= 0x7fffffff;
1132   }
1133
1134   return 0;
1135 }
1136
1137 char *
1138 hivex_value_value (hive_h *h, hive_value_h value,
1139                    hive_type *t_rtn, size_t *len_rtn)
1140 {
1141   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1142     errno = EINVAL;
1143     return NULL;
1144   }
1145
1146   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1147
1148   hive_type t;
1149   size_t len;
1150
1151   t = le32toh (vk->data_type);
1152
1153   len = le32toh (vk->data_len);
1154   if (len == 0x80000000) {      /* special case */
1155     len = 4;
1156     t = hive_t_dword;
1157   }
1158   len &= 0x7fffffff;
1159
1160   if (h->msglvl >= 2)
1161     fprintf (stderr, "hivex_value_value: value=0x%zx, t=%d, len=%zu\n",
1162              value, t, len);
1163
1164   if (t_rtn)
1165     *t_rtn = t;
1166   if (len_rtn)
1167     *len_rtn = len;
1168
1169   /* Arbitrarily limit the length that we will read. */
1170   if (len > 1000000) {
1171     errno = ERANGE;
1172     return NULL;
1173   }
1174
1175   char *ret = malloc (len);
1176   if (ret == NULL)
1177     return NULL;
1178
1179   /* If length is <= 4 it's always stored inline. */
1180   if (len <= 4) {
1181     memcpy (ret, (char *) &vk->data_offset, len);
1182     return ret;
1183   }
1184
1185   size_t data_offset = le32toh (vk->data_offset);
1186   data_offset += 0x1000;
1187   if (!IS_VALID_BLOCK (h, data_offset)) {
1188     if (h->msglvl >= 2)
1189       fprintf (stderr, "hivex_value_value: returning EFAULT because data offset is not a valid block (0x%zx)\n",
1190                data_offset);
1191     errno = EFAULT;
1192     free (ret);
1193     return NULL;
1194   }
1195
1196   /* Check that the declared size isn't larger than the block its in.
1197    *
1198    * XXX Some apparently valid registries are seen to have this,
1199    * so turn this into a warning and substitute the smaller length
1200    * instead.
1201    */
1202   size_t blen = block_len (h, data_offset, NULL);
1203   if (len > blen - 4 /* subtract 4 for block header */) {
1204     if (h->msglvl >= 2)
1205       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",
1206                data_offset, len, blen);
1207     len = blen - 4;
1208   }
1209
1210   char *data = h->addr + data_offset + 4;
1211   memcpy (ret, data, len);
1212   return ret;
1213 }
1214
1215 static char *
1216 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1217 {
1218   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1219   if (ic == (iconv_t) -1)
1220     return NULL;
1221
1222   /* iconv(3) has an insane interface ... */
1223
1224   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1225   size_t outalloc = len;
1226
1227  again:;
1228   size_t inlen = len;
1229   size_t outlen = outalloc;
1230   char *out = malloc (outlen + 1);
1231   if (out == NULL) {
1232     int err = errno;
1233     iconv_close (ic);
1234     errno = err;
1235     return NULL;
1236   }
1237   char *inp = input;
1238   char *outp = out;
1239
1240   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1241   if (r == (size_t) -1) {
1242     if (errno == E2BIG) {
1243       size_t prev = outalloc;
1244       /* Try again with a larger output buffer. */
1245       free (out);
1246       outalloc *= 2;
1247       if (outalloc < prev)
1248         return NULL;
1249       goto again;
1250     }
1251     else {
1252       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1253       int err = errno;
1254       iconv_close (ic);
1255       free (out);
1256       errno = err;
1257       return NULL;
1258     }
1259   }
1260
1261   *outp = '\0';
1262   iconv_close (ic);
1263
1264   return out;
1265 }
1266
1267 char *
1268 hivex_value_string (hive_h *h, hive_value_h value)
1269 {
1270   hive_type t;
1271   size_t len;
1272   char *data = hivex_value_value (h, value, &t, &len);
1273
1274   if (data == NULL)
1275     return NULL;
1276
1277   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1278     free (data);
1279     errno = EINVAL;
1280     return NULL;
1281   }
1282
1283   char *ret = windows_utf16_to_utf8 (data, len);
1284   free (data);
1285   if (ret == NULL)
1286     return NULL;
1287
1288   return ret;
1289 }
1290
1291 static void
1292 free_strings (char **argv)
1293 {
1294   if (argv) {
1295     size_t i;
1296
1297     for (i = 0; argv[i] != NULL; ++i)
1298       free (argv[i]);
1299     free (argv);
1300   }
1301 }
1302
1303 /* Get the length of a UTF-16 format string.  Handle the string as
1304  * pairs of bytes, looking for the first \0\0 pair.
1305  */
1306 static size_t
1307 utf16_string_len_in_bytes (const char *str)
1308 {
1309   size_t ret = 0;
1310
1311   while (str[0] || str[1]) {
1312     str += 2;
1313     ret += 2;
1314   }
1315
1316   return ret;
1317 }
1318
1319 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1320 char **
1321 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1322 {
1323   hive_type t;
1324   size_t len;
1325   char *data = hivex_value_value (h, value, &t, &len);
1326
1327   if (data == NULL)
1328     return NULL;
1329
1330   if (t != hive_t_multiple_strings) {
1331     free (data);
1332     errno = EINVAL;
1333     return NULL;
1334   }
1335
1336   size_t nr_strings = 0;
1337   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1338   if (ret == NULL) {
1339     free (data);
1340     return NULL;
1341   }
1342   ret[0] = NULL;
1343
1344   char *p = data;
1345   size_t plen;
1346
1347   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1348     nr_strings++;
1349     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1350     if (ret2 == NULL) {
1351       free_strings (ret);
1352       free (data);
1353       return NULL;
1354     }
1355     ret = ret2;
1356
1357     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1358     ret[nr_strings] = NULL;
1359     if (ret[nr_strings-1] == NULL) {
1360       free_strings (ret);
1361       free (data);
1362       return NULL;
1363     }
1364
1365     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1366   }
1367
1368   free (data);
1369   return ret;
1370 }
1371
1372 int32_t
1373 hivex_value_dword (hive_h *h, hive_value_h value)
1374 {
1375   hive_type t;
1376   size_t len;
1377   char *data = hivex_value_value (h, value, &t, &len);
1378
1379   if (data == NULL)
1380     return -1;
1381
1382   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1383     free (data);
1384     errno = EINVAL;
1385     return -1;
1386   }
1387
1388   int32_t ret = *(int32_t*)data;
1389   free (data);
1390   if (t == hive_t_dword)        /* little endian */
1391     ret = le32toh (ret);
1392   else
1393     ret = be32toh (ret);
1394
1395   return ret;
1396 }
1397
1398 int64_t
1399 hivex_value_qword (hive_h *h, hive_value_h value)
1400 {
1401   hive_type t;
1402   size_t len;
1403   char *data = hivex_value_value (h, value, &t, &len);
1404
1405   if (data == NULL)
1406     return -1;
1407
1408   if (t != hive_t_qword || len != 8) {
1409     free (data);
1410     errno = EINVAL;
1411     return -1;
1412   }
1413
1414   int64_t ret = *(int64_t*)data;
1415   free (data);
1416   ret = le64toh (ret);          /* always little endian */
1417
1418   return ret;
1419 }
1420
1421 /*----------------------------------------------------------------------
1422  * Visiting.
1423  */
1424
1425 int
1426 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1427              void *opaque, int flags)
1428 {
1429   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1430 }
1431
1432 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1433
1434 int
1435 hivex_visit_node (hive_h *h, hive_node_h node,
1436                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1437                   int flags)
1438 {
1439   struct hivex_visitor vtor;
1440   memset (&vtor, 0, sizeof vtor);
1441
1442   /* Note that len might be larger *or smaller* than the expected size. */
1443   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1444   memcpy (&vtor, visitor, copysize);
1445
1446   /* This bitmap records unvisited nodes, so we don't loop if the
1447    * registry contains cycles.
1448    */
1449   char *unvisited = malloc (1 + h->size / 32);
1450   if (unvisited == NULL)
1451     return -1;
1452   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1453
1454   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1455   free (unvisited);
1456   return r;
1457 }
1458
1459 static int
1460 hivex__visit_node (hive_h *h, hive_node_h node,
1461                    const struct hivex_visitor *vtor, char *unvisited,
1462                    void *opaque, int flags)
1463 {
1464   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1465   char *name = NULL;
1466   hive_value_h *values = NULL;
1467   hive_node_h *children = NULL;
1468   char *key = NULL;
1469   char *str = NULL;
1470   char **strs = NULL;
1471   int i;
1472
1473   /* Return -1 on all callback errors.  However on internal errors,
1474    * check if skip_bad is set and suppress those errors if so.
1475    */
1476   int ret = -1;
1477
1478   if (!BITMAP_TST (unvisited, node)) {
1479     if (h->msglvl >= 2)
1480       fprintf (stderr, "hivex__visit_node: contains cycle: visited node 0x%zx already\n",
1481                node);
1482
1483     errno = ELOOP;
1484     return skip_bad ? 0 : -1;
1485   }
1486   BITMAP_CLR (unvisited, node);
1487
1488   name = hivex_node_name (h, node);
1489   if (!name) return skip_bad ? 0 : -1;
1490   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1491     goto error;
1492
1493   values = hivex_node_values (h, node);
1494   if (!values) {
1495     ret = skip_bad ? 0 : -1;
1496     goto error;
1497   }
1498
1499   for (i = 0; values[i] != 0; ++i) {
1500     hive_type t;
1501     size_t len;
1502
1503     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1504       ret = skip_bad ? 0 : -1;
1505       goto error;
1506     }
1507
1508     key = hivex_value_key (h, values[i]);
1509     if (key == NULL) {
1510       ret = skip_bad ? 0 : -1;
1511       goto error;
1512     }
1513
1514     if (vtor->value_any) {
1515       str = hivex_value_value (h, values[i], &t, &len);
1516       if (str == NULL) {
1517         ret = skip_bad ? 0 : -1;
1518         goto error;
1519       }
1520       if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
1521         goto error;
1522       free (str); str = NULL;
1523     }
1524     else {
1525       switch (t) {
1526       case hive_t_none:
1527         str = hivex_value_value (h, values[i], &t, &len);
1528         if (str == NULL) {
1529           ret = skip_bad ? 0 : -1;
1530           goto error;
1531         }
1532         if (t != hive_t_none) {
1533           ret = skip_bad ? 0 : -1;
1534           goto error;
1535         }
1536         if (vtor->value_none &&
1537             vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1538           goto error;
1539         free (str); str = NULL;
1540         break;
1541
1542       case hive_t_string:
1543       case hive_t_expand_string:
1544       case hive_t_link:
1545         str = hivex_value_string (h, values[i]);
1546         if (str == NULL) {
1547           if (errno != EILSEQ && errno != EINVAL) {
1548             ret = skip_bad ? 0 : -1;
1549             goto error;
1550           }
1551           if (vtor->value_string_invalid_utf16) {
1552             str = hivex_value_value (h, values[i], &t, &len);
1553             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1554               goto error;
1555             free (str); str = NULL;
1556           }
1557           break;
1558         }
1559         if (vtor->value_string &&
1560             vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1561           goto error;
1562         free (str); str = NULL;
1563         break;
1564
1565       case hive_t_dword:
1566       case hive_t_dword_be: {
1567         int32_t i32 = hivex_value_dword (h, values[i]);
1568         if (vtor->value_dword &&
1569             vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1570           goto error;
1571         break;
1572       }
1573
1574       case hive_t_qword: {
1575         int64_t i64 = hivex_value_qword (h, values[i]);
1576         if (vtor->value_qword &&
1577             vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1578           goto error;
1579         break;
1580       }
1581
1582       case hive_t_binary:
1583         str = hivex_value_value (h, values[i], &t, &len);
1584         if (str == NULL) {
1585           ret = skip_bad ? 0 : -1;
1586           goto error;
1587         }
1588         if (t != hive_t_binary) {
1589           ret = skip_bad ? 0 : -1;
1590           goto error;
1591         }
1592         if (vtor->value_binary &&
1593             vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1594           goto error;
1595         free (str); str = NULL;
1596         break;
1597
1598       case hive_t_multiple_strings:
1599         strs = hivex_value_multiple_strings (h, values[i]);
1600         if (strs == NULL) {
1601           if (errno != EILSEQ && errno != EINVAL) {
1602             ret = skip_bad ? 0 : -1;
1603             goto error;
1604           }
1605           if (vtor->value_string_invalid_utf16) {
1606             str = hivex_value_value (h, values[i], &t, &len);
1607             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1608               goto error;
1609             free (str); str = NULL;
1610           }
1611           break;
1612         }
1613         if (vtor->value_multiple_strings &&
1614             vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1615           goto error;
1616         free_strings (strs); strs = NULL;
1617         break;
1618
1619       case hive_t_resource_list:
1620       case hive_t_full_resource_description:
1621       case hive_t_resource_requirements_list:
1622       default:
1623         str = hivex_value_value (h, values[i], &t, &len);
1624         if (str == NULL) {
1625           ret = skip_bad ? 0 : -1;
1626           goto error;
1627         }
1628         if (vtor->value_other &&
1629             vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1630           goto error;
1631         free (str); str = NULL;
1632         break;
1633       }
1634     }
1635
1636     free (key); key = NULL;
1637   }
1638
1639   children = hivex_node_children (h, node);
1640   if (children == NULL) {
1641     ret = skip_bad ? 0 : -1;
1642     goto error;
1643   }
1644
1645   for (i = 0; children[i] != 0; ++i) {
1646     if (h->msglvl >= 2)
1647       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n",
1648                name, i, children[i]);
1649
1650     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1651       goto error;
1652   }
1653
1654   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1655     goto error;
1656
1657   ret = 0;
1658
1659  error:
1660   free (name);
1661   free (values);
1662   free (children);
1663   free (key);
1664   free (str);
1665   free_strings (strs);
1666   return ret;
1667 }
1668
1669 /*----------------------------------------------------------------------
1670  * Writing.
1671  */
1672
1673 /* Allocate an hbin (page), extending the malloc'd space if necessary,
1674  * and updating the hive handle fields (but NOT the hive disk header
1675  * -- the hive disk header is updated when we commit).  This function
1676  * also extends the bitmap if necessary.
1677  *
1678  * 'allocation_hint' is the size of the block allocation we would like
1679  * to make.  Normally registry blocks are very small (avg 50 bytes)
1680  * and are contained in standard-sized pages (4KB), but the registry
1681  * can support blocks which are larger than a standard page, in which
1682  * case it creates a page of 8KB, 12KB etc.
1683  *
1684  * Returns:
1685  * > 0 : offset of first usable byte of new page (after page header)
1686  * 0   : error (errno set)
1687  */
1688 static size_t
1689 allocate_page (hive_h *h, size_t allocation_hint)
1690 {
1691   /* In almost all cases this will be 1. */
1692   size_t nr_4k_pages =
1693     1 + (allocation_hint + sizeof (struct ntreg_hbin_page) - 1) / 4096;
1694   assert (nr_4k_pages >= 1);
1695
1696   /* 'extend' is the number of bytes to extend the file by.  Note that
1697    * hives found in the wild often contain slack between 'endpages'
1698    * and the actual end of the file, so we don't always need to make
1699    * the file larger.
1700    */
1701   ssize_t extend = h->endpages + nr_4k_pages * 4096 - h->size;
1702
1703   if (h->msglvl >= 2) {
1704     fprintf (stderr, "allocate_page: current endpages = 0x%zx, current size = 0x%zx\n",
1705              h->endpages, h->size);
1706     fprintf (stderr, "allocate_page: extending file by %zd bytes (<= 0 if no extension)\n",
1707              extend);
1708   }
1709
1710   if (extend > 0) {
1711     size_t oldsize = h->size;
1712     size_t newsize = h->size + extend;
1713     char *newaddr = realloc (h->addr, newsize);
1714     if (newaddr == NULL)
1715       return 0;
1716
1717     size_t oldbitmapsize = 1 + oldsize / 32;
1718     size_t newbitmapsize = 1 + newsize / 32;
1719     char *newbitmap = realloc (h->bitmap, newbitmapsize);
1720     if (newbitmap == NULL) {
1721       free (newaddr);
1722       return 0;
1723     }
1724
1725     h->addr = newaddr;
1726     h->size = newsize;
1727     h->bitmap = newbitmap;
1728
1729     memset (h->addr + oldsize, 0, newsize - oldsize);
1730     memset (h->bitmap + oldbitmapsize, 0, newbitmapsize - oldbitmapsize);
1731   }
1732
1733   size_t offset = h->endpages;
1734   h->endpages += nr_4k_pages * 4096;
1735
1736   if (h->msglvl >= 2)
1737     fprintf (stderr, "allocate_page: new endpages = 0x%zx, new size = 0x%zx\n",
1738              h->endpages, h->size);
1739
1740   /* Write the hbin header. */
1741   struct ntreg_hbin_page *page =
1742     (struct ntreg_hbin_page *) (h->addr + offset);
1743   page->magic[0] = 'h';
1744   page->magic[1] = 'b';
1745   page->magic[2] = 'i';
1746   page->magic[3] = 'n';
1747   page->offset_first = htole32 (offset - 0x1000);
1748   page->page_size = htole32 (nr_4k_pages * 4096);
1749   memset (page->unknown, 0, sizeof (page->unknown));
1750
1751   if (h->msglvl >= 2)
1752     fprintf (stderr, "allocate_page: new page at 0x%zx\n", offset);
1753
1754   /* Offset of first usable byte after the header. */
1755   return offset + sizeof (struct ntreg_hbin_page);
1756 }
1757
1758 /* Allocate a single block, first allocating an hbin (page) at the end
1759  * of the current file if necessary.  NB. To keep the implementation
1760  * simple and more likely to be correct, we do not reuse existing free
1761  * blocks.
1762  *
1763  * seg_len is the size of the block (this INCLUDES the block header).
1764  * The header of the block is initialized to -seg_len (negative to
1765  * indicate used).  id[2] is the block ID (type), eg. "nk" for nk-
1766  * record.  The block bitmap is updated to show this block as valid.
1767  * The rest of the contents of the block will be zero.
1768  *
1769  * Returns:
1770  * > 0 : offset of new block
1771  * 0   : error (errno set)
1772  */
1773 static size_t
1774 allocate_block (hive_h *h, size_t seg_len, const char id[2])
1775 {
1776   if (!h->writable) {
1777     errno = EROFS;
1778     return 0;
1779   }
1780
1781   if (seg_len < 4) {
1782     /* The caller probably forgot to include the header.  Note that
1783      * value lists have no ID field, so seg_len == 4 would be possible
1784      * for them, albeit unusual.
1785      */
1786     if (h->msglvl >= 2)
1787       fprintf (stderr, "allocate_block: refusing too small allocation (%zu), returning ERANGE\n",
1788                seg_len);
1789     errno = ERANGE;
1790     return 0;
1791   }
1792
1793   /* Refuse really large allocations. */
1794   if (seg_len > 1000000) {
1795     if (h->msglvl >= 2)
1796       fprintf (stderr, "allocate_block: refusing large allocation (%zu), returning ERANGE\n",
1797                seg_len);
1798     errno = ERANGE;
1799     return 0;
1800   }
1801
1802   /* Round up allocation to multiple of 8 bytes.  All blocks must be
1803    * on an 8 byte boundary.
1804    */
1805   seg_len = (seg_len + 7) & ~7;
1806
1807   /* Allocate a new page if necessary. */
1808   if (h->endblocks == 0 || h->endblocks + seg_len > h->endpages) {
1809     size_t newendblocks = allocate_page (h, seg_len);
1810     if (newendblocks == 0)
1811       return 0;
1812     h->endblocks = newendblocks;
1813   }
1814
1815   size_t offset = h->endblocks;
1816
1817   if (h->msglvl >= 2)
1818     fprintf (stderr, "allocate_block: new block at 0x%zx, size %zu\n",
1819              offset, seg_len);
1820
1821   struct ntreg_hbin_block *blockhdr =
1822     (struct ntreg_hbin_block *) (h->addr + offset);
1823
1824   blockhdr->seg_len = htole32 (- (int32_t) seg_len);
1825   if (id[0] && id[1] && seg_len >= 6) {
1826     blockhdr->id[0] = id[0];
1827     blockhdr->id[1] = id[1];
1828   }
1829
1830   h->endblocks += seg_len;
1831
1832   /* If there is space after the last block in the last page, then we
1833    * have to put a dummy free block header here to mark the rest of
1834    * the page as free.
1835    */
1836   ssize_t rem = h->endpages - h->endblocks;
1837   if (rem > 0) {
1838     if (h->msglvl >= 2)
1839       fprintf (stderr, "allocate_block: marking remainder of page free starting at 0x%zx, size %zd\n",
1840                h->endblocks, rem);
1841
1842     assert (rem >= 4);
1843
1844     blockhdr = (struct ntreg_hbin_block *) (h->addr + h->endblocks);
1845     blockhdr->seg_len = htole32 ((int32_t) rem);
1846   }
1847
1848   return offset;
1849 }
1850
1851 /* 'offset' must point to a valid, used block.  This function marks
1852  * the block unused (by updating the seg_len field) and invalidates
1853  * the bitmap.  It does NOT do this recursively, so to avoid creating
1854  * unreachable used blocks, callers may have to recurse over the hive
1855  * structures.  Also callers must ensure there are no references to
1856  * this block from other parts of the hive.
1857  */
1858 static void
1859 mark_block_unused (hive_h *h, size_t offset)
1860 {
1861   assert (h->writable);
1862   assert (IS_VALID_BLOCK (h, offset));
1863
1864   struct ntreg_hbin_block *blockhdr =
1865     (struct ntreg_hbin_block *) (h->addr + offset);
1866
1867   size_t seg_len = block_len (h, offset, NULL);
1868   blockhdr->seg_len = htole32 (seg_len);
1869
1870   BITMAP_CLR (h->bitmap, offset);
1871 }
1872
1873 /* Delete all existing values at this node. */
1874 static int
1875 delete_values (hive_h *h, hive_node_h node)
1876 {
1877   assert (h->writable);
1878
1879   hive_value_h *values;
1880   size_t *blocks;
1881   if (get_values (h, node, &values, &blocks) == -1)
1882     return -1;
1883
1884   size_t i;
1885   for (i = 0; blocks[i] != 0; ++i)
1886     mark_block_unused (h, blocks[i]);
1887
1888   free (blocks);
1889
1890   for (i = 0; values[i] != 0; ++i) {
1891     struct ntreg_vk_record *vk =
1892       (struct ntreg_vk_record *) (h->addr + values[i]);
1893
1894     size_t len;
1895     len = le32toh (vk->data_len);
1896     if (len == 0x80000000)      /* special case */
1897       len = 4;
1898     len &= 0x7fffffff;
1899
1900     if (len > 4) {              /* non-inline, so remove data block */
1901       size_t data_offset = le32toh (vk->data_offset);
1902       data_offset += 0x1000;
1903       mark_block_unused (h, data_offset);
1904     }
1905
1906     /* remove vk record */
1907     mark_block_unused (h, values[i]);
1908   }
1909
1910   free (values);
1911
1912   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1913   nk->nr_values = htole32 (0);
1914   nk->vallist = htole32 (0xffffffff);
1915
1916   return 0;
1917 }
1918
1919 int
1920 hivex_commit (hive_h *h, const char *filename, int flags)
1921 {
1922   if (flags != 0) {
1923     errno = EINVAL;
1924     return -1;
1925   }
1926
1927   if (!h->writable) {
1928     errno = EROFS;
1929     return -1;
1930   }
1931
1932   filename = filename ? : h->filename;
1933   int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
1934   if (fd == -1)
1935     return -1;
1936
1937   /* Update the header fields. */
1938   uint32_t sequence = le32toh (h->hdr->sequence1);
1939   sequence++;
1940   h->hdr->sequence1 = htole32 (sequence);
1941   h->hdr->sequence2 = htole32 (sequence);
1942   /* XXX Ought to update h->hdr->last_modified. */
1943   h->hdr->blocks = htole32 (h->endpages - 0x1000);
1944
1945   /* Recompute header checksum. */
1946   uint32_t sum = header_checksum (h);
1947   h->hdr->csum = htole32 (sum);
1948
1949   if (h->msglvl >= 2)
1950     fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum);
1951
1952   if (full_write (fd, h->addr, h->size) != h->size) {
1953     int err = errno;
1954     close (fd);
1955     errno = err;
1956     return -1;
1957   }
1958
1959   if (close (fd) == -1)
1960     return -1;
1961
1962   return 0;
1963 }
1964
1965 int
1966 hivex_node_set_values (hive_h *h, hive_node_h node,
1967                        size_t nr_values, const hive_set_value *values,
1968                        int flags)
1969 {
1970   if (!h->writable) {
1971     errno = EROFS;
1972     return -1;
1973   }
1974
1975   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
1976     errno = EINVAL;
1977     return -1;
1978   }
1979
1980   /* Delete all existing values. */
1981   if (delete_values (h, node) == -1)
1982     return -1;
1983
1984   if (nr_values == 0)
1985     return 0;
1986
1987   /* Allocate value list node.  Value lists have no id field. */
1988   static const char nul_id[2] = { 0, 0 };
1989   size_t seg_len =
1990     sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t);
1991   size_t vallist_offs = allocate_block (h, seg_len, nul_id);
1992   if (vallist_offs == 0)
1993     return -1;
1994
1995   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1996   nk->nr_values = htole32 (nr_values);
1997   nk->vallist = htole32 (vallist_offs - 0x1000);
1998
1999   struct ntreg_value_list *vallist =
2000     (struct ntreg_value_list *) (h->addr + vallist_offs);
2001
2002   size_t i;
2003   for (i = 0; i < nr_values; ++i) {
2004     /* Allocate vk record to store this (key, value) pair. */
2005     static const char vk_id[2] = { 'v', 'k' };
2006     seg_len = sizeof (struct ntreg_vk_record) + strlen (values[i].key);
2007     size_t vk_offs = allocate_block (h, seg_len, vk_id);
2008     if (vk_offs == 0)
2009       return -1;
2010
2011     vallist->offset[i] = htole32 (vk_offs - 0x1000);
2012
2013     struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + vk_offs);
2014     size_t name_len = strlen (values[i].key);
2015     vk->name_len = htole16 (name_len);
2016     strcpy (vk->name, values[i].key);
2017     vk->data_type = htole32 (values[i].t);
2018     vk->data_len = htole16 (values[i].len);
2019     vk->flags = name_len == 0 ? 0 : 1;
2020
2021     if (values[i].len <= 4)     /* Store data inline. */
2022       memcpy (&vk->data_offset, values[i].value, values[i].len);
2023     else {
2024       size_t offs = allocate_block (h, values[i].len + 4, nul_id);
2025       if (offs == 0)
2026         return -1;
2027       memcpy (h->addr + offs + 4, values[i].value, values[i].len);
2028       vk->data_offset = htole32 (offs - 0x1000);
2029     }
2030
2031     if (name_len * 2 > le32toh (nk->max_vk_name_len))
2032       nk->max_vk_name_len = htole32 (name_len * 2);
2033     if (values[i].len > le32toh (nk->max_vk_data_len))
2034       nk->max_vk_data_len = htole32 (values[i].len);
2035   }
2036
2037   return 0;
2038 }