Call iconv_close along error path out of function.
[hivex.git] / lib / 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 "c-ctype.h"
38 #include "full-read.h"
39 #include "full-write.h"
40
41 #ifndef O_CLOEXEC
42 #define O_CLOEXEC 0
43 #endif
44
45 #define STREQ(a,b) (strcmp((a),(b)) == 0)
46 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
47 //#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
48 //#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
49 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
50 //#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
51 //#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
52 //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
53 #define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
54
55 #include "hivex.h"
56 #include "byte_conversions.h"
57
58 /* These limits are in place to stop really stupid stuff and/or exploits. */
59 #define HIVEX_MAX_SUBKEYS       15000
60 #define HIVEX_MAX_VALUES        10000
61 #define HIVEX_MAX_VALUE_LEN   1000000
62 #define HIVEX_MAX_ALLOCATION  1000000
63
64 static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len);
65
66 struct hive_h {
67   char *filename;
68   int fd;
69   size_t size;
70   int msglvl;
71   int writable;
72
73   /* Registry file, memory mapped if read-only, or malloc'd if writing. */
74   union {
75     char *addr;
76     struct ntreg_header *hdr;
77   };
78
79   /* Use a bitmap to store which file offsets are valid (point to a
80    * used block).  We only need to store 1 bit per 32 bits of the file
81    * (because blocks are 4-byte aligned).  We found that the average
82    * block size in a registry file is ~50 bytes.  So roughly 1 in 12
83    * bits in the bitmap will be set, making it likely a more efficient
84    * structure than a hash table.
85    */
86   char *bitmap;
87 #define BITMAP_SET(bitmap,off) (bitmap[(off)>>5] |= 1 << (((off)>>2)&7))
88 #define BITMAP_CLR(bitmap,off) (bitmap[(off)>>5] &= ~ (1 << (((off)>>2)&7)))
89 #define BITMAP_TST(bitmap,off) (bitmap[(off)>>5] & (1 << (((off)>>2)&7)))
90 #define IS_VALID_BLOCK(h,off)               \
91   (((off) & 3) == 0 &&                      \
92    (off) >= 0x1000 &&                       \
93    (off) < (h)->size &&                     \
94    BITMAP_TST((h)->bitmap,(off)))
95
96   /* Fields from the header, extracted from little-endianness hell. */
97   size_t rootoffs;              /* Root key offset (always an nk-block). */
98   size_t endpages;              /* Offset of end of pages. */
99
100   /* For writing. */
101   size_t endblocks;             /* Offset to next block allocation (0
102                                    if not allocated anything yet). */
103 };
104
105 /* NB. All fields are little endian. */
106 struct ntreg_header {
107   char magic[4];                /* "regf" */
108   uint32_t sequence1;
109   uint32_t sequence2;
110   char last_modified[8];
111   uint32_t major_ver;           /* 1 */
112   uint32_t minor_ver;           /* 3 */
113   uint32_t unknown5;            /* 0 */
114   uint32_t unknown6;            /* 1 */
115   uint32_t offset;              /* offset of root key record - 4KB */
116   uint32_t blocks;              /* pointer AFTER last hbin in file - 4KB */
117   uint32_t unknown7;            /* 1 */
118   /* 0x30 */
119   char name[64];                /* original file name of hive */
120   char unknown_guid1[16];
121   char unknown_guid2[16];
122   /* 0x90 */
123   uint32_t unknown8;
124   char unknown_guid3[16];
125   uint32_t unknown9;
126   /* 0xa8 */
127   char unknown10[340];
128   /* 0x1fc */
129   uint32_t csum;                /* checksum: xor of dwords 0-0x1fb. */
130   /* 0x200 */
131   char unknown11[3528];
132   /* 0xfc8 */
133   char unknown_guid4[16];
134   char unknown_guid5[16];
135   char unknown_guid6[16];
136   uint32_t unknown12;
137   uint32_t unknown13;
138   /* 0x1000 */
139 } __attribute__((__packed__));
140
141 struct ntreg_hbin_page {
142   char magic[4];                /* "hbin" */
143   uint32_t offset_first;        /* offset from 1st block */
144   uint32_t page_size;           /* size of this page (multiple of 4KB) */
145   char unknown[20];
146   /* Linked list of blocks follows here. */
147 } __attribute__((__packed__));
148
149 struct ntreg_hbin_block {
150   int32_t seg_len;              /* length of this block (-ve for used block) */
151   char id[2];                   /* the block type (eg. "nk" for nk record) */
152   /* Block data follows here. */
153 } __attribute__((__packed__));
154
155 #define BLOCK_ID_EQ(h,offs,eqid) \
156   (STREQLEN (((struct ntreg_hbin_block *)((h)->addr + (offs)))->id, (eqid), 2))
157
158 static size_t
159 block_len (hive_h *h, size_t blkoff, int *used)
160 {
161   struct ntreg_hbin_block *block;
162   block = (struct ntreg_hbin_block *) (h->addr + blkoff);
163
164   int32_t len = le32toh (block->seg_len);
165   if (len < 0) {
166     if (used) *used = 1;
167     len = -len;
168   } else {
169     if (used) *used = 0;
170   }
171
172   return (size_t) len;
173 }
174
175 struct ntreg_nk_record {
176   int32_t seg_len;              /* length (always -ve because used) */
177   char id[2];                   /* "nk" */
178   uint16_t flags;
179   char timestamp[8];
180   uint32_t unknown1;
181   uint32_t parent;              /* offset of owner/parent */
182   uint32_t nr_subkeys;          /* number of subkeys */
183   uint32_t nr_subkeys_volatile;
184   uint32_t subkey_lf;           /* lf record containing list of subkeys */
185   uint32_t subkey_lf_volatile;
186   uint32_t nr_values;           /* number of values */
187   uint32_t vallist;             /* value-list record */
188   uint32_t sk;                  /* offset of sk-record */
189   uint32_t classname;           /* offset of classname record */
190   uint16_t max_subkey_name_len; /* maximum length of a subkey name in bytes
191                                    if the subkey was reencoded as UTF-16LE */
192   uint16_t unknown2;
193   uint32_t unknown3;
194   uint32_t max_vk_name_len;     /* maximum length of any vk name in bytes
195                                    if the name was reencoded as UTF-16LE */
196   uint32_t max_vk_data_len;     /* maximum length of any vk data in bytes */
197   uint32_t unknown6;
198   uint16_t name_len;            /* length of name */
199   uint16_t classname_len;       /* length of classname */
200   char name[1];                 /* name follows here */
201 } __attribute__((__packed__));
202
203 struct ntreg_lf_record {
204   int32_t seg_len;
205   char id[2];                   /* "lf"|"lh" */
206   uint16_t nr_keys;             /* number of keys in this record */
207   struct {
208     uint32_t offset;            /* offset of nk-record for this subkey */
209     char hash[4];               /* hash of subkey name */
210   } keys[1];
211 } __attribute__((__packed__));
212
213 struct ntreg_ri_record {
214   int32_t seg_len;
215   char id[2];                   /* "ri" */
216   uint16_t nr_offsets;          /* number of pointers to lh records */
217   uint32_t offset[1];           /* list of pointers to lh records */
218 } __attribute__((__packed__));
219
220 /* This has no ID header. */
221 struct ntreg_value_list {
222   int32_t seg_len;
223   uint32_t offset[1];           /* list of pointers to vk records */
224 } __attribute__((__packed__));
225
226 struct ntreg_vk_record {
227   int32_t seg_len;              /* length (always -ve because used) */
228   char id[2];                   /* "vk" */
229   uint16_t name_len;            /* length of name */
230   /* length of the data:
231    * If data_len is <= 4, then it's stored inline.
232    * Top bit is set to indicate inline.
233    */
234   uint32_t data_len;
235   uint32_t data_offset;         /* pointer to the data (or data if inline) */
236   uint32_t data_type;           /* type of the data */
237   uint16_t flags;               /* bit 0 set => key name ASCII,
238                                    bit 0 clr => key name UTF-16.
239                                    Only seen ASCII here in the wild.
240                                    NB: this is CLEAR for default key. */
241   uint16_t unknown2;
242   char name[1];                 /* key name follows here */
243 } __attribute__((__packed__));
244
245 struct ntreg_sk_record {
246   int32_t seg_len;              /* length (always -ve because used) */
247   char id[2];                   /* "sk" */
248   uint16_t unknown1;
249   uint32_t sk_next;             /* linked into a circular list */
250   uint32_t sk_prev;
251   uint32_t refcount;            /* reference count */
252   uint32_t sec_len;             /* length of security info */
253   char sec_desc[1];             /* security info follows */
254 } __attribute__((__packed__));
255
256 static uint32_t
257 header_checksum (const hive_h *h)
258 {
259   uint32_t *daddr = (uint32_t *) h->addr;
260   size_t i;
261   uint32_t sum = 0;
262
263   for (i = 0; i < 0x1fc / 4; ++i) {
264     sum ^= le32toh (*daddr);
265     daddr++;
266   }
267
268   return sum;
269 }
270
271 #define HIVEX_OPEN_MSGLVL_MASK (HIVEX_OPEN_VERBOSE|HIVEX_OPEN_DEBUG)
272
273 hive_h *
274 hivex_open (const char *filename, int flags)
275 {
276   hive_h *h = NULL;
277
278   assert (sizeof (struct ntreg_header) == 0x1000);
279   assert (offsetof (struct ntreg_header, csum) == 0x1fc);
280
281   h = calloc (1, sizeof *h);
282   if (h == NULL)
283     goto error;
284
285   h->msglvl = flags & HIVEX_OPEN_MSGLVL_MASK;
286
287   const char *debug = getenv ("HIVEX_DEBUG");
288   if (debug && STREQ (debug, "1"))
289     h->msglvl = 2;
290
291   if (h->msglvl >= 2)
292     fprintf (stderr, "hivex_open: created handle %p\n", h);
293
294   h->writable = !!(flags & HIVEX_OPEN_WRITE);
295   h->filename = strdup (filename);
296   if (h->filename == NULL)
297     goto error;
298
299   h->fd = open (filename, O_RDONLY | O_CLOEXEC);
300   if (h->fd == -1)
301     goto error;
302
303   struct stat statbuf;
304   if (fstat (h->fd, &statbuf) == -1)
305     goto error;
306
307   h->size = statbuf.st_size;
308
309   if (!h->writable) {
310     h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0);
311     if (h->addr == MAP_FAILED)
312       goto error;
313
314     if (h->msglvl >= 2)
315       fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
316   } else {
317     h->addr = malloc (h->size);
318     if (h->addr == NULL)
319       goto error;
320
321     if (full_read (h->fd, h->addr, h->size) < h->size)
322       goto error;
323   }
324
325   /* Check header. */
326   if (h->hdr->magic[0] != 'r' ||
327       h->hdr->magic[1] != 'e' ||
328       h->hdr->magic[2] != 'g' ||
329       h->hdr->magic[3] != 'f') {
330     fprintf (stderr, "hivex: %s: not a Windows NT Registry hive file\n",
331              filename);
332     errno = ENOTSUP;
333     goto error;
334   }
335
336   /* Check major version. */
337   uint32_t major_ver = le32toh (h->hdr->major_ver);
338   if (major_ver != 1) {
339     fprintf (stderr,
340              "hivex: %s: hive file major version %" PRIu32 " (expected 1)\n",
341              filename, major_ver);
342     errno = ENOTSUP;
343     goto error;
344   }
345
346   h->bitmap = calloc (1 + h->size / 32, 1);
347   if (h->bitmap == NULL)
348     goto error;
349
350   /* Header checksum. */
351   uint32_t sum = header_checksum (h);
352   if (sum != le32toh (h->hdr->csum)) {
353     fprintf (stderr, "hivex: %s: bad checksum in hive header\n", filename);
354     errno = EINVAL;
355     goto error;
356   }
357
358   if (h->msglvl >= 2) {
359     char *name = windows_utf16_to_utf8 (h->hdr->name, 64);
360
361     fprintf (stderr,
362              "hivex_open: header fields:\n"
363              "  file version             %" PRIu32 ".%" PRIu32 "\n"
364              "  sequence nos             %" PRIu32 " %" PRIu32 "\n"
365              "    (sequences nos should match if hive was synched at shutdown)\n"
366              "  original file name       %s\n"
367              "    (only 32 chars are stored, name is probably truncated)\n"
368              "  root offset              0x%x + 0x1000\n"
369              "  end of last page         0x%x + 0x1000 (total file size 0x%zx)\n"
370              "  checksum                 0x%x (calculated 0x%x)\n",
371              major_ver, le32toh (h->hdr->minor_ver),
372              le32toh (h->hdr->sequence1), le32toh (h->hdr->sequence2),
373              name ? name : "(conversion failed)",
374              le32toh (h->hdr->offset),
375              le32toh (h->hdr->blocks), h->size,
376              le32toh (h->hdr->csum), sum);
377     free (name);
378   }
379
380   h->rootoffs = le32toh (h->hdr->offset) + 0x1000;
381   h->endpages = le32toh (h->hdr->blocks) + 0x1000;
382
383   if (h->msglvl >= 2)
384     fprintf (stderr, "hivex_open: root offset = 0x%zx\n", h->rootoffs);
385
386   /* We'll set this flag when we see a block with the root offset (ie.
387    * the root block).
388    */
389   int seen_root_block = 0, bad_root_block = 0;
390
391   /* Collect some stats. */
392   size_t pages = 0;           /* Number of hbin pages read. */
393   size_t smallest_page = SIZE_MAX, largest_page = 0;
394   size_t blocks = 0;          /* Total number of blocks found. */
395   size_t smallest_block = SIZE_MAX, largest_block = 0, blocks_bytes = 0;
396   size_t used_blocks = 0;     /* Total number of used blocks found. */
397   size_t used_size = 0;       /* Total size (bytes) of used blocks. */
398
399   /* Read the pages and blocks.  The aim here is to be robust against
400    * corrupt or malicious registries.  So we make sure the loops
401    * always make forward progress.  We add the address of each block
402    * we read to a hash table so pointers will only reference the start
403    * of valid blocks.
404    */
405   size_t off;
406   struct ntreg_hbin_page *page;
407   for (off = 0x1000; off < h->size; off += le32toh (page->page_size)) {
408     if (off >= h->endpages)
409       break;
410
411     page = (struct ntreg_hbin_page *) (h->addr + off);
412     if (page->magic[0] != 'h' ||
413         page->magic[1] != 'b' ||
414         page->magic[2] != 'i' ||
415         page->magic[3] != 'n') {
416       fprintf (stderr, "hivex: %s: trailing garbage at end of file (at 0x%zx, after %zu pages)\n",
417                filename, off, pages);
418       errno = ENOTSUP;
419       goto error;
420     }
421
422     size_t page_size = le32toh (page->page_size);
423     if (h->msglvl >= 2)
424       fprintf (stderr, "hivex_open: page at 0x%zx, size %zu\n", off, page_size);
425     pages++;
426     if (page_size < smallest_page) smallest_page = page_size;
427     if (page_size > largest_page) largest_page = page_size;
428
429     if (page_size <= sizeof (struct ntreg_hbin_page) ||
430         (page_size & 0x0fff) != 0) {
431       fprintf (stderr, "hivex: %s: page size %zu at 0x%zx, bad registry\n",
432                filename, page_size, off);
433       errno = ENOTSUP;
434       goto error;
435     }
436
437     /* Read the blocks in this page. */
438     size_t blkoff;
439     struct ntreg_hbin_block *block;
440     size_t seg_len;
441     for (blkoff = off + 0x20;
442          blkoff < off + page_size;
443          blkoff += seg_len) {
444       blocks++;
445
446       int is_root = blkoff == h->rootoffs;
447       if (is_root)
448         seen_root_block = 1;
449
450       block = (struct ntreg_hbin_block *) (h->addr + blkoff);
451       int used;
452       seg_len = block_len (h, blkoff, &used);
453       if (seg_len <= 4 || (seg_len & 3) != 0) {
454         fprintf (stderr, "hivex: %s: block size %" PRIu32 " at 0x%zx, bad registry\n",
455                  filename, le32toh (block->seg_len), blkoff);
456         errno = ENOTSUP;
457         goto error;
458       }
459
460       if (h->msglvl >= 2)
461         fprintf (stderr, "hivex_open: %s block id %d,%d at 0x%zx size %zu%s\n",
462                  used ? "used" : "free", block->id[0], block->id[1], blkoff,
463                  seg_len, is_root ? " (root)" : "");
464
465       blocks_bytes += seg_len;
466       if (seg_len < smallest_block) smallest_block = seg_len;
467       if (seg_len > largest_block) largest_block = seg_len;
468
469       if (is_root && !used)
470         bad_root_block = 1;
471
472       if (used) {
473         used_blocks++;
474         used_size += seg_len;
475
476         /* Root block must be an nk-block. */
477         if (is_root && (block->id[0] != 'n' || block->id[1] != 'k'))
478           bad_root_block = 1;
479
480         /* Note this blkoff is a valid address. */
481         BITMAP_SET (h->bitmap, blkoff);
482       }
483     }
484   }
485
486   if (!seen_root_block) {
487     fprintf (stderr, "hivex: %s: no root block found\n", filename);
488     errno = ENOTSUP;
489     goto error;
490   }
491
492   if (bad_root_block) {
493     fprintf (stderr, "hivex: %s: bad root block (free or not nk)\n", filename);
494     errno = ENOTSUP;
495     goto error;
496   }
497
498   if (h->msglvl >= 1)
499     fprintf (stderr,
500              "hivex_open: successfully read Windows Registry hive file:\n"
501              "  pages:          %zu [sml: %zu, lge: %zu]\n"
502              "  blocks:         %zu [sml: %zu, avg: %zu, lge: %zu]\n"
503              "  blocks used:    %zu\n"
504              "  bytes used:     %zu\n",
505              pages, smallest_page, largest_page,
506              blocks, smallest_block, blocks_bytes / blocks, largest_block,
507              used_blocks, used_size);
508
509   return h;
510
511  error:;
512   int err = errno;
513   if (h) {
514     free (h->bitmap);
515     if (h->addr && h->size && h->addr != MAP_FAILED) {
516       if (!h->writable)
517         munmap (h->addr, h->size);
518       else
519         free (h->addr);
520     }
521     if (h->fd >= 0)
522       close (h->fd);
523     free (h->filename);
524     free (h);
525   }
526   errno = err;
527   return NULL;
528 }
529
530 int
531 hivex_close (hive_h *h)
532 {
533   int r;
534
535   free (h->bitmap);
536   if (!h->writable)
537     munmap (h->addr, h->size);
538   else
539     free (h->addr);
540   r = close (h->fd);
541   free (h->filename);
542   free (h);
543
544   return r;
545 }
546
547 /*----------------------------------------------------------------------
548  * Reading.
549  */
550
551 hive_node_h
552 hivex_root (hive_h *h)
553 {
554   hive_node_h ret = h->rootoffs;
555   if (!IS_VALID_BLOCK (h, ret)) {
556     errno = ENOKEY;
557     return 0;
558   }
559   return ret;
560 }
561
562 char *
563 hivex_node_name (hive_h *h, hive_node_h node)
564 {
565   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
566     errno = EINVAL;
567     return NULL;
568   }
569
570   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
571
572   /* AFAIK the node name is always plain ASCII, so no conversion
573    * to UTF-8 is necessary.  However we do need to nul-terminate
574    * the string.
575    */
576
577   /* nk->name_len is unsigned, 16 bit, so this is safe ...  However
578    * we have to make sure the length doesn't exceed the block length.
579    */
580   size_t len = le16toh (nk->name_len);
581   size_t seg_len = block_len (h, node, NULL);
582   if (sizeof (struct ntreg_nk_record) + len - 1 > seg_len) {
583     if (h->msglvl >= 2)
584       fprintf (stderr, "hivex_node_name: returning EFAULT because node name is too long (%zu, %zu)\n",
585               len, seg_len);
586     errno = EFAULT;
587     return NULL;
588   }
589
590   char *ret = malloc (len + 1);
591   if (ret == NULL)
592     return NULL;
593   memcpy (ret, nk->name, len);
594   ret[len] = '\0';
595   return ret;
596 }
597
598 #if 0
599 /* I think the documentation for the sk and classname fields in the nk
600  * record is wrong, or else the offset field is in the wrong place.
601  * Otherwise this makes no sense.  Disabled this for now -- it's not
602  * useful for reading the registry anyway.
603  */
604
605 hive_security_h
606 hivex_node_security (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->sk);
616   ret += 0x1000;
617   if (!IS_VALID_BLOCK (h, ret)) {
618     errno = EFAULT;
619     return 0;
620   }
621   return ret;
622 }
623
624 hive_classname_h
625 hivex_node_classname (hive_h *h, hive_node_h node)
626 {
627   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
628     errno = EINVAL;
629     return 0;
630   }
631
632   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
633
634   hive_node_h ret = le32toh (nk->classname);
635   ret += 0x1000;
636   if (!IS_VALID_BLOCK (h, ret)) {
637     errno = EFAULT;
638     return 0;
639   }
640   return ret;
641 }
642 #endif
643
644 /* Structure for returning 0-terminated lists of offsets (nodes,
645  * values, etc).
646  */
647 struct offset_list {
648   size_t *offsets;
649   size_t len;
650   size_t alloc;
651 };
652
653 static void
654 init_offset_list (struct offset_list *list)
655 {
656   list->len = 0;
657   list->alloc = 0;
658   list->offsets = NULL;
659 }
660
661 #define INIT_OFFSET_LIST(name) \
662   struct offset_list name; \
663   init_offset_list (&name)
664
665 /* Preallocates the offset_list, but doesn't make the contents longer. */
666 static int
667 grow_offset_list (struct offset_list *list, size_t alloc)
668 {
669   assert (alloc >= list->len);
670   size_t *p = realloc (list->offsets, alloc * sizeof (size_t));
671   if (p == NULL)
672     return -1;
673   list->offsets = p;
674   list->alloc = alloc;
675   return 0;
676 }
677
678 static int
679 add_to_offset_list (struct offset_list *list, size_t offset)
680 {
681   if (list->len >= list->alloc) {
682     if (grow_offset_list (list, list->alloc ? list->alloc * 2 : 4) == -1)
683       return -1;
684   }
685   list->offsets[list->len] = offset;
686   list->len++;
687   return 0;
688 }
689
690 static void
691 free_offset_list (struct offset_list *list)
692 {
693   free (list->offsets);
694 }
695
696 static size_t *
697 return_offset_list (struct offset_list *list)
698 {
699   if (add_to_offset_list (list, 0) == -1)
700     return NULL;
701   return list->offsets;         /* caller frees */
702 }
703
704 /* Iterate over children, returning child nodes and intermediate blocks. */
705 #define GET_CHILDREN_NO_CHECK_NK 1
706
707 static int
708 get_children (hive_h *h, hive_node_h node,
709               hive_node_h **children_ret, size_t **blocks_ret,
710               int flags)
711 {
712   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
713     errno = EINVAL;
714     return -1;
715   }
716
717   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
718
719   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
720
721   INIT_OFFSET_LIST (children);
722   INIT_OFFSET_LIST (blocks);
723
724   /* Deal with the common "no subkeys" case quickly. */
725   if (nr_subkeys_in_nk == 0)
726     goto ok;
727
728   /* Arbitrarily limit the number of subkeys we will ever deal with. */
729   if (nr_subkeys_in_nk > HIVEX_MAX_SUBKEYS) {
730     if (h->msglvl >= 2)
731       fprintf (stderr, "hivex: get_children: returning ERANGE because nr_subkeys_in_nk > HIVEX_MAX_SUBKEYS (%zu > %d)\n",
732                nr_subkeys_in_nk, HIVEX_MAX_SUBKEYS);
733     errno = ERANGE;
734     goto error;
735   }
736
737   /* Preallocate space for the children. */
738   if (grow_offset_list (&children, nr_subkeys_in_nk) == -1)
739     goto error;
740
741   /* The subkey_lf field can point either to an lf-record, which is
742    * the common case, or if there are lots of subkeys, to an
743    * ri-record.
744    */
745   size_t subkey_lf = le32toh (nk->subkey_lf);
746   subkey_lf += 0x1000;
747   if (!IS_VALID_BLOCK (h, subkey_lf)) {
748     if (h->msglvl >= 2)
749       fprintf (stderr, "hivex_node_children: returning EFAULT because subkey_lf is not a valid block (0x%zx)\n",
750                subkey_lf);
751     errno = EFAULT;
752     goto error;
753   }
754
755   if (add_to_offset_list (&blocks, subkey_lf) == -1)
756     goto error;
757
758   struct ntreg_hbin_block *block =
759     (struct ntreg_hbin_block *) (h->addr + subkey_lf);
760
761   /* Points to lf-record?  (Note, also "lh" but that is basically the
762    * same as "lf" as far as we are concerned here).
763    */
764   if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
765     struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
766
767     /* Check number of subkeys in the nk-record matches number of subkeys
768      * in the lf-record.
769      */
770     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
771
772     if (h->msglvl >= 2)
773       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, nr_subkeys_in_lf = %zu\n",
774                nr_subkeys_in_nk, nr_subkeys_in_lf);
775
776     if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
777       errno = ENOTSUP;
778       goto error;
779     }
780
781     size_t len = block_len (h, subkey_lf, NULL);
782     if (8 + nr_subkeys_in_lf * 8 > len) {
783       if (h->msglvl >= 2)
784         fprintf (stderr, "hivex_node_children: returning EFAULT because too many subkeys (%zu, %zu)\n",
785                  nr_subkeys_in_lf, len);
786       errno = EFAULT;
787       goto error;
788     }
789
790     size_t i;
791     for (i = 0; i < nr_subkeys_in_lf; ++i) {
792       hive_node_h subkey = le32toh (lf->keys[i].offset);
793       subkey += 0x1000;
794       if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
795         if (!IS_VALID_BLOCK (h, subkey)) {
796           if (h->msglvl >= 2)
797             fprintf (stderr, "hivex_node_children: returning EFAULT because subkey is not a valid block (0x%zx)\n",
798                      subkey);
799           errno = EFAULT;
800           goto error;
801         }
802       }
803       if (add_to_offset_list (&children, subkey) == -1)
804         goto error;
805     }
806     goto ok;
807   }
808   /* Points to ri-record? */
809   else if (block->id[0] == 'r' && block->id[1] == 'i') {
810     struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block;
811
812     size_t nr_offsets = le16toh (ri->nr_offsets);
813
814     /* Count total number of children. */
815     size_t i, count = 0;
816     for (i = 0; i < nr_offsets; ++i) {
817       hive_node_h offset = le32toh (ri->offset[i]);
818       offset += 0x1000;
819       if (!IS_VALID_BLOCK (h, offset)) {
820         if (h->msglvl >= 2)
821           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
822                    offset);
823         errno = EFAULT;
824         goto error;
825       }
826       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
827         if (h->msglvl >= 2)
828           fprintf (stderr, "get_children: returning ENOTSUP because ri-record offset does not point to lf/lh (0x%zx)\n",
829                    offset);
830         errno = ENOTSUP;
831         goto error;
832       }
833
834       if (add_to_offset_list (&blocks, offset) == -1)
835         goto error;
836
837       struct ntreg_lf_record *lf =
838         (struct ntreg_lf_record *) (h->addr + offset);
839
840       count += le16toh (lf->nr_keys);
841     }
842
843     if (h->msglvl >= 2)
844       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, counted = %zu\n",
845                nr_subkeys_in_nk, count);
846
847     if (nr_subkeys_in_nk != count) {
848       errno = ENOTSUP;
849       goto error;
850     }
851
852     /* Copy list of children.  Note nr_subkeys_in_nk is limited to
853      * something reasonable above.
854      */
855     for (i = 0; i < nr_offsets; ++i) {
856       hive_node_h offset = le32toh (ri->offset[i]);
857       offset += 0x1000;
858       if (!IS_VALID_BLOCK (h, offset)) {
859         if (h->msglvl >= 2)
860           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (0x%zx)\n",
861                    offset);
862         errno = EFAULT;
863         goto error;
864       }
865       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
866         if (h->msglvl >= 2)
867           fprintf (stderr, "get_children: returning ENOTSUP because ri-record offset does not point to lf/lh (0x%zx)\n",
868                    offset);
869         errno = ENOTSUP;
870         goto error;
871       }
872
873       struct ntreg_lf_record *lf =
874         (struct ntreg_lf_record *) (h->addr + offset);
875
876       size_t j;
877       for (j = 0; j < le16toh (lf->nr_keys); ++j) {
878         hive_node_h subkey = le32toh (lf->keys[j].offset);
879         subkey += 0x1000;
880         if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
881           if (!IS_VALID_BLOCK (h, subkey)) {
882             if (h->msglvl >= 2)
883               fprintf (stderr, "hivex_node_children: returning EFAULT because indirect subkey is not a valid block (0x%zx)\n",
884                        subkey);
885             errno = EFAULT;
886             goto error;
887           }
888         }
889         if (add_to_offset_list (&children, subkey) == -1)
890           goto error;
891       }
892     }
893     goto ok;
894   }
895   /* else not supported, set errno and fall through */
896   if (h->msglvl >= 2)
897     fprintf (stderr, "get_children: returning ENOTSUP because subkey block is not lf/lh/ri (0x%zx, %d, %d)\n",
898              subkey_lf, block->id[0], block->id[1]);
899   errno = ENOTSUP;
900  error:
901   free_offset_list (&children);
902   free_offset_list (&blocks);
903   return -1;
904
905  ok:
906   *children_ret = return_offset_list (&children);
907   *blocks_ret = return_offset_list (&blocks);
908   if (!*children_ret || !*blocks_ret)
909     goto error;
910   return 0;
911 }
912
913 hive_node_h *
914 hivex_node_children (hive_h *h, hive_node_h node)
915 {
916   hive_node_h *children;
917   size_t *blocks;
918
919   if (get_children (h, node, &children, &blocks, 0) == -1)
920     return NULL;
921
922   free (blocks);
923   return children;
924 }
925
926 /* Very inefficient, but at least having a separate API call
927  * allows us to make it more efficient in future.
928  */
929 hive_node_h
930 hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
931 {
932   hive_node_h *children = NULL;
933   char *name = NULL;
934   hive_node_h ret = 0;
935
936   children = hivex_node_children (h, node);
937   if (!children) goto error;
938
939   size_t i;
940   for (i = 0; children[i] != 0; ++i) {
941     name = hivex_node_name (h, children[i]);
942     if (!name) goto error;
943     if (STRCASEEQ (name, nname)) {
944       ret = children[i];
945       break;
946     }
947     free (name); name = NULL;
948   }
949
950  error:
951   free (children);
952   free (name);
953   return ret;
954 }
955
956 hive_node_h
957 hivex_node_parent (hive_h *h, hive_node_h node)
958 {
959   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
960     errno = EINVAL;
961     return 0;
962   }
963
964   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
965
966   hive_node_h ret = le32toh (nk->parent);
967   ret += 0x1000;
968   if (!IS_VALID_BLOCK (h, ret)) {
969     if (h->msglvl >= 2)
970       fprintf (stderr, "hivex_node_parent: returning EFAULT because parent is not a valid block (0x%zx)\n",
971               ret);
972     errno = EFAULT;
973     return 0;
974   }
975   return ret;
976 }
977
978 static int
979 get_values (hive_h *h, hive_node_h node,
980             hive_value_h **values_ret, size_t **blocks_ret)
981 {
982   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
983     errno = EINVAL;
984     return -1;
985   }
986
987   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
988
989   size_t nr_values = le32toh (nk->nr_values);
990
991   if (h->msglvl >= 2)
992     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
993
994   INIT_OFFSET_LIST (values);
995   INIT_OFFSET_LIST (blocks);
996
997   /* Deal with the common "no values" case quickly. */
998   if (nr_values == 0)
999     goto ok;
1000
1001   /* Arbitrarily limit the number of values we will ever deal with. */
1002   if (nr_values > HIVEX_MAX_VALUES) {
1003     if (h->msglvl >= 2)
1004       fprintf (stderr, "hivex: get_values: returning ERANGE because nr_values > HIVEX_MAX_VALUES (%zu > %d)\n",
1005                nr_values, HIVEX_MAX_VALUES);
1006     errno = ERANGE;
1007     goto error;
1008   }
1009
1010   /* Preallocate space for the values. */
1011   if (grow_offset_list (&values, nr_values) == -1)
1012     goto error;
1013
1014   /* Get the value list and check it looks reasonable. */
1015   size_t vlist_offset = le32toh (nk->vallist);
1016   vlist_offset += 0x1000;
1017   if (!IS_VALID_BLOCK (h, vlist_offset)) {
1018     if (h->msglvl >= 2)
1019       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is not a valid block (0x%zx)\n",
1020                vlist_offset);
1021     errno = EFAULT;
1022     goto error;
1023   }
1024
1025   if (add_to_offset_list (&blocks, vlist_offset) == -1)
1026     goto error;
1027
1028   struct ntreg_value_list *vlist =
1029     (struct ntreg_value_list *) (h->addr + vlist_offset);
1030
1031   size_t len = block_len (h, vlist_offset, NULL);
1032   if (4 + nr_values * 4 > len) {
1033     if (h->msglvl >= 2)
1034       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is too long (%zu, %zu)\n",
1035                nr_values, len);
1036     errno = EFAULT;
1037     goto error;
1038   }
1039
1040   size_t i;
1041   for (i = 0; i < nr_values; ++i) {
1042     hive_node_h value = vlist->offset[i];
1043     value += 0x1000;
1044     if (!IS_VALID_BLOCK (h, value)) {
1045       if (h->msglvl >= 2)
1046         fprintf (stderr, "hivex_node_values: returning EFAULT because value is not a valid block (0x%zx)\n",
1047                  value);
1048       errno = EFAULT;
1049       goto error;
1050     }
1051     if (add_to_offset_list (&values, value) == -1)
1052       goto error;
1053   }
1054
1055  ok:
1056   *values_ret = return_offset_list (&values);
1057   *blocks_ret = return_offset_list (&blocks);
1058   if (!*values_ret || !*blocks_ret)
1059     goto error;
1060   return 0;
1061
1062  error:
1063   free_offset_list (&values);
1064   free_offset_list (&blocks);
1065   return -1;
1066 }
1067
1068 hive_value_h *
1069 hivex_node_values (hive_h *h, hive_node_h node)
1070 {
1071   hive_value_h *values;
1072   size_t *blocks;
1073
1074   if (get_values (h, node, &values, &blocks) == -1)
1075     return NULL;
1076
1077   free (blocks);
1078   return values;
1079 }
1080
1081 /* Very inefficient, but at least having a separate API call
1082  * allows us to make it more efficient in future.
1083  */
1084 hive_value_h
1085 hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
1086 {
1087   hive_value_h *values = NULL;
1088   char *name = NULL;
1089   hive_value_h ret = 0;
1090
1091   values = hivex_node_values (h, node);
1092   if (!values) goto error;
1093
1094   size_t i;
1095   for (i = 0; values[i] != 0; ++i) {
1096     name = hivex_value_key (h, values[i]);
1097     if (!name) goto error;
1098     if (STRCASEEQ (name, key)) {
1099       ret = values[i];
1100       break;
1101     }
1102     free (name); name = NULL;
1103   }
1104
1105  error:
1106   free (values);
1107   free (name);
1108   return ret;
1109 }
1110
1111 char *
1112 hivex_value_key (hive_h *h, hive_value_h value)
1113 {
1114   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1115     errno = EINVAL;
1116     return 0;
1117   }
1118
1119   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1120
1121   /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
1122    * necessary.  However we do need to nul-terminate the string.
1123    */
1124
1125   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
1126    * we have to make sure the length doesn't exceed the block length.
1127    */
1128   size_t len = le16toh (vk->name_len);
1129   size_t seg_len = block_len (h, value, NULL);
1130   if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
1131     if (h->msglvl >= 2)
1132       fprintf (stderr, "hivex_value_key: returning EFAULT because key length is too long (%zu, %zu)\n",
1133                len, seg_len);
1134     errno = EFAULT;
1135     return NULL;
1136   }
1137
1138   char *ret = malloc (len + 1);
1139   if (ret == NULL)
1140     return NULL;
1141   memcpy (ret, vk->name, len);
1142   ret[len] = '\0';
1143   return ret;
1144 }
1145
1146 int
1147 hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
1148 {
1149   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1150     errno = EINVAL;
1151     return -1;
1152   }
1153
1154   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1155
1156   if (t)
1157     *t = le32toh (vk->data_type);
1158
1159   if (len) {
1160     *len = le32toh (vk->data_len);
1161     *len &= 0x7fffffff;         /* top bit indicates if data is stored inline */
1162   }
1163
1164   return 0;
1165 }
1166
1167 char *
1168 hivex_value_value (hive_h *h, hive_value_h value,
1169                    hive_type *t_rtn, size_t *len_rtn)
1170 {
1171   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
1172     errno = EINVAL;
1173     return NULL;
1174   }
1175
1176   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
1177
1178   hive_type t;
1179   size_t len;
1180   int is_inline;
1181
1182   t = le32toh (vk->data_type);
1183
1184   len = le32toh (vk->data_len);
1185   is_inline = !!(len & 0x80000000);
1186   len &= 0x7fffffff;
1187
1188   if (h->msglvl >= 2)
1189     fprintf (stderr, "hivex_value_value: value=0x%zx, t=%d, len=%zu, inline=%d\n",
1190              value, t, len, is_inline);
1191
1192   if (t_rtn)
1193     *t_rtn = t;
1194   if (len_rtn)
1195     *len_rtn = len;
1196
1197   if (is_inline && len > 4) {
1198     errno = ENOTSUP;
1199     return NULL;
1200   }
1201
1202   /* Arbitrarily limit the length that we will read. */
1203   if (len > HIVEX_MAX_VALUE_LEN) {
1204     if (h->msglvl >= 2)
1205       fprintf (stderr, "hivex_value_value: returning ERANGE because data length > HIVEX_MAX_VALUE_LEN (%zu > %d)\n",
1206                len, HIVEX_MAX_SUBKEYS);
1207     errno = ERANGE;
1208     return NULL;
1209   }
1210
1211   char *ret = malloc (len);
1212   if (ret == NULL)
1213     return NULL;
1214
1215   if (is_inline) {
1216     memcpy (ret, (char *) &vk->data_offset, len);
1217     return ret;
1218   }
1219
1220   size_t data_offset = le32toh (vk->data_offset);
1221   data_offset += 0x1000;
1222   if (!IS_VALID_BLOCK (h, data_offset)) {
1223     if (h->msglvl >= 2)
1224       fprintf (stderr, "hivex_value_value: returning EFAULT because data offset is not a valid block (0x%zx)\n",
1225                data_offset);
1226     errno = EFAULT;
1227     free (ret);
1228     return NULL;
1229   }
1230
1231   /* Check that the declared size isn't larger than the block its in.
1232    *
1233    * XXX Some apparently valid registries are seen to have this,
1234    * so turn this into a warning and substitute the smaller length
1235    * instead.
1236    */
1237   size_t blen = block_len (h, data_offset, NULL);
1238   if (len > blen - 4 /* subtract 4 for block header */) {
1239     if (h->msglvl >= 2)
1240       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",
1241                data_offset, len, blen);
1242     len = blen - 4;
1243   }
1244
1245   char *data = h->addr + data_offset + 4;
1246   memcpy (ret, data, len);
1247   return ret;
1248 }
1249
1250 static char *
1251 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1252 {
1253   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1254   if (ic == (iconv_t) -1)
1255     return NULL;
1256
1257   /* iconv(3) has an insane interface ... */
1258
1259   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1260   size_t outalloc = len;
1261
1262  again:;
1263   size_t inlen = len;
1264   size_t outlen = outalloc;
1265   char *out = malloc (outlen + 1);
1266   if (out == NULL) {
1267     int err = errno;
1268     iconv_close (ic);
1269     errno = err;
1270     return NULL;
1271   }
1272   char *inp = input;
1273   char *outp = out;
1274
1275   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1276   if (r == (size_t) -1) {
1277     if (errno == E2BIG) {
1278       int err = errno;
1279       size_t prev = outalloc;
1280       /* Try again with a larger output buffer. */
1281       free (out);
1282       outalloc *= 2;
1283       if (outalloc < prev) {
1284         iconv_close (ic);
1285         errno = err;
1286         return NULL;
1287       }
1288       goto again;
1289     }
1290     else {
1291       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1292       int err = errno;
1293       iconv_close (ic);
1294       free (out);
1295       errno = err;
1296       return NULL;
1297     }
1298   }
1299
1300   *outp = '\0';
1301   iconv_close (ic);
1302
1303   return out;
1304 }
1305
1306 char *
1307 hivex_value_string (hive_h *h, hive_value_h value)
1308 {
1309   hive_type t;
1310   size_t len;
1311   char *data = hivex_value_value (h, value, &t, &len);
1312
1313   if (data == NULL)
1314     return NULL;
1315
1316   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1317     free (data);
1318     errno = EINVAL;
1319     return NULL;
1320   }
1321
1322   char *ret = windows_utf16_to_utf8 (data, len);
1323   free (data);
1324   if (ret == NULL)
1325     return NULL;
1326
1327   return ret;
1328 }
1329
1330 static void
1331 free_strings (char **argv)
1332 {
1333   if (argv) {
1334     size_t i;
1335
1336     for (i = 0; argv[i] != NULL; ++i)
1337       free (argv[i]);
1338     free (argv);
1339   }
1340 }
1341
1342 /* Get the length of a UTF-16 format string.  Handle the string as
1343  * pairs of bytes, looking for the first \0\0 pair.
1344  */
1345 static size_t
1346 utf16_string_len_in_bytes (const char *str)
1347 {
1348   size_t ret = 0;
1349
1350   while (str[0] || str[1]) {
1351     str += 2;
1352     ret += 2;
1353   }
1354
1355   return ret;
1356 }
1357
1358 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1359 char **
1360 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1361 {
1362   hive_type t;
1363   size_t len;
1364   char *data = hivex_value_value (h, value, &t, &len);
1365
1366   if (data == NULL)
1367     return NULL;
1368
1369   if (t != hive_t_multiple_strings) {
1370     free (data);
1371     errno = EINVAL;
1372     return NULL;
1373   }
1374
1375   size_t nr_strings = 0;
1376   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1377   if (ret == NULL) {
1378     free (data);
1379     return NULL;
1380   }
1381   ret[0] = NULL;
1382
1383   char *p = data;
1384   size_t plen;
1385
1386   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1387     nr_strings++;
1388     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1389     if (ret2 == NULL) {
1390       free_strings (ret);
1391       free (data);
1392       return NULL;
1393     }
1394     ret = ret2;
1395
1396     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1397     ret[nr_strings] = NULL;
1398     if (ret[nr_strings-1] == NULL) {
1399       free_strings (ret);
1400       free (data);
1401       return NULL;
1402     }
1403
1404     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1405   }
1406
1407   free (data);
1408   return ret;
1409 }
1410
1411 int32_t
1412 hivex_value_dword (hive_h *h, hive_value_h value)
1413 {
1414   hive_type t;
1415   size_t len;
1416   char *data = hivex_value_value (h, value, &t, &len);
1417
1418   if (data == NULL)
1419     return -1;
1420
1421   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1422     free (data);
1423     errno = EINVAL;
1424     return -1;
1425   }
1426
1427   int32_t ret = *(int32_t*)data;
1428   free (data);
1429   if (t == hive_t_dword)        /* little endian */
1430     ret = le32toh (ret);
1431   else
1432     ret = be32toh (ret);
1433
1434   return ret;
1435 }
1436
1437 int64_t
1438 hivex_value_qword (hive_h *h, hive_value_h value)
1439 {
1440   hive_type t;
1441   size_t len;
1442   char *data = hivex_value_value (h, value, &t, &len);
1443
1444   if (data == NULL)
1445     return -1;
1446
1447   if (t != hive_t_qword || len != 8) {
1448     free (data);
1449     errno = EINVAL;
1450     return -1;
1451   }
1452
1453   int64_t ret = *(int64_t*)data;
1454   free (data);
1455   ret = le64toh (ret);          /* always little endian */
1456
1457   return ret;
1458 }
1459
1460 /*----------------------------------------------------------------------
1461  * Visiting.
1462  */
1463
1464 int
1465 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1466              void *opaque, int flags)
1467 {
1468   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1469 }
1470
1471 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1472
1473 int
1474 hivex_visit_node (hive_h *h, hive_node_h node,
1475                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1476                   int flags)
1477 {
1478   struct hivex_visitor vtor;
1479   memset (&vtor, 0, sizeof vtor);
1480
1481   /* Note that len might be larger *or smaller* than the expected size. */
1482   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1483   memcpy (&vtor, visitor, copysize);
1484
1485   /* This bitmap records unvisited nodes, so we don't loop if the
1486    * registry contains cycles.
1487    */
1488   char *unvisited = malloc (1 + h->size / 32);
1489   if (unvisited == NULL)
1490     return -1;
1491   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1492
1493   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1494   free (unvisited);
1495   return r;
1496 }
1497
1498 static int
1499 hivex__visit_node (hive_h *h, hive_node_h node,
1500                    const struct hivex_visitor *vtor, char *unvisited,
1501                    void *opaque, int flags)
1502 {
1503   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1504   char *name = NULL;
1505   hive_value_h *values = NULL;
1506   hive_node_h *children = NULL;
1507   char *key = NULL;
1508   char *str = NULL;
1509   char **strs = NULL;
1510   int i;
1511
1512   /* Return -1 on all callback errors.  However on internal errors,
1513    * check if skip_bad is set and suppress those errors if so.
1514    */
1515   int ret = -1;
1516
1517   if (!BITMAP_TST (unvisited, node)) {
1518     if (h->msglvl >= 2)
1519       fprintf (stderr, "hivex__visit_node: contains cycle: visited node 0x%zx already\n",
1520                node);
1521
1522     errno = ELOOP;
1523     return skip_bad ? 0 : -1;
1524   }
1525   BITMAP_CLR (unvisited, node);
1526
1527   name = hivex_node_name (h, node);
1528   if (!name) return skip_bad ? 0 : -1;
1529   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1530     goto error;
1531
1532   values = hivex_node_values (h, node);
1533   if (!values) {
1534     ret = skip_bad ? 0 : -1;
1535     goto error;
1536   }
1537
1538   for (i = 0; values[i] != 0; ++i) {
1539     hive_type t;
1540     size_t len;
1541
1542     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1543       ret = skip_bad ? 0 : -1;
1544       goto error;
1545     }
1546
1547     key = hivex_value_key (h, values[i]);
1548     if (key == NULL) {
1549       ret = skip_bad ? 0 : -1;
1550       goto error;
1551     }
1552
1553     if (vtor->value_any) {
1554       str = hivex_value_value (h, values[i], &t, &len);
1555       if (str == NULL) {
1556         ret = skip_bad ? 0 : -1;
1557         goto error;
1558       }
1559       if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
1560         goto error;
1561       free (str); str = NULL;
1562     }
1563     else {
1564       switch (t) {
1565       case hive_t_none:
1566         str = hivex_value_value (h, values[i], &t, &len);
1567         if (str == NULL) {
1568           ret = skip_bad ? 0 : -1;
1569           goto error;
1570         }
1571         if (t != hive_t_none) {
1572           ret = skip_bad ? 0 : -1;
1573           goto error;
1574         }
1575         if (vtor->value_none &&
1576             vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1577           goto error;
1578         free (str); str = NULL;
1579         break;
1580
1581       case hive_t_string:
1582       case hive_t_expand_string:
1583       case hive_t_link:
1584         str = hivex_value_string (h, values[i]);
1585         if (str == NULL) {
1586           if (errno != EILSEQ && errno != EINVAL) {
1587             ret = skip_bad ? 0 : -1;
1588             goto error;
1589           }
1590           if (vtor->value_string_invalid_utf16) {
1591             str = hivex_value_value (h, values[i], &t, &len);
1592             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1593               goto error;
1594             free (str); str = NULL;
1595           }
1596           break;
1597         }
1598         if (vtor->value_string &&
1599             vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1600           goto error;
1601         free (str); str = NULL;
1602         break;
1603
1604       case hive_t_dword:
1605       case hive_t_dword_be: {
1606         int32_t i32 = hivex_value_dword (h, values[i]);
1607         if (vtor->value_dword &&
1608             vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1609           goto error;
1610         break;
1611       }
1612
1613       case hive_t_qword: {
1614         int64_t i64 = hivex_value_qword (h, values[i]);
1615         if (vtor->value_qword &&
1616             vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1617           goto error;
1618         break;
1619       }
1620
1621       case hive_t_binary:
1622         str = hivex_value_value (h, values[i], &t, &len);
1623         if (str == NULL) {
1624           ret = skip_bad ? 0 : -1;
1625           goto error;
1626         }
1627         if (t != hive_t_binary) {
1628           ret = skip_bad ? 0 : -1;
1629           goto error;
1630         }
1631         if (vtor->value_binary &&
1632             vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1633           goto error;
1634         free (str); str = NULL;
1635         break;
1636
1637       case hive_t_multiple_strings:
1638         strs = hivex_value_multiple_strings (h, values[i]);
1639         if (strs == NULL) {
1640           if (errno != EILSEQ && errno != EINVAL) {
1641             ret = skip_bad ? 0 : -1;
1642             goto error;
1643           }
1644           if (vtor->value_string_invalid_utf16) {
1645             str = hivex_value_value (h, values[i], &t, &len);
1646             if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1647               goto error;
1648             free (str); str = NULL;
1649           }
1650           break;
1651         }
1652         if (vtor->value_multiple_strings &&
1653             vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1654           goto error;
1655         free_strings (strs); strs = NULL;
1656         break;
1657
1658       case hive_t_resource_list:
1659       case hive_t_full_resource_description:
1660       case hive_t_resource_requirements_list:
1661       default:
1662         str = hivex_value_value (h, values[i], &t, &len);
1663         if (str == NULL) {
1664           ret = skip_bad ? 0 : -1;
1665           goto error;
1666         }
1667         if (vtor->value_other &&
1668             vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1669           goto error;
1670         free (str); str = NULL;
1671         break;
1672       }
1673     }
1674
1675     free (key); key = NULL;
1676   }
1677
1678   children = hivex_node_children (h, node);
1679   if (children == NULL) {
1680     ret = skip_bad ? 0 : -1;
1681     goto error;
1682   }
1683
1684   for (i = 0; children[i] != 0; ++i) {
1685     if (h->msglvl >= 2)
1686       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n",
1687                name, i, children[i]);
1688
1689     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1690       goto error;
1691   }
1692
1693   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1694     goto error;
1695
1696   ret = 0;
1697
1698  error:
1699   free (name);
1700   free (values);
1701   free (children);
1702   free (key);
1703   free (str);
1704   free_strings (strs);
1705   return ret;
1706 }
1707
1708 /*----------------------------------------------------------------------
1709  * Writing.
1710  */
1711
1712 /* Allocate an hbin (page), extending the malloc'd space if necessary,
1713  * and updating the hive handle fields (but NOT the hive disk header
1714  * -- the hive disk header is updated when we commit).  This function
1715  * also extends the bitmap if necessary.
1716  *
1717  * 'allocation_hint' is the size of the block allocation we would like
1718  * to make.  Normally registry blocks are very small (avg 50 bytes)
1719  * and are contained in standard-sized pages (4KB), but the registry
1720  * can support blocks which are larger than a standard page, in which
1721  * case it creates a page of 8KB, 12KB etc.
1722  *
1723  * Returns:
1724  * > 0 : offset of first usable byte of new page (after page header)
1725  * 0   : error (errno set)
1726  */
1727 static size_t
1728 allocate_page (hive_h *h, size_t allocation_hint)
1729 {
1730   /* In almost all cases this will be 1. */
1731   size_t nr_4k_pages =
1732     1 + (allocation_hint + sizeof (struct ntreg_hbin_page) - 1) / 4096;
1733   assert (nr_4k_pages >= 1);
1734
1735   /* 'extend' is the number of bytes to extend the file by.  Note that
1736    * hives found in the wild often contain slack between 'endpages'
1737    * and the actual end of the file, so we don't always need to make
1738    * the file larger.
1739    */
1740   ssize_t extend = h->endpages + nr_4k_pages * 4096 - h->size;
1741
1742   if (h->msglvl >= 2) {
1743     fprintf (stderr, "allocate_page: current endpages = 0x%zx, current size = 0x%zx\n",
1744              h->endpages, h->size);
1745     fprintf (stderr, "allocate_page: extending file by %zd bytes (<= 0 if no extension)\n",
1746              extend);
1747   }
1748
1749   if (extend > 0) {
1750     size_t oldsize = h->size;
1751     size_t newsize = h->size + extend;
1752     char *newaddr = realloc (h->addr, newsize);
1753     if (newaddr == NULL)
1754       return 0;
1755
1756     size_t oldbitmapsize = 1 + oldsize / 32;
1757     size_t newbitmapsize = 1 + newsize / 32;
1758     char *newbitmap = realloc (h->bitmap, newbitmapsize);
1759     if (newbitmap == NULL) {
1760       free (newaddr);
1761       return 0;
1762     }
1763
1764     h->addr = newaddr;
1765     h->size = newsize;
1766     h->bitmap = newbitmap;
1767
1768     memset (h->addr + oldsize, 0, newsize - oldsize);
1769     memset (h->bitmap + oldbitmapsize, 0, newbitmapsize - oldbitmapsize);
1770   }
1771
1772   size_t offset = h->endpages;
1773   h->endpages += nr_4k_pages * 4096;
1774
1775   if (h->msglvl >= 2)
1776     fprintf (stderr, "allocate_page: new endpages = 0x%zx, new size = 0x%zx\n",
1777              h->endpages, h->size);
1778
1779   /* Write the hbin header. */
1780   struct ntreg_hbin_page *page =
1781     (struct ntreg_hbin_page *) (h->addr + offset);
1782   page->magic[0] = 'h';
1783   page->magic[1] = 'b';
1784   page->magic[2] = 'i';
1785   page->magic[3] = 'n';
1786   page->offset_first = htole32 (offset - 0x1000);
1787   page->page_size = htole32 (nr_4k_pages * 4096);
1788   memset (page->unknown, 0, sizeof (page->unknown));
1789
1790   if (h->msglvl >= 2)
1791     fprintf (stderr, "allocate_page: new page at 0x%zx\n", offset);
1792
1793   /* Offset of first usable byte after the header. */
1794   return offset + sizeof (struct ntreg_hbin_page);
1795 }
1796
1797 /* Allocate a single block, first allocating an hbin (page) at the end
1798  * of the current file if necessary.  NB. To keep the implementation
1799  * simple and more likely to be correct, we do not reuse existing free
1800  * blocks.
1801  *
1802  * seg_len is the size of the block (this INCLUDES the block header).
1803  * The header of the block is initialized to -seg_len (negative to
1804  * indicate used).  id[2] is the block ID (type), eg. "nk" for nk-
1805  * record.  The block bitmap is updated to show this block as valid.
1806  * The rest of the contents of the block will be zero.
1807  *
1808  * **NB** Because allocate_block may reallocate the memory, all
1809  * pointers into the memory become potentially invalid.  I really
1810  * love writing in C, can't you tell?
1811  *
1812  * Returns:
1813  * > 0 : offset of new block
1814  * 0   : error (errno set)
1815  */
1816 static size_t
1817 allocate_block (hive_h *h, size_t seg_len, const char id[2])
1818 {
1819   if (!h->writable) {
1820     errno = EROFS;
1821     return 0;
1822   }
1823
1824   if (seg_len < 4) {
1825     /* The caller probably forgot to include the header.  Note that
1826      * value lists have no ID field, so seg_len == 4 would be possible
1827      * for them, albeit unusual.
1828      */
1829     if (h->msglvl >= 2)
1830       fprintf (stderr, "allocate_block: refusing too small allocation (%zu), returning ERANGE\n",
1831                seg_len);
1832     errno = ERANGE;
1833     return 0;
1834   }
1835
1836   /* Refuse really large allocations. */
1837   if (seg_len > HIVEX_MAX_ALLOCATION) {
1838     if (h->msglvl >= 2)
1839       fprintf (stderr, "allocate_block: refusing large allocation (%zu), returning ERANGE\n",
1840                seg_len);
1841     errno = ERANGE;
1842     return 0;
1843   }
1844
1845   /* Round up allocation to multiple of 8 bytes.  All blocks must be
1846    * on an 8 byte boundary.
1847    */
1848   seg_len = (seg_len + 7) & ~7;
1849
1850   /* Allocate a new page if necessary. */
1851   if (h->endblocks == 0 || h->endblocks + seg_len > h->endpages) {
1852     size_t newendblocks = allocate_page (h, seg_len);
1853     if (newendblocks == 0)
1854       return 0;
1855     h->endblocks = newendblocks;
1856   }
1857
1858   size_t offset = h->endblocks;
1859
1860   if (h->msglvl >= 2)
1861     fprintf (stderr, "allocate_block: new block at 0x%zx, size %zu\n",
1862              offset, seg_len);
1863
1864   struct ntreg_hbin_block *blockhdr =
1865     (struct ntreg_hbin_block *) (h->addr + offset);
1866
1867   memset (blockhdr, 0, seg_len);
1868
1869   blockhdr->seg_len = htole32 (- (int32_t) seg_len);
1870   if (id[0] && id[1] && seg_len >= sizeof (struct ntreg_hbin_block)) {
1871     blockhdr->id[0] = id[0];
1872     blockhdr->id[1] = id[1];
1873   }
1874
1875   BITMAP_SET (h->bitmap, offset);
1876
1877   h->endblocks += seg_len;
1878
1879   /* If there is space after the last block in the last page, then we
1880    * have to put a dummy free block header here to mark the rest of
1881    * the page as free.
1882    */
1883   ssize_t rem = h->endpages - h->endblocks;
1884   if (rem > 0) {
1885     if (h->msglvl >= 2)
1886       fprintf (stderr, "allocate_block: marking remainder of page free starting at 0x%zx, size %zd\n",
1887                h->endblocks, rem);
1888
1889     assert (rem >= 4);
1890
1891     blockhdr = (struct ntreg_hbin_block *) (h->addr + h->endblocks);
1892     blockhdr->seg_len = htole32 ((int32_t) rem);
1893   }
1894
1895   return offset;
1896 }
1897
1898 /* 'offset' must point to a valid, used block.  This function marks
1899  * the block unused (by updating the seg_len field) and invalidates
1900  * the bitmap.  It does NOT do this recursively, so to avoid creating
1901  * unreachable used blocks, callers may have to recurse over the hive
1902  * structures.  Also callers must ensure there are no references to
1903  * this block from other parts of the hive.
1904  */
1905 static void
1906 mark_block_unused (hive_h *h, size_t offset)
1907 {
1908   assert (h->writable);
1909   assert (IS_VALID_BLOCK (h, offset));
1910
1911   if (h->msglvl >= 2)
1912     fprintf (stderr, "mark_block_unused: marking 0x%zx unused\n", offset);
1913
1914   struct ntreg_hbin_block *blockhdr =
1915     (struct ntreg_hbin_block *) (h->addr + offset);
1916
1917   size_t seg_len = block_len (h, offset, NULL);
1918   blockhdr->seg_len = htole32 (seg_len);
1919
1920   BITMAP_CLR (h->bitmap, offset);
1921 }
1922
1923 /* Delete all existing values at this node. */
1924 static int
1925 delete_values (hive_h *h, hive_node_h node)
1926 {
1927   assert (h->writable);
1928
1929   hive_value_h *values;
1930   size_t *blocks;
1931   if (get_values (h, node, &values, &blocks) == -1)
1932     return -1;
1933
1934   size_t i;
1935   for (i = 0; blocks[i] != 0; ++i)
1936     mark_block_unused (h, blocks[i]);
1937
1938   free (blocks);
1939
1940   for (i = 0; values[i] != 0; ++i) {
1941     struct ntreg_vk_record *vk =
1942       (struct ntreg_vk_record *) (h->addr + values[i]);
1943
1944     size_t len;
1945     int is_inline;
1946     len = le32toh (vk->data_len);
1947     is_inline = !!(len & 0x80000000); /* top bit indicates is inline */
1948     len &= 0x7fffffff;
1949
1950     if (!is_inline) {           /* non-inline, so remove data block */
1951       size_t data_offset = le32toh (vk->data_offset);
1952       data_offset += 0x1000;
1953       mark_block_unused (h, data_offset);
1954     }
1955
1956     /* remove vk record */
1957     mark_block_unused (h, values[i]);
1958   }
1959
1960   free (values);
1961
1962   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
1963   nk->nr_values = htole32 (0);
1964   nk->vallist = htole32 (0xffffffff);
1965
1966   return 0;
1967 }
1968
1969 int
1970 hivex_commit (hive_h *h, const char *filename, int flags)
1971 {
1972   if (flags != 0) {
1973     errno = EINVAL;
1974     return -1;
1975   }
1976
1977   if (!h->writable) {
1978     errno = EROFS;
1979     return -1;
1980   }
1981
1982   filename = filename ? : h->filename;
1983   int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
1984   if (fd == -1)
1985     return -1;
1986
1987   /* Update the header fields. */
1988   uint32_t sequence = le32toh (h->hdr->sequence1);
1989   sequence++;
1990   h->hdr->sequence1 = htole32 (sequence);
1991   h->hdr->sequence2 = htole32 (sequence);
1992   /* XXX Ought to update h->hdr->last_modified. */
1993   h->hdr->blocks = htole32 (h->endpages - 0x1000);
1994
1995   /* Recompute header checksum. */
1996   uint32_t sum = header_checksum (h);
1997   h->hdr->csum = htole32 (sum);
1998
1999   if (h->msglvl >= 2)
2000     fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum);
2001
2002   if (full_write (fd, h->addr, h->size) != h->size) {
2003     int err = errno;
2004     close (fd);
2005     errno = err;
2006     return -1;
2007   }
2008
2009   if (close (fd) == -1)
2010     return -1;
2011
2012   return 0;
2013 }
2014
2015 /* Calculate the hash for a lf or lh record offset.
2016  */
2017 static void
2018 calc_hash (const char *type, const char *name, char *ret)
2019 {
2020   size_t len = strlen (name);
2021
2022   if (STRPREFIX (type, "lf"))
2023     /* Old-style, not used in current registries. */
2024     memcpy (ret, name, len < 4 ? len : 4);
2025   else {
2026     /* New-style for lh-records. */
2027     size_t i, c;
2028     uint32_t h = 0;
2029     for (i = 0; i < len; ++i) {
2030       c = c_toupper (name[i]);
2031       h *= 37;
2032       h += c;
2033     }
2034     *((uint32_t *) ret) = htole32 (h);
2035   }
2036 }
2037
2038 /* Create a completely new lh-record containing just the single node. */
2039 static size_t
2040 new_lh_record (hive_h *h, const char *name, hive_node_h node)
2041 {
2042   static const char id[2] = { 'l', 'h' };
2043   size_t seg_len = sizeof (struct ntreg_lf_record);
2044   size_t offset = allocate_block (h, seg_len, id);
2045   if (offset == 0)
2046     return 0;
2047
2048   struct ntreg_lf_record *lh = (struct ntreg_lf_record *) (h->addr + offset);
2049   lh->nr_keys = htole16 (1);
2050   lh->keys[0].offset = htole32 (node - 0x1000);
2051   calc_hash ("lh", name, lh->keys[0].hash);
2052
2053   return offset;
2054 }
2055
2056 /* Insert node into existing lf/lh-record at position.
2057  * This allocates a new record and marks the old one as unused.
2058  */
2059 static size_t
2060 insert_lf_record (hive_h *h, size_t old_offs, size_t posn,
2061                   const char *name, hive_node_h node)
2062 {
2063   assert (IS_VALID_BLOCK (h, old_offs));
2064
2065   /* Work around C stupidity.
2066    * http://www.redhat.com/archives/libguestfs/2010-February/msg00056.html
2067    */
2068   int test = BLOCK_ID_EQ (h, old_offs, "lf") || BLOCK_ID_EQ (h, old_offs, "lh");
2069   assert (test);
2070
2071   struct ntreg_lf_record *old_lf =
2072     (struct ntreg_lf_record *) (h->addr + old_offs);
2073   size_t nr_keys = le16toh (old_lf->nr_keys);
2074
2075   nr_keys++; /* in new record ... */
2076
2077   size_t seg_len = sizeof (struct ntreg_lf_record) + (nr_keys-1) * 8;
2078
2079   /* Copy the old_lf->id in case it moves during allocate_block. */
2080   char id[2];
2081   memcpy (id, old_lf->id, sizeof id);
2082
2083   size_t new_offs = allocate_block (h, seg_len, id);
2084   if (new_offs == 0)
2085     return 0;
2086
2087   /* old_lf could have been invalidated by allocate_block. */
2088   old_lf = (struct ntreg_lf_record *) (h->addr + old_offs);
2089
2090   struct ntreg_lf_record *new_lf =
2091     (struct ntreg_lf_record *) (h->addr + new_offs);
2092   new_lf->nr_keys = htole16 (nr_keys);
2093
2094   /* Copy the keys until we reach posn, insert the new key there, then
2095    * copy the remaining keys.
2096    */
2097   size_t i;
2098   for (i = 0; i < posn; ++i)
2099     new_lf->keys[i] = old_lf->keys[i];
2100
2101   new_lf->keys[i].offset = htole32 (node - 0x1000);
2102   calc_hash (new_lf->id, name, new_lf->keys[i].hash);
2103
2104   for (i = posn+1; i < nr_keys; ++i)
2105     new_lf->keys[i] = old_lf->keys[i-1];
2106
2107   /* Old block is unused, return new block. */
2108   mark_block_unused (h, old_offs);
2109   return new_offs;
2110 }
2111
2112 /* Compare name with name in nk-record. */
2113 static int
2114 compare_name_with_nk_name (hive_h *h, const char *name, hive_node_h nk_offs)
2115 {
2116   assert (IS_VALID_BLOCK (h, nk_offs));
2117   assert (BLOCK_ID_EQ (h, nk_offs, "nk"));
2118
2119   /* Name in nk is not necessarily nul-terminated. */
2120   char *nname = hivex_node_name (h, nk_offs);
2121
2122   /* Unfortunately we don't have a way to return errors here. */
2123   if (!nname) {
2124     perror ("compare_name_with_nk_name");
2125     return 0;
2126   }
2127
2128   int r = strcasecmp (name, nname);
2129   free (nname);
2130
2131   return r;
2132 }
2133
2134 hive_node_h
2135 hivex_node_add_child (hive_h *h, hive_node_h parent, const char *name)
2136 {
2137   if (!h->writable) {
2138     errno = EROFS;
2139     return 0;
2140   }
2141
2142   if (!IS_VALID_BLOCK (h, parent) || !BLOCK_ID_EQ (h, parent, "nk")) {
2143     errno = EINVAL;
2144     return 0;
2145   }
2146
2147   if (name == NULL || strlen (name) == 0) {
2148     errno = EINVAL;
2149     return 0;
2150   }
2151
2152   if (hivex_node_get_child (h, parent, name) != 0) {
2153     errno = EEXIST;
2154     return 0;
2155   }
2156
2157   /* Create the new nk-record. */
2158   static const char nk_id[2] = { 'n', 'k' };
2159   size_t seg_len = sizeof (struct ntreg_nk_record) + strlen (name);
2160   hive_node_h node = allocate_block (h, seg_len, nk_id);
2161   if (node == 0)
2162     return 0;
2163
2164   if (h->msglvl >= 2)
2165     fprintf (stderr, "hivex_node_add_child: allocated new nk-record for child at 0x%zx\n", node);
2166
2167   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
2168   nk->flags = htole16 (0x0020); /* key is ASCII. */
2169   nk->parent = htole32 (parent - 0x1000);
2170   nk->subkey_lf = htole32 (0xffffffff);
2171   nk->subkey_lf_volatile = htole32 (0xffffffff);
2172   nk->vallist = htole32 (0xffffffff);
2173   nk->classname = htole32 (0xffffffff);
2174   nk->name_len = htole16 (strlen (name));
2175   strcpy (nk->name, name);
2176
2177   /* Inherit parent sk. */
2178   struct ntreg_nk_record *parent_nk =
2179     (struct ntreg_nk_record *) (h->addr + parent);
2180   size_t parent_sk_offset = le32toh (parent_nk->sk);
2181   parent_sk_offset += 0x1000;
2182   if (!IS_VALID_BLOCK (h, parent_sk_offset) ||
2183       !BLOCK_ID_EQ (h, parent_sk_offset, "sk")) {
2184     if (h->msglvl >= 2)
2185       fprintf (stderr, "hivex_node_add_child: returning EFAULT because parent sk is not a valid block (%zu)\n",
2186                parent_sk_offset);
2187     errno = EFAULT;
2188     return 0;
2189   }
2190   struct ntreg_sk_record *sk =
2191     (struct ntreg_sk_record *) (h->addr + parent_sk_offset);
2192   sk->refcount = htole32 (le32toh (sk->refcount) + 1);
2193   nk->sk = htole32 (parent_sk_offset - 0x1000);
2194
2195   /* Inherit parent timestamp. */
2196   memcpy (nk->timestamp, parent_nk->timestamp, sizeof (parent_nk->timestamp));
2197
2198   /* What I found out the hard way (not documented anywhere): the
2199    * subkeys in lh-records must be kept sorted.  If you just add a
2200    * subkey in a non-sorted position (eg. just add it at the end) then
2201    * Windows won't see the subkey _and_ Windows will corrupt the hive
2202    * itself when it modifies or saves it.
2203    *
2204    * So use get_children() to get a list of intermediate
2205    * lf/lh-records.  get_children() returns these in reading order
2206    * (which is sorted), so we look for the lf/lh-records in sequence
2207    * until we find the key name just after the one we are inserting,
2208    * and we insert the subkey just before it.
2209    *
2210    * The only other case is the no-subkeys case, where we have to
2211    * create a brand new lh-record.
2212    */
2213   hive_node_h *unused;
2214   size_t *blocks;
2215
2216   if (get_children (h, parent, &unused, &blocks, 0) == -1)
2217     return 0;
2218   free (unused);
2219
2220   size_t i, j;
2221   size_t nr_subkeys_in_parent_nk = le32toh (parent_nk->nr_subkeys);
2222   if (nr_subkeys_in_parent_nk == 0) { /* No subkeys case. */
2223     /* Free up any existing intermediate blocks. */
2224     for (i = 0; blocks[i] != 0; ++i)
2225       mark_block_unused (h, blocks[i]);
2226     size_t lh_offs = new_lh_record (h, name, node);
2227     if (lh_offs == 0) {
2228       free (blocks);
2229       return 0;
2230     }
2231
2232     /* Recalculate pointers that could have been invalidated by
2233      * previous call to allocate_block (via new_lh_record).
2234      */
2235     nk = (struct ntreg_nk_record *) (h->addr + node);
2236     parent_nk = (struct ntreg_nk_record *) (h->addr + parent);
2237
2238     if (h->msglvl >= 2)
2239       fprintf (stderr, "hivex_node_add_child: no keys, allocated new lh-record at 0x%zx\n", lh_offs);
2240
2241     parent_nk->subkey_lf = htole32 (lh_offs - 0x1000);
2242   }
2243   else {                        /* Insert subkeys case. */
2244     size_t old_offs = 0, new_offs = 0;
2245     struct ntreg_lf_record *old_lf = NULL;
2246
2247     /* Find lf/lh key name just after the one we are inserting. */
2248     for (i = 0; blocks[i] != 0; ++i) {
2249       if (BLOCK_ID_EQ (h, blocks[i], "lf") ||
2250           BLOCK_ID_EQ (h, blocks[i], "lh")) {
2251         old_offs = blocks[i];
2252         old_lf = (struct ntreg_lf_record *) (h->addr + old_offs);
2253         for (j = 0; j < le16toh (old_lf->nr_keys); ++j) {
2254           hive_node_h nk_offs = le32toh (old_lf->keys[j].offset);
2255           nk_offs += 0x1000;
2256           if (compare_name_with_nk_name (h, name, nk_offs) < 0)
2257             goto insert_it;
2258         }
2259       }
2260     }
2261
2262     /* Insert it at the end.
2263      * old_offs points to the last lf record, set j.
2264      */
2265     assert (old_offs != 0);   /* should never happen if nr_subkeys > 0 */
2266     j = le16toh (old_lf->nr_keys);
2267
2268     /* Insert it. */
2269   insert_it:
2270     if (h->msglvl >= 2)
2271       fprintf (stderr, "hivex_node_add_child: insert key in existing lh-record at 0x%zx, posn %zu\n", old_offs, j);
2272
2273     new_offs = insert_lf_record (h, old_offs, j, name, node);
2274     if (new_offs == 0) {
2275       free (blocks);
2276       return 0;
2277     }
2278
2279     /* Recalculate pointers that could have been invalidated by
2280      * previous call to allocate_block (via insert_lf_record).
2281      */
2282     nk = (struct ntreg_nk_record *) (h->addr + node);
2283     parent_nk = (struct ntreg_nk_record *) (h->addr + parent);
2284
2285     if (h->msglvl >= 2)
2286       fprintf (stderr, "hivex_node_add_child: new lh-record at 0x%zx\n",
2287                new_offs);
2288
2289     /* If the lf/lh-record was directly referenced by the parent nk,
2290      * then update the parent nk.
2291      */
2292     if (le32toh (parent_nk->subkey_lf) + 0x1000 == old_offs)
2293       parent_nk->subkey_lf = htole32 (new_offs - 0x1000);
2294     /* Else we have to look for the intermediate ri-record and update
2295      * that in-place.
2296      */
2297     else {
2298       for (i = 0; blocks[i] != 0; ++i) {
2299         if (BLOCK_ID_EQ (h, blocks[i], "ri")) {
2300           struct ntreg_ri_record *ri =
2301             (struct ntreg_ri_record *) (h->addr + blocks[i]);
2302           for (j = 0; j < le16toh (ri->nr_offsets); ++j)
2303             if (le32toh (ri->offset[j] + 0x1000) == old_offs) {
2304               ri->offset[j] = htole32 (new_offs - 0x1000);
2305               goto found_it;
2306             }
2307         }
2308       }
2309
2310       /* Not found ..  This is an internal error. */
2311       if (h->msglvl >= 2)
2312         fprintf (stderr, "hivex_node_add_child: returning ENOTSUP because could not find ri->lf link\n");
2313       errno = ENOTSUP;
2314       free (blocks);
2315       return 0;
2316
2317     found_it:
2318       ;
2319     }
2320   }
2321
2322   free (blocks);
2323
2324   /* Update nr_subkeys in parent nk. */
2325   nr_subkeys_in_parent_nk++;
2326   parent_nk->nr_subkeys = htole32 (nr_subkeys_in_parent_nk);
2327
2328   /* Update max_subkey_name_len in parent nk. */
2329   uint16_t max = le16toh (parent_nk->max_subkey_name_len);
2330   if (max < strlen (name) * 2)  /* *2 because "recoded" in UTF16-LE. */
2331     parent_nk->max_subkey_name_len = htole16 (strlen (name) * 2);
2332
2333   return node;
2334 }
2335
2336 /* Decrement the refcount of an sk-record, and if it reaches zero,
2337  * unlink it from the chain and delete it.
2338  */
2339 static int
2340 delete_sk (hive_h *h, size_t sk_offset)
2341 {
2342   if (!IS_VALID_BLOCK (h, sk_offset) || !BLOCK_ID_EQ (h, sk_offset, "sk")) {
2343     if (h->msglvl >= 2)
2344       fprintf (stderr, "delete_sk: not an sk record: 0x%zx\n", sk_offset);
2345     errno = EFAULT;
2346     return -1;
2347   }
2348
2349   struct ntreg_sk_record *sk = (struct ntreg_sk_record *) (h->addr + sk_offset);
2350
2351   if (sk->refcount == 0) {
2352     if (h->msglvl >= 2)
2353       fprintf (stderr, "delete_sk: sk record already has refcount 0: 0x%zx\n",
2354                sk_offset);
2355     errno = EINVAL;
2356     return -1;
2357   }
2358
2359   sk->refcount--;
2360
2361   if (sk->refcount == 0) {
2362     size_t sk_prev_offset = sk->sk_prev;
2363     sk_prev_offset += 0x1000;
2364
2365     size_t sk_next_offset = sk->sk_next;
2366     sk_next_offset += 0x1000;
2367
2368     /* Update sk_prev/sk_next SKs, unless they both point back to this
2369      * cell in which case we are deleting the last SK.
2370      */
2371     if (sk_prev_offset != sk_offset && sk_next_offset != sk_offset) {
2372       struct ntreg_sk_record *sk_prev =
2373         (struct ntreg_sk_record *) (h->addr + sk_prev_offset);
2374       struct ntreg_sk_record *sk_next =
2375         (struct ntreg_sk_record *) (h->addr + sk_next_offset);
2376
2377       sk_prev->sk_next = htole32 (sk_next_offset - 0x1000);
2378       sk_next->sk_prev = htole32 (sk_prev_offset - 0x1000);
2379     }
2380
2381     /* Refcount is zero so really delete this block. */
2382     mark_block_unused (h, sk_offset);
2383   }
2384
2385   return 0;
2386 }
2387
2388 /* Callback from hivex_node_delete_child which is called to delete a
2389  * node AFTER its subnodes have been visited.  The subnodes have been
2390  * deleted but we still have to delete any lf/lh/li/ri records and the
2391  * value list block and values, followed by deleting the node itself.
2392  */
2393 static int
2394 delete_node (hive_h *h, void *opaque, hive_node_h node, const char *name)
2395 {
2396   /* Get the intermediate blocks.  The subkeys have already been
2397    * deleted by this point, so tell get_children() not to check for
2398    * validity of the nk-records.
2399    */
2400   hive_node_h *unused;
2401   size_t *blocks;
2402   if (get_children (h, node, &unused, &blocks, GET_CHILDREN_NO_CHECK_NK) == -1)
2403     return -1;
2404   free (unused);
2405
2406   /* We don't care what's in these intermediate blocks, so we can just
2407    * delete them unconditionally.
2408    */
2409   size_t i;
2410   for (i = 0; blocks[i] != 0; ++i)
2411     mark_block_unused (h, blocks[i]);
2412
2413   free (blocks);
2414
2415   /* Delete the values in the node. */
2416   if (delete_values (h, node) == -1)
2417     return -1;
2418
2419   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
2420
2421   /* If the NK references an SK, delete it. */
2422   size_t sk_offs = le32toh (nk->sk);
2423   if (sk_offs != 0xffffffff) {
2424     sk_offs += 0x1000;
2425     if (delete_sk (h, sk_offs) == -1)
2426       return -1;
2427     nk->sk = htole32 (0xffffffff);
2428   }
2429
2430   /* If the NK references a classname, delete it. */
2431   size_t cl_offs = le32toh (nk->classname);
2432   if (cl_offs != 0xffffffff) {
2433     cl_offs += 0x1000;
2434     mark_block_unused (h, cl_offs);
2435     nk->classname = htole32 (0xffffffff);
2436   }
2437
2438   /* Delete the node itself. */
2439   mark_block_unused (h, node);
2440
2441   return 0;
2442 }
2443
2444 int
2445 hivex_node_delete_child (hive_h *h, hive_node_h node)
2446 {
2447   if (!h->writable) {
2448     errno = EROFS;
2449     return -1;
2450   }
2451
2452   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
2453     errno = EINVAL;
2454     return -1;
2455   }
2456
2457   if (node == hivex_root (h)) {
2458     if (h->msglvl >= 2)
2459       fprintf (stderr, "hivex_node_delete_child: cannot delete root node\n");
2460     errno = EINVAL;
2461     return -1;
2462   }
2463
2464   hive_node_h parent = hivex_node_parent (h, node);
2465   if (parent == 0)
2466     return -1;
2467
2468   /* Delete node and all its children and values recursively. */
2469   static const struct hivex_visitor visitor = { .node_end = delete_node };
2470   if (hivex_visit_node (h, node, &visitor, sizeof visitor, NULL, 0) == -1)
2471     return -1;
2472
2473   /* Delete the link from parent to child.  We need to find the lf/lh
2474    * record which contains the offset and remove the offset from that
2475    * record, then decrement the element count in that record, and
2476    * decrement the overall number of subkeys stored in the parent
2477    * node.
2478    */
2479   hive_node_h *unused;
2480   size_t *blocks;
2481   if (get_children (h, parent, &unused, &blocks, GET_CHILDREN_NO_CHECK_NK)== -1)
2482     return -1;
2483   free (unused);
2484
2485   size_t i, j;
2486   for (i = 0; blocks[i] != 0; ++i) {
2487     struct ntreg_hbin_block *block =
2488       (struct ntreg_hbin_block *) (h->addr + blocks[i]);
2489
2490     if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
2491       struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
2492
2493       size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
2494
2495       for (j = 0; j < nr_subkeys_in_lf; ++j)
2496         if (le32toh (lf->keys[j].offset) + 0x1000 == node) {
2497           for (; j < nr_subkeys_in_lf - 1; ++j)
2498             memcpy (&lf->keys[j], &lf->keys[j+1], sizeof (lf->keys[j]));
2499           lf->nr_keys = htole16 (nr_subkeys_in_lf - 1);
2500           goto found;
2501         }
2502     }
2503   }
2504   if (h->msglvl >= 2)
2505     fprintf (stderr, "hivex_node_delete_child: could not find parent to child link\n");
2506   errno = ENOTSUP;
2507   return -1;
2508
2509  found:;
2510   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + parent);
2511   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
2512   nk->nr_subkeys = htole32 (nr_subkeys_in_nk - 1);
2513
2514   if (h->msglvl >= 2)
2515     fprintf (stderr, "hivex_node_delete_child: updating nr_subkeys in parent 0x%zx to %zu\n",
2516              parent, nr_subkeys_in_nk);
2517
2518   return 0;
2519 }
2520
2521 int
2522 hivex_node_set_values (hive_h *h, hive_node_h node,
2523                        size_t nr_values, const hive_set_value *values,
2524                        int flags)
2525 {
2526   if (!h->writable) {
2527     errno = EROFS;
2528     return -1;
2529   }
2530
2531   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
2532     errno = EINVAL;
2533     return -1;
2534   }
2535
2536   /* Delete all existing values. */
2537   if (delete_values (h, node) == -1)
2538     return -1;
2539
2540   if (nr_values == 0)
2541     return 0;
2542
2543   /* Allocate value list node.  Value lists have no id field. */
2544   static const char nul_id[2] = { 0, 0 };
2545   size_t seg_len =
2546     sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t);
2547   size_t vallist_offs = allocate_block (h, seg_len, nul_id);
2548   if (vallist_offs == 0)
2549     return -1;
2550
2551   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
2552   nk->nr_values = htole32 (nr_values);
2553   nk->vallist = htole32 (vallist_offs - 0x1000);
2554
2555   struct ntreg_value_list *vallist =
2556     (struct ntreg_value_list *) (h->addr + vallist_offs);
2557
2558   size_t i;
2559   for (i = 0; i < nr_values; ++i) {
2560     /* Allocate vk record to store this (key, value) pair. */
2561     static const char vk_id[2] = { 'v', 'k' };
2562     seg_len = sizeof (struct ntreg_vk_record) + strlen (values[i].key);
2563     size_t vk_offs = allocate_block (h, seg_len, vk_id);
2564     if (vk_offs == 0)
2565       return -1;
2566
2567     /* Recalculate pointers that could have been invalidated by
2568      * previous call to allocate_block.
2569      */
2570     nk = (struct ntreg_nk_record *) (h->addr + node);
2571     vallist = (struct ntreg_value_list *) (h->addr + vallist_offs);
2572
2573     vallist->offset[i] = htole32 (vk_offs - 0x1000);
2574
2575     struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + vk_offs);
2576     size_t name_len = strlen (values[i].key);
2577     vk->name_len = htole16 (name_len);
2578     strcpy (vk->name, values[i].key);
2579     vk->data_type = htole32 (values[i].t);
2580     uint32_t len = values[i].len;
2581     if (len <= 4)               /* store it inline => set MSB flag */
2582       len |= 0x80000000;
2583     vk->data_len = htole32 (len);
2584     vk->flags = name_len == 0 ? 0 : 1;
2585
2586     if (values[i].len <= 4)     /* store it inline */
2587       memcpy (&vk->data_offset, values[i].value, values[i].len);
2588     else {
2589       size_t offs = allocate_block (h, values[i].len + 4, nul_id);
2590       if (offs == 0)
2591         return -1;
2592
2593       /* Recalculate pointers that could have been invalidated by
2594        * previous call to allocate_block.
2595        */
2596       nk = (struct ntreg_nk_record *) (h->addr + node);
2597       vallist = (struct ntreg_value_list *) (h->addr + vallist_offs);
2598       vk = (struct ntreg_vk_record *) (h->addr + vk_offs);
2599
2600       memcpy (h->addr + offs + 4, values[i].value, values[i].len);
2601       vk->data_offset = htole32 (offs - 0x1000);
2602     }
2603
2604     if (name_len * 2 > le32toh (nk->max_vk_name_len))
2605       /* * 2 for UTF16-LE "reencoding" */
2606       nk->max_vk_name_len = htole32 (name_len * 2);
2607     if (values[i].len > le32toh (nk->max_vk_data_len))
2608       nk->max_vk_data_len = htole32 (values[i].len);
2609   }
2610
2611   return 0;
2612 }
2613
2614 int
2615 hivex_node_set_value (hive_h *h, hive_node_h node,
2616                       const hive_set_value *val, int flags)
2617 {
2618   hive_value_h *prev_values = hivex_node_values (h, node);
2619   if (prev_values == NULL)
2620     return -1;
2621
2622   int retval = -1;
2623
2624   size_t nr_values = 0;
2625   for (hive_value_h *itr = prev_values; *itr != 0; ++itr)
2626     ++nr_values;
2627
2628   hive_set_value *values = malloc ((nr_values + 1) * (sizeof (hive_set_value)));
2629   if (values == NULL)
2630     goto leave_prev_values;
2631
2632   int alloc_ct = 0;
2633   int idx_of_val = -1;
2634   hive_value_h *prev_val;
2635   for (prev_val = prev_values; *prev_val != 0; ++prev_val) {
2636     size_t len;
2637     hive_type t;
2638
2639     hive_set_value *value = &values[prev_val - prev_values];
2640
2641     char *valval = hivex_value_value (h, *prev_val, &t, &len);
2642     if (valval == NULL) goto leave_partial;
2643
2644     ++alloc_ct;
2645     value->value = valval;
2646     value->t = t;
2647     value->len = len;
2648
2649     char *valkey = hivex_value_key (h, *prev_val);
2650     if (valkey == NULL) goto leave_partial;
2651
2652     ++alloc_ct;
2653     value->key = valkey;
2654
2655     if (STRCASEEQ (valkey, val->key))
2656       idx_of_val = prev_val - prev_values;
2657   }
2658
2659   if (idx_of_val > -1) {
2660     free (values[idx_of_val].key);
2661     free (values[idx_of_val].value);
2662   } else {
2663     idx_of_val = nr_values;
2664     ++nr_values;
2665   }
2666
2667   hive_set_value *value = &values[idx_of_val];
2668   *value = (hive_set_value){
2669     .key = strdup (val->key),
2670     .value = malloc (val->len),
2671     .len = val->len,
2672     .t = val->t
2673   };
2674
2675   if (value->key == NULL || value->value == NULL) goto leave_partial;
2676   memcpy (value->value, val->value, val->len);
2677
2678   retval = hivex_node_set_values (h, node, nr_values, values, 0);
2679
2680  leave_partial:
2681   for (int i = 0; i < alloc_ct; i += 2) {
2682     if (values[i / 2].value != NULL)
2683       free (values[i / 2].value);
2684     if (i + 1 < alloc_ct && values[i / 2].key != NULL)
2685       free (values[i / 2].key);
2686   }
2687   free (values);
2688
2689  leave_prev_values:
2690   free (prev_values);
2691   return retval;
2692 }