X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=hivex%2Fhivex.c;h=44f29984c055ebb1e5b036a37e06cf2a186e301b;hp=d2c450fe192e3011425114d8718168e33828fd60;hb=4718aeb9f0f743a05dfa342bc797617f3b9f96b3;hpb=9a7640218c8c13d2924686d96457cfe0d3f91b1c diff --git a/hivex/hivex.c b/hivex/hivex.c index d2c450f..44f2998 100644 --- a/hivex/hivex.c +++ b/hivex/hivex.c @@ -1,5 +1,5 @@ /* hivex - Windows Registry "hive" extraction library. - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2010 Red Hat Inc. * Derived from code by Petter Nordahl-Hagen under a compatible license: * Copyright (c) 1997-2007 Petter Nordahl-Hagen. * Derived from code by Markus Stephany under a compatible license: @@ -33,11 +33,11 @@ #include #include #include -#ifdef HAVE_ENDIAN_H -#include -#endif -#ifdef HAVE_BYTESWAP_H -#include + +#include "full-read.h" + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 #endif #define STREQ(a,b) (strcmp((a),(b)) == 0) @@ -50,41 +50,8 @@ //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0) //#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#ifndef be32toh -#define be32toh(x) __bswap_32 (x) -#endif -#ifndef be64toh -#define be64toh(x) __bswap_64 (x) -#endif -#ifndef le16toh -#define le16toh(x) (x) -#endif -#ifndef le32toh -#define le32toh(x) (x) -#endif -#ifndef le64toh -#define le64toh(x) (x) -#endif -#else -#ifndef be32toh -#define be32toh(x) (x) -#endif -#ifndef be64toh -#define be64toh(x) (x) -#endif -#ifndef le16toh -#define le16toh(x) __bswap_16 (x) -#endif -#ifndef le32toh -#define le32toh(x) __bswap_32 (x) -#endif -#ifndef le64toh -#define le64toh(x) __bswap_64 (x) -#endif -#endif - #include "hivex.h" +#include "byte_conversions.h" static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len); @@ -93,8 +60,9 @@ struct hive_h { int fd; size_t size; int msglvl; + int writable; - /* Memory-mapped (readonly) registry file. */ + /* Registry file, memory mapped if read-only, or malloc'd if writing. */ union { char *addr; struct ntreg_header *hdr; @@ -257,7 +225,8 @@ struct ntreg_vk_record { uint32_t data_type; /* type of the data */ uint16_t flags; /* bit 0 set => key name ASCII, bit 0 clr => key name UTF-16. - Only seen ASCII here in the wild. */ + Only seen ASCII here in the wild. + NB: this is CLEAR for default key. */ uint16_t unknown2; char name[1]; /* key name follows here */ } __attribute__((__packed__)); @@ -298,11 +267,12 @@ hivex_open (const char *filename, int flags) if (h->msglvl >= 2) fprintf (stderr, "hivex_open: created handle %p\n", h); + h->writable = !!(flags & HIVEX_OPEN_WRITE); h->filename = strdup (filename); if (h->filename == NULL) goto error; - h->fd = open (filename, O_RDONLY); + h->fd = open (filename, O_RDONLY | O_CLOEXEC); if (h->fd == -1) goto error; @@ -312,12 +282,21 @@ hivex_open (const char *filename, int flags) h->size = statbuf.st_size; - h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0); - if (h->addr == MAP_FAILED) - goto error; + if (!h->writable) { + h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0); + if (h->addr == MAP_FAILED) + goto error; - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr); + if (h->msglvl >= 2) + fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr); + } else { + h->addr = malloc (h->size); + if (h->addr == NULL) + goto error; + + if (full_read (h->fd, h->addr, h->size) < h->size) + goto error; + } /* Check header. */ if (h->hdr->magic[0] != 'r' || @@ -509,8 +488,12 @@ hivex_open (const char *filename, int flags) int err = errno; if (h) { free (h->bitmap); - if (h->addr && h->size && h->addr != MAP_FAILED) - munmap (h->addr, h->size); + if (h->addr && h->size && h->addr != MAP_FAILED) { + if (!h->writable) + munmap (h->addr, h->size); + else + free (h->addr); + } if (h->fd >= 0) close (h->fd); free (h->filename); @@ -526,7 +509,10 @@ hivex_close (hive_h *h) int r; free (h->bitmap); - munmap (h->addr, h->size); + if (!h->writable) + munmap (h->addr, h->size); + else + free (h->addr); r = close (h->fd); free (h->filename); free (h);