[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Libguestfs] Patch to build hivex lib on Windows

On 09/03/2011 07:35 PM, 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.


mmap is exactly the problem. I didn't find it in gnulib or somewhere else.

I did some more research on how it could be done and I came up with the following. Definitely less invasive :) and full_read and full_write can be used again.

What do you think about that one?

Oh, and there is another problem which I encountered while building on Windows and on Osx 10.7.

In Linux, "include/bits/byteswap.h" define __bswap_* functions and "include/byteswap.h" define those as bswap_*. Your "lib/byte_conversions.h" file uses the __bswap_* functions but when compiling on a system where byteswap.h does not exist and the gnulib byteswap.h file is used, there are no __bswap_* functions defined anymore resulting in the lib not being able to link.

Is there a special reason the __bswap_* functions were used and not the bswap_* ones?

Unix _IS_ user friendly - it's just
selective about who its friends are!
diff --git a/lib/hivex.c b/lib/hivex.c
index 4b9fcf0..374e435 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -30,7 +30,11 @@
 #include <unistd.h>
 #include <errno.h>
 #include <iconv.h>
-#include <sys/mman.h>
+#ifndef __MINGW32__
+  #include <sys/mman.h>
+  #include <windows.h>
 #include <sys/stat.h>
 #include <assert.h>
@@ -63,6 +67,10 @@ static size_t utf16_string_len_in_bytes_max (const char *str, size_t len);
 struct hive_h {
   char *filename;
   int fd;
+#ifdef __MINGW32__
+  HANDLE winmap;
   size_t size;
   int msglvl;
   int writable;
@@ -312,9 +320,21 @@ hivex_open (const char *filename, int flags)
   h->size = statbuf.st_size;
   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;
+    // Mingw / Gnulib does not support mmap, we have to use native win32api
+    // Create file mapping
+    h->winmap = CreateFileMapping ((HANDLE)_get_osfhandle(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;
     if (h->msglvl >= 2)
       fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
@@ -532,11 +552,23 @@ 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)
+    if (h->addr && h->size && h->addr != NULL) {
+      if (!h->writable) {
+#ifndef __MINGW32__
         munmap (h->addr, h->size);
-      else
+        UnmapViewOfFile (h->addr);
+      } else
         free (h->addr);
+#ifdef __MINGW32__
+      if (!h->writable && h->winmap != NULL)
+        CloseHandle (h->winmap);
     if (h->fd >= 0)
       close (h->fd);
@@ -556,9 +588,14 @@ 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
+    UnmapViewOfFile (h->addr);
+    CloseHandle (h->winmap);
+  } else
     free (h->addr);
   if (h->fd >= 0)
     r = close (h->fd);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]