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