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

[Libguestfs] Patch to build hivex lib on Windows



Hi

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.

cu

--
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..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;
 }

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