hivex: Begin implementation of writing to hives.
[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   size_t blen = block_len (h, data_offset, NULL);
1191   if (len > blen - 4 /* subtract 4 for block header */) {
1192     if (h->msglvl >= 2)
1193       fprintf (stderr, "hivex_value_value: returning EFAULT because data is longer than its block (data 0x%zx, data len %zu, block len %zu)\n",
1194                data_offset, len, blen);
1195     errno = EFAULT;
1196     free (ret);
1197     return NULL;
1198   }
1199
1200   char *data = h->addr + data_offset + 4;
1201   memcpy (ret, data, len);
1202   return ret;
1203 }
1204
1205 static char *
1206 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1207 {
1208   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1209   if (ic == (iconv_t) -1)
1210     return NULL;
1211
1212   /* iconv(3) has an insane interface ... */
1213
1214   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1215   size_t outalloc = len;
1216
1217  again:;
1218   size_t inlen = len;
1219   size_t outlen = outalloc;
1220   char *out = malloc (outlen + 1);
1221   if (out == NULL) {
1222     int err = errno;
1223     iconv_close (ic);
1224     errno = err;
1225     return NULL;
1226   }
1227   char *inp = input;
1228   char *outp = out;
1229
1230   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1231   if (r == (size_t) -1) {
1232     if (errno == E2BIG) {
1233       size_t prev = outalloc;
1234       /* Try again with a larger output buffer. */
1235       free (out);
1236       outalloc *= 2;
1237       if (outalloc < prev)
1238         return NULL;
1239       goto again;
1240     }
1241     else {
1242       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1243       int err = errno;
1244       iconv_close (ic);
1245       free (out);
1246       errno = err;
1247       return NULL;
1248     }
1249   }
1250
1251   *outp = '\0';
1252   iconv_close (ic);
1253
1254   return out;
1255 }
1256
1257 char *
1258 hivex_value_string (hive_h *h, hive_value_h value)
1259 {
1260   hive_type t;
1261   size_t len;
1262   char *data = hivex_value_value (h, value, &t, &len);
1263
1264   if (data == NULL)
1265     return NULL;
1266
1267   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1268     free (data);
1269     errno = EINVAL;
1270     return NULL;
1271   }
1272
1273   char *ret = windows_utf16_to_utf8 (data, len);
1274   free (data);
1275   if (ret == NULL)
1276     return NULL;
1277
1278   return ret;
1279 }
1280
1281 static void
1282 free_strings (char **argv)
1283 {
1284   if (argv) {
1285     size_t i;
1286
1287     for (i = 0; argv[i] != NULL; ++i)
1288       free (argv[i]);
1289     free (argv);
1290   }
1291 }
1292
1293 /* Get the length of a UTF-16 format string.  Handle the string as
1294  * pairs of bytes, looking for the first \0\0 pair.
1295  */
1296 static size_t
1297 utf16_string_len_in_bytes (const char *str)
1298 {
1299   size_t ret = 0;
1300
1301   while (str[0] || str[1]) {
1302     str += 2;
1303     ret += 2;
1304   }
1305
1306   return ret;
1307 }
1308
1309 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1310 char **
1311 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1312 {
1313   hive_type t;
1314   size_t len;
1315   char *data = hivex_value_value (h, value, &t, &len);
1316
1317   if (data == NULL)
1318     return NULL;
1319
1320   if (t != hive_t_multiple_strings) {
1321     free (data);
1322     errno = EINVAL;
1323     return NULL;
1324   }
1325
1326   size_t nr_strings = 0;
1327   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1328   if (ret == NULL) {
1329     free (data);
1330     return NULL;
1331   }
1332   ret[0] = NULL;
1333
1334   char *p = data;
1335   size_t plen;
1336
1337   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1338     nr_strings++;
1339     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1340     if (ret2 == NULL) {
1341       free_strings (ret);
1342       free (data);
1343       return NULL;
1344     }
1345     ret = ret2;
1346
1347     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1348     ret[nr_strings] = NULL;
1349     if (ret[nr_strings-1] == NULL) {
1350       free_strings (ret);
1351       free (data);
1352       return NULL;
1353     }
1354
1355     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1356   }
1357
1358   free (data);
1359   return ret;
1360 }
1361
1362 int32_t
1363 hivex_value_dword (hive_h *h, hive_value_h value)
1364 {
1365   hive_type t;
1366   size_t len;
1367   char *data = hivex_value_value (h, value, &t, &len);
1368
1369   if (data == NULL)
1370     return -1;
1371
1372   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1373     free (data);
1374     errno = EINVAL;
1375     return -1;
1376   }
1377
1378   int32_t ret = *(int32_t*)data;
1379   free (data);
1380   if (t == hive_t_dword)        /* little endian */
1381     ret = le32toh (ret);
1382   else
1383     ret = be32toh (ret);
1384
1385   return ret;
1386 }
1387
1388 int64_t
1389 hivex_value_qword (hive_h *h, hive_value_h value)
1390 {
1391   hive_type t;
1392   size_t len;
1393   char *data = hivex_value_value (h, value, &t, &len);
1394
1395   if (data == NULL)
1396     return -1;
1397
1398   if (t != hive_t_qword || len != 8) {
1399     free (data);
1400     errno = EINVAL;
1401     return -1;
1402   }
1403
1404   int64_t ret = *(int64_t*)data;
1405   free (data);
1406   ret = le64toh (ret);          /* always little endian */
1407
1408   return ret;
1409 }
1410
1411 /*----------------------------------------------------------------------
1412  * Visiting.
1413  */
1414
1415 int
1416 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1417              void *opaque, int flags)
1418 {
1419   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1420 }
1421
1422 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1423
1424 int
1425 hivex_visit_node (hive_h *h, hive_node_h node,
1426                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1427                   int flags)
1428 {
1429   struct hivex_visitor vtor;
1430   memset (&vtor, 0, sizeof vtor);
1431
1432   /* Note that len might be larger *or smaller* than the expected size. */
1433   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1434   memcpy (&vtor, visitor, copysize);
1435
1436   /* This bitmap records unvisited nodes, so we don't loop if the
1437    * registry contains cycles.
1438    */
1439   char *unvisited = malloc (1 + h->size / 32);
1440   if (unvisited == NULL)
1441     return -1;
1442   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1443
1444   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1445   free (unvisited);
1446   return r;
1447 }
1448
1449 static int
1450 hivex__visit_node (hive_h *h, hive_node_h node,
1451                    const struct hivex_visitor *vtor, char *unvisited,
1452                    void *opaque, int flags)
1453 {
1454   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1455   char *name = NULL;
1456   hive_value_h *values = NULL;
1457   hive_node_h *children = NULL;
1458   char *key = NULL;
1459   char *str = NULL;
1460   char **strs = NULL;
1461   int i;
1462
1463   /* Return -1 on all callback errors.  However on internal errors,
1464    * check if skip_bad is set and suppress those errors if so.
1465    */
1466   int ret = -1;
1467
1468   if (!BITMAP_TST (unvisited, node)) {
1469     if (h->msglvl >= 2)
1470       fprintf (stderr, "hivex__visit_node: contains cycle: visited node 0x%zx already\n",
1471                node);
1472
1473     errno = ELOOP;
1474     return skip_bad ? 0 : -1;
1475   }
1476   BITMAP_CLR (unvisited, node);
1477
1478   name = hivex_node_name (h, node);
1479   if (!name) return skip_bad ? 0 : -1;
1480   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1481     goto error;
1482
1483   values = hivex_node_values (h, node);
1484   if (!values) {
1485     ret = skip_bad ? 0 : -1;
1486     goto error;
1487   }
1488
1489   for (i = 0; values[i] != 0; ++i) {
1490     hive_type t;
1491     size_t len;
1492
1493     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1494       ret = skip_bad ? 0 : -1;
1495       goto error;
1496     }
1497
1498     key = hivex_value_key (h, values[i]);
1499     if (key == NULL) {
1500       ret = skip_bad ? 0 : -1;
1501       goto error;
1502     }
1503
1504     if (vtor->value_any) {
1505       str = hivex_value_value (h, values[i], &t, &len);
1506       if (str == NULL) {
1507         ret = skip_bad ? 0 : -1;
1508         goto error;
1509       }
1510       if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
1511         goto error;
1512       free (str); str = NULL;
1513     }
1514     else {
1515       switch (t) {
1516       case hive_t_none:
1517         str = hivex_value_value (h, values[i], &t, &len);
1518         if (str == NULL) {
1519           ret = skip_bad ? 0 : -1;
1520           goto error;
1521         }
1522         if (t != hive_t_none) {
1523           ret = skip_bad ? 0 : -1;
1524           goto error;
1525         }
1526         if (vtor->value_none &&
1527             vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1528           goto error;
1529         free (str); str = NULL;
1530         break;
1531
1532       case hive_t_string:
1533       case hive_t_expand_string:
1534       case hive_t_link:
1535         str = hivex_value_string (h, values[i]);
1536         if (str == NULL) {
1537           if (errno != EILSEQ && errno != EINVAL) {
1538             ret = skip_bad ? 0 : -1;
1539             goto error;
1540           }
1541           if (vtor->value_string_invalid_utf16) {
1542             str = hivex_value_value (h, values[i], &t, &len);
1543             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1544               goto error;
1545             free (str); str = NULL;
1546           }
1547           break;
1548         }
1549         if (vtor->value_string &&
1550             vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1551           goto error;
1552         free (str); str = NULL;
1553         break;
1554
1555       case hive_t_dword:
1556       case hive_t_dword_be: {
1557         int32_t i32 = hivex_value_dword (h, values[i]);
1558         if (vtor->value_dword &&
1559             vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1560           goto error;
1561         break;
1562       }
1563
1564       case hive_t_qword: {
1565         int64_t i64 = hivex_value_qword (h, values[i]);
1566         if (vtor->value_qword &&
1567             vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1568           goto error;
1569         break;
1570       }
1571
1572       case hive_t_binary:
1573         str = hivex_value_value (h, values[i], &t, &len);
1574         if (str == NULL) {
1575           ret = skip_bad ? 0 : -1;
1576           goto error;
1577         }
1578         if (t != hive_t_binary) {
1579           ret = skip_bad ? 0 : -1;
1580           goto error;
1581         }
1582         if (vtor->value_binary &&
1583             vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1584           goto error;
1585         free (str); str = NULL;
1586         break;
1587
1588       case hive_t_multiple_strings:
1589         strs = hivex_value_multiple_strings (h, values[i]);
1590         if (strs == NULL) {
1591           if (errno != EILSEQ && errno != EINVAL) {
1592             ret = skip_bad ? 0 : -1;
1593             goto error;
1594           }
1595           if (vtor->value_string_invalid_utf16) {
1596             str = hivex_value_value (h, values[i], &t, &len);
1597             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1598               goto error;
1599             free (str); str = NULL;
1600           }
1601           break;
1602         }
1603         if (vtor->value_multiple_strings &&
1604             vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1605           goto error;
1606         free_strings (strs); strs = NULL;
1607         break;
1608
1609       case hive_t_resource_list:
1610       case hive_t_full_resource_description:
1611       case hive_t_resource_requirements_list:
1612       default:
1613         str = hivex_value_value (h, values[i], &t, &len);
1614         if (str == NULL) {
1615           ret = skip_bad ? 0 : -1;
1616           goto error;
1617         }
1618         if (vtor->value_other &&
1619             vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1620           goto error;
1621         free (str); str = NULL;
1622         break;
1623       }
1624     }
1625
1626     free (key); key = NULL;
1627   }
1628
1629   children = hivex_node_children (h, node);
1630   if (children == NULL) {
1631     ret = skip_bad ? 0 : -1;
1632     goto error;
1633   }
1634
1635   for (i = 0; children[i] != 0; ++i) {
1636     if (h->msglvl >= 2)
1637       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n",
1638                name, i, children[i]);
1639
1640     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1641       goto error;
1642   }
1643
1644   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1645     goto error;
1646
1647   ret = 0;
1648
1649  error:
1650   free (name);
1651   free (values);
1652   free (children);
1653   free (key);
1654   free (str);
1655   free_strings (strs);
1656   return ret;
1657 }
1658
1659 /*----------------------------------------------------------------------
1660  * Writing.
1661  */
1662
1663 /* Allocate an hbin (page), extending the malloc'd space if necessary,
1664  * and updating the hive handle fields (but NOT the hive disk header
1665  * -- the hive disk header is updated when we commit).  This function
1666  * also extends the bitmap if necessary.
1667  *
1668  * 'allocation_hint' is the size of the block allocation we would like
1669  * to make.  Normally registry blocks are very small (avg 50 bytes)
1670  * and are contained in standard-sized pages (4KB), but the registry
1671  * can support blocks which are larger than a standard page, in which
1672  * case it creates a page of 8KB, 12KB etc.
1673  *
1674  * Returns:
1675  * > 0 : offset of first usable byte of new page (after page header)
1676  * 0   : error (errno set)
1677  */
1678 static size_t
1679 allocate_page (hive_h *h, size_t allocation_hint)
1680 {
1681   /* In almost all cases this will be 1. */
1682   size_t nr_4k_pages =
1683     1 + (allocation_hint + sizeof (struct ntreg_hbin_page) - 1) / 4096;
1684   assert (nr_4k_pages >= 1);
1685
1686   /* 'extend' is the number of bytes to extend the file by.  Note that
1687    * hives found in the wild often contain slack between 'endpages'
1688    * and the actual end of the file, so we don't always need to make
1689    * the file larger.
1690    */
1691   ssize_t extend = h->endpages + nr_4k_pages * 4096 - h->size;
1692
1693   if (h->msglvl >= 2) {
1694     fprintf (stderr, "allocate_page: current endpages = 0x%zx, current size = 0x%zx\n",
1695              h->endpages, h->size);
1696     fprintf (stderr, "allocate_page: extending file by %zd bytes (<= 0 if no extension)\n",
1697              extend);
1698   }
1699
1700   if (extend > 0) {
1701     size_t oldsize = h->size;
1702     size_t newsize = h->size + extend;
1703     char *newaddr = realloc (h->addr, newsize);
1704     if (newaddr == NULL)
1705       return 0;
1706
1707     size_t oldbitmapsize = 1 + oldsize / 32;
1708     size_t newbitmapsize = 1 + newsize / 32;
1709     char *newbitmap = realloc (h->bitmap, newbitmapsize);
1710     if (newbitmap == NULL) {
1711       free (newaddr);
1712       return 0;
1713     }
1714
1715     h->addr = newaddr;
1716     h->size = newsize;
1717     h->bitmap = newbitmap;
1718
1719     memset (h->addr + oldsize, 0, newsize - oldsize);
1720     memset (h->bitmap + oldbitmapsize, 0, newbitmapsize - oldbitmapsize);
1721   }
1722
1723   size_t offset = h->endpages;
1724   h->endpages += nr_4k_pages * 4096;
1725
1726   if (h->msglvl >= 2)
1727     fprintf (stderr, "allocate_page: new endpages = 0x%zx, new size = 0x%zx\n",
1728              h->endpages, h->size);
1729
1730   /* Write the hbin header. */
1731   struct ntreg_hbin_page *page =
1732     (struct ntreg_hbin_page *) (h->addr + offset);
1733   page->magic[0] = 'h';
1734   page->magic[1] = 'b';
1735   page->magic[2] = 'i';
1736   page->magic[3] = 'n';
1737   page->offset_first = htole32 (offset - 0x1000);
1738   page->page_size = htole32 (nr_4k_pages * 4096);
1739   memset (page->unknown, 0, sizeof (page->unknown));
1740
1741   if (h->msglvl >= 2)
1742     fprintf (stderr, "allocate_page: new page at 0x%zx\n", offset);
1743
1744   /* Offset of first usable byte after the header. */
1745   return offset + sizeof (struct ntreg_hbin_page);
1746 }
1747
1748 /* Allocate a single block, first allocating an hbin (page) at the end
1749  * of the current file if necessary.  NB. To keep the implementation
1750  * simple and more likely to be correct, we do not reuse existing free
1751  * blocks.
1752  *
1753  * seg_len is the size of the block (this INCLUDES the block header).
1754  * The header of the block is initialized to -seg_len (negative to
1755  * indicate used).  id[2] is the block ID (type), eg. "nk" for nk-
1756  * record.  The block bitmap is updated to show this block as valid.
1757  * The rest of the contents of the block will be zero.
1758  *
1759  * Returns:
1760  * > 0 : offset of new block
1761  * 0   : error (errno set)
1762  */
1763 static size_t
1764 allocate_block (hive_h *h, size_t seg_len, const char id[2])
1765 {
1766   if (!h->writable) {
1767     errno = EROFS;
1768     return 0;
1769   }
1770
1771   if (seg_len < 4) {
1772     /* The caller probably forgot to include the header.  Note that
1773      * value lists have no ID field, so seg_len == 4 would be possible
1774      * for them, albeit unusual.
1775      */
1776     if (h->msglvl >= 2)
1777       fprintf (stderr, "allocate_block: refusing too small allocation (%zu), returning ERANGE\n",
1778                seg_len);
1779     errno = ERANGE;
1780     return 0;
1781   }
1782
1783   /* Refuse really large allocations. */
1784   if (seg_len > 1000000) {
1785     if (h->msglvl >= 2)
1786       fprintf (stderr, "allocate_block: refusing large allocation (%zu), returning ERANGE\n",
1787                seg_len);
1788     errno = ERANGE;
1789     return 0;
1790   }
1791
1792   /* Round up allocation to multiple of 8 bytes.  All blocks must be
1793    * on an 8 byte boundary.
1794    */
1795   seg_len = (seg_len + 7) & ~7;
1796
1797   /* Allocate a new page if necessary. */
1798   if (h->endblocks == 0 || h->endblocks + seg_len > h->endpages) {
1799     size_t newendblocks = allocate_page (h, seg_len);
1800     if (newendblocks == 0)
1801       return 0;
1802     h->endblocks = newendblocks;
1803   }
1804
1805   size_t offset = h->endblocks;
1806
1807   if (h->msglvl >= 2)
1808     fprintf (stderr, "allocate_block: new block at 0x%zx, size %zu\n",
1809              offset, seg_len);
1810
1811   struct ntreg_hbin_block *blockhdr =
1812     (struct ntreg_hbin_block *) (h->addr + offset);
1813
1814   blockhdr->seg_len = htole32 (- (int32_t) seg_len);
1815   if (id[0] && id[1] && seg_len >= 6) {
1816     blockhdr->id[0] = id[0];
1817     blockhdr->id[1] = id[1];
1818   }
1819
1820   h->endblocks += seg_len;
1821
1822   /* If there is space after the last block in the last page, then we
1823    * have to put a dummy free block header here to mark the rest of
1824    * the page as free.
1825    */
1826   ssize_t rem = h->endpages - h->endblocks;
1827   if (rem > 0) {
1828     if (h->msglvl >= 2)
1829       fprintf (stderr, "allocate_block: marking remainder of page free starting at 0x%zx, size %zd\n",
1830                h->endblocks, rem);
1831
1832     assert (rem >= 4);
1833
1834     blockhdr = (struct ntreg_hbin_block *) (h->addr + h->endblocks);
1835     blockhdr->seg_len = htole32 ((int32_t) rem);
1836   }
1837
1838   return offset;
1839 }
1840
1841 /* 'offset' must point to a valid, used block.  This function marks
1842  * the block unused (by updating the seg_len field) and invalidates
1843  * the bitmap.  It does NOT do this recursively, so to avoid creating
1844  * unreachable used blocks, callers may have to recurse over the hive
1845  * structures.  Also callers must ensure there are no references to
1846  * this block from other parts of the hive.
1847  */
1848 static void
1849 mark_block_unused (hive_h *h, size_t offset)
1850 {
1851   assert (h->writable);
1852   assert (IS_VALID_BLOCK (h, offset));
1853
1854   struct ntreg_hbin_block *blockhdr =
1855     (struct ntreg_hbin_block *) (h->addr + offset);
1856
1857   size_t seg_len = block_len (h, offset, NULL);
1858   blockhdr->seg_len = htole32 (seg_len);
1859
1860   BITMAP_CLR (h->bitmap, offset);
1861 }
1862
1863 /* Delete all existing values at this node. */
1864 static int
1865 delete_values (hive_h *h, hive_node_h node)
1866 {
1867   assert (h->writable);
1868
1869   hive_value_h *values;
1870   size_t *blocks;
1871   if (get_values (h, node, &values, &blocks) == -1)
1872     return -1;
1873
1874   size_t i;
1875   for (i = 0; blocks[i] != 0; ++i)
1876     mark_block_unused (h, blocks[i]);
1877
1878   free (blocks);
1879
1880   for (i = 0; values[i] != 0; ++i) {
1881     struct ntreg_vk_record *vk =
1882       (struct ntreg_vk_record *) (h->addr + values[i]);
1883
1884     size_t len;
1885     len = le32toh (vk->data_len);
1886     if (len == 0x80000000)      /* special case */
1887       len = 4;
1888     len &= 0x7fffffff;
1889
1890     if (len > 4) {              /* non-inline, so remove data block */
1891       size_t data_offset = le32toh (vk->data_offset);
1892       data_offset += 0x1000;
1893       mark_block_unused (h, data_offset);
1894     }
1895
1896     /* remove vk record */
1897     mark_block_unused (h, values[i]);
1898   }
1899
1900   free (values);
1901
1902   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1903   nk->nr_values = htole32 (0);
1904   nk->vallist = htole32 (0xffffffff);
1905
1906   return 0;
1907 }
1908
1909 int
1910 hivex_commit (hive_h *h, const char *filename, int flags)
1911 {
1912   if (flags != 0) {
1913     errno = EINVAL;
1914     return -1;
1915   }
1916
1917   if (!h->writable) {
1918     errno = EROFS;
1919     return -1;
1920   }
1921
1922   filename = filename ? : h->filename;
1923   int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
1924   if (fd == -1)
1925     return -1;
1926
1927   /* Update the header fields. */
1928   uint32_t sequence = le32toh (h->hdr->sequence1);
1929   sequence++;
1930   h->hdr->sequence1 = htole32 (sequence);
1931   h->hdr->sequence2 = htole32 (sequence);
1932   /* XXX Ought to update h->hdr->last_modified. */
1933   h->hdr->blocks = htole32 (h->endpages - 0x1000);
1934
1935   /* Recompute header checksum. */
1936   uint32_t sum = header_checksum (h);
1937   h->hdr->csum = htole32 (sum);
1938
1939   if (h->msglvl >= 2)
1940     fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum);
1941
1942   if (full_write (fd, h->addr, h->size) != h->size) {
1943     int err = errno;
1944     close (fd);
1945     errno = err;
1946     return -1;
1947   }
1948
1949   if (close (fd) == -1)
1950     return -1;
1951
1952   return 0;
1953 }
1954
1955 int
1956 hivex_node_set_values (hive_h *h, hive_node_h node,
1957                        size_t nr_values, const hive_set_value *values,
1958                        int flags)
1959 {
1960   if (!h->writable) {
1961     errno = EROFS;
1962     return -1;
1963   }
1964
1965   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
1966     errno = EINVAL;
1967     return -1;
1968   }
1969
1970   /* Delete all existing values. */
1971   if (delete_values (h, node) == -1)
1972     return -1;
1973
1974   if (nr_values == 0)
1975     return 0;
1976
1977   /* Allocate value list node.  Value lists have no id field. */
1978   static const char nul_id[2] = { 0, 0 };
1979   size_t seg_len =
1980     sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t);
1981   size_t vallist_offs = allocate_block (h, seg_len, nul_id);
1982   if (vallist_offs == 0)
1983     return -1;
1984
1985   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1986   nk->nr_values = htole32 (nr_values);
1987   nk->vallist = htole32 (vallist_offs - 0x1000);
1988
1989   struct ntreg_value_list *vallist =
1990     (struct ntreg_value_list *) (h->addr + vallist_offs);
1991
1992   size_t i;
1993   for (i = 0; i < nr_values; ++i) {
1994     /* Allocate vk record to store this (key, value) pair. */
1995     static const char vk_id[2] = { 'v', 'k' };
1996     seg_len = sizeof (struct ntreg_vk_record) + strlen (values[i].key);
1997     size_t vk_offs = allocate_block (h, seg_len, vk_id);
1998     if (vk_offs == 0)
1999       return -1;
2000
2001     vallist->offset[i] = htole32 (vk_offs - 0x1000);
2002
2003     struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + vk_offs);
2004     size_t name_len = strlen (values[i].key);
2005     vk->name_len = htole16 (name_len);
2006     strcpy (vk->name, values[i].key);
2007     vk->data_type = htole32 (values[i].t);
2008     vk->data_len = htole16 (values[i].len);
2009     vk->flags = name_len == 0 ? 0 : 1;
2010
2011     if (values[i].len <= 4)     /* Store data inline. */
2012       memcpy (&vk->data_offset, values[i].value, values[i].len);
2013     else {
2014       size_t offs = allocate_block (h, values[i].len + 4, nul_id);
2015       if (offs == 0)
2016         return -1;
2017       memcpy (h->addr + offs + 4, values[i].value, values[i].len);
2018       vk->data_offset = htole32 (offs - 0x1000);
2019     }
2020
2021     if (name_len * 2 > le32toh (nk->max_vk_name_len))
2022       nk->max_vk_name_len = htole32 (name_len * 2);
2023     if (values[i].len > le32toh (nk->max_vk_data_len))
2024       nk->max_vk_data_len = htole32 (values[i].len);
2025   }
2026
2027   return 0;
2028 }