[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Libguestfs] Patch to build hivex lib on Windows
From: |
Jim Meyering |
Subject: |
Re: [Libguestfs] Patch to build hivex lib on Windows |
Date: |
Sat, 03 Sep 2011 20:01:03 +0200 |
Richard W.M. Jones wrote:
> On Sat, Sep 03, 2011 at 04:45:28PM +0200, Gillen Daniel wrote:
>> I'm just posting this here in case someone is interested in building
>> hivex on Windows (mingw32). The attached patch allows building the
>> lib but not the tools (hivexsh etc..) as there are some more
>> problems to solve.
>>
>> In short terms, this patch replaces file i/o functions and mmap(),
>> munmap() with their win32api pendants.
>
> NACK ... This patch is too invasive.
>
> We are already linking with gnulib, which ought to provide a degree of
> platform independence. By adding the right gnulib modules (see the
> file 'bootstrap' in the toplevel directory) it should be possible to
> make hivex compile directly on Windows, while requiring fewer source
> code changes.
>
> gnulib can almost certainly do all the file things. I don't see a
> gnulib module for mmap, which could be a problem, but a less invasive
> change should still be possible for that.
>
> Rich.
>
>> diff --git a/lib/hivex.c b/lib/hivex.c
>> index 4b9fcf0..986bdeb 100644
>> --- a/lib/hivex.c
>> +++ b/lib/hivex.c
>> @@ -30,13 +30,19 @@
>> #include <unistd.h>
>> #include <errno.h>
>> #include <iconv.h>
>> -#include <sys/mman.h>
>> +#ifndef __MINGW32__
>> + #include <sys/mman.h>
>> +#else
>> + #include <windows.h>
>> +#endif
>> #include <sys/stat.h>
>> #include <assert.h>
>>
>> #include "c-ctype.h"
>> -#include "full-read.h"
>> -#include "full-write.h"
>> +#ifndef __MINGW32__
>> + #include "full-read.h"
>> + #include "full-write.h"
>> +#endif
>>
>> #define STREQ(a,b) (strcmp((a),(b)) == 0)
>> #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
>> @@ -62,7 +68,13 @@ static size_t utf16_string_len_in_bytes_max (const char
>> *str, size_t len);
>>
>> struct hive_h {
>> char *filename;
>> +#ifndef __MINGW32__
>> int fd;
>> +#else
>> + HANDLE fd;
>> + HANDLE winmap;
>> +#endif
>> +
>> size_t size;
>> int msglvl;
>> int writable;
>> @@ -294,28 +306,48 @@ hivex_open (const char *filename, int flags)
>> if (h->filename == NULL)
>> goto error;
>>
>> -#ifdef O_CLOEXEC
>> - h->fd = open (filename, O_RDONLY | O_CLOEXEC);
>> -#else
>> - h->fd = open (filename, O_RDONLY);
>> -#endif
>> - if (h->fd == -1)
>> - goto error;
>> -#ifndef O_CLOEXEC
>> - fcntl (h->fd, F_SETFD, FD_CLOEXEC);
>> -#endif
>> -
>> +#ifndef __MINGW32__
>> + #ifdef O_CLOEXEC
>> + h->fd = open (filename, O_RDONLY | O_CLOEXEC);
>> + #else
>> + h->fd = open (filename, O_RDONLY);
>> + #endif
>> + if (h->fd == -1)
>> + goto error;
>> + #ifndef O_CLOEXEC
>> + fcntl (h->fd, F_SETFD, FD_CLOEXEC);
>> + #endif
>> +
>> struct stat statbuf;
>> if (fstat (h->fd, &statbuf) == -1)
>> goto error;
>>
>> h->size = statbuf.st_size;
>> +#else
>> + h->fd = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
>> OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
>> + if (h->fd == INVALID_HANDLE_VALUE)
>> + goto error;
>> +
>> + // XXX: There might be a problem if hive > 2^32 bytes
>> + h->size = GetFileSize (h->fd, NULL);
>> +#endif
>>
>> if (!h->writable) {
>> +#ifndef __MINGW32__
>> h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0);
>> if (h->addr == MAP_FAILED)
>> goto error;
>> -
>> +#else
>> + // Mingw does not support mmap, we have to use native API
>> + // Create file mapping
>> + h->winmap = CreateFileMapping (h->fd, NULL, PAGE_READONLY, 0, 0, NULL);
>> + if (h->winmap == NULL)
>> + goto error;
>> + // Create map view
>> + h->addr = MapViewOfFile (h->winmap, FILE_MAP_READ, 0, 0, h->size);
>> + if (h->addr == NULL)
>> + goto error;
>> +#endif
>> if (h->msglvl >= 2)
>> fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
>> } else {
>> @@ -323,15 +355,29 @@ hivex_open (const char *filename, int flags)
>> if (h->addr == NULL)
>> goto error;
>>
>> +#ifndef __MINGW32__
>> if (full_read (h->fd, h->addr, h->size) < h->size)
>> goto error;
>> +#else
>> + DWORD bytes_read=0;
>> + if (!ReadFile (h->fd, h->addr, h->size, &bytes_read, NULL))
>> + goto error;
>> + if (bytes_read != h->size)
>> + goto error;
>> +#endif
>>
>> /* We don't need the file descriptor along this path, since we
>> * have read all the data.
>> */
>> +#ifndef __MINGW32__
>> if (close (h->fd) == -1)
>> goto error;
>> h->fd = -1;
>> +#else
>> + if (!CloseHandle (h->fd))
>> + goto error;
>> + h->fd = INVALID_HANDLE_VALUE;
>> +#endif
>> }
>>
>> /* Check header. */
>> @@ -532,14 +578,28 @@ hivex_open (const char *filename, int flags)
>> int err = errno;
>> if (h) {
>> free (h->bitmap);
>> +#ifndef __MINGW32__
>> if (h->addr && h->size && h->addr != MAP_FAILED) {
>> - if (!h->writable)
>> +#else
>> + if (h->addr && h->size && h->addr != NULL) {
>> +#endif
>> + if (!h->writable) {
>> +#ifndef __MINGW32__
>> munmap (h->addr, h->size);
>> - else
>> +#else
>> + UnmapViewOfFile (h->addr);
>> + CloseHandle (h->winmap);
>> +#endif
>> + } else
>> free (h->addr);
>> }
>> +#ifndef __MINGW32__
>> if (h->fd >= 0)
>> close (h->fd);
>> +#else
>> + if (h->fd != INVALID_HANDLE_VALUE)
>> + CloseHandle (h->fd);
>> +#endif
>> free (h->filename);
>> free (h);
>> }
>> @@ -556,12 +616,22 @@ hivex_close (hive_h *h)
>> fprintf (stderr, "hivex_close\n");
>>
>> free (h->bitmap);
>> - if (!h->writable)
>> + if (!h->writable) {
>> +#ifndef __MINGW32__
>> munmap (h->addr, h->size);
>> - else
>> +#else
>> + UnmapViewOfFile (h->addr);
>> + CloseHandle (h->winmap);
>> +#endif
>> + } else
>> free (h->addr);
>> +#ifndef __MINGW32__
>> if (h->fd >= 0)
>> r = close (h->fd);
>> +#else
>> + if (h->fd != INVALID_HANDLE_VALUE)
>> + r = CloseHandle (h->fd) ? 0 : 1;
>> +#endif
>> else
>> r = 0;
>> free (h->filename);
>> @@ -2100,9 +2170,15 @@ hivex_commit (hive_h *h, const char *filename, int
>> flags)
>> }
>>
>> filename = filename ? : h->filename;
>> +#ifndef __MINGW32__
>> int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
>> if (fd == -1)
>> return -1;
>> +#else
>> + HANDLE fd = CreateFile (filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
>> FILE_ATTRIBUTE_NORMAL, NULL);
>> + if (fd == INVALID_HANDLE_VALUE)
>> + return -1;
>> +#endif
>>
>> /* Update the header fields. */
>> uint32_t sequence = le32toh (h->hdr->sequence1);
>> @@ -2119,6 +2195,7 @@ hivex_commit (hive_h *h, const char *filename, int
>> flags)
>> if (h->msglvl >= 2)
>> fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum);
>>
>> +#ifndef __MINGW32__
>> if (full_write (fd, h->addr, h->size) != h->size) {
>> int err = errno;
>> close (fd);
>> @@ -2128,6 +2205,20 @@ hivex_commit (hive_h *h, const char *filename, int
>> flags)
>>
>> if (close (fd) == -1)
>> return -1;
>> +#else
>> + DWORD bytes_written;
>> + if (!WriteFile (fd, h->addr, h->size, &bytes_written, NULL)) {
>> + CloseHandle (fd);
>> + return -1;
>> + }
>> + if (bytes_written != h->size) {
>> + CloseHandle (fd);
>> + return -1;
>> + }
>> +
>> + if (!CloseHandle (fd))
>> + return -1;
>> +#endif
>>
>> return 0;
>> }
Thanks for the patch, Gillen, but as Rich says, parts look unnecessary.
In particular, why do you ifdef the uses of full_read and full_write?
I've Cc'd bug-gnulib.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Libguestfs] Patch to build hivex lib on Windows,
Jim Meyering <=