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