Adapt ext4_utils for windows.

This is not a full port of ext4_utils for windows.
Instead it merely enables use to use the library
for the 'create an empty fs image' functionality
as used by 'fastboot format'.

Change-Id: Ia1ffacd64e4233c4fbb369c4ac5927ccd72ac526
diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk
index 9b0dc1b..f09197c 100644
--- a/ext4_utils/Android.mk
+++ b/ext4_utils/Android.mk
@@ -4,7 +4,7 @@
 include $(CLEAR_VARS)
 
 libext4_utils_src_files := \
-	make_ext4fs.c \
+        make_ext4fs.c \
         ext4fixup.c \
         ext4_utils.c \
         allocate.c \
@@ -15,8 +15,34 @@
         indirect.c \
         uuid.c \
         sha1.c \
-	sparse_crc32.c \
-	wipe.c
+        sparse_crc32.c \
+        wipe.c
+
+# -- All host/targets including windows
+
+LOCAL_SRC_FILES := $(libext4_utils_src_files)
+LOCAL_MODULE := libext4_utils
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES += external/zlib
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := make_ext4fs_main.c
+LOCAL_MODULE := make_ext4fs
+LOCAL_STATIC_LIBRARIES += libext4_utils libz
+ifeq ($(HOST_OS),windows)
+LOCAL_LDLIBS += -lws2_32
+endif
+
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
+# -- All host/targets excluding windows
+
+ifneq ($(HOST_OS),windows)
 
 LOCAL_SRC_FILES := $(libext4_utils_src_files)
 LOCAL_MODULE := libext4_utils
@@ -24,7 +50,6 @@
 LOCAL_C_INCLUDES += external/zlib
 LOCAL_SHARED_LIBRARIES := libz
 
-
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -38,14 +63,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(libext4_utils_src_files)
-LOCAL_MODULE := libext4_utils
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
 LOCAL_SRC_FILES := make_ext4fs_main.c
 LOCAL_MODULE := make_ext4fs
 LOCAL_MODULE_TAGS := optional
@@ -55,14 +72,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := make_ext4fs_main.c
-LOCAL_MODULE := make_ext4fs
-LOCAL_STATIC_LIBRARIES += libext4_utils libz
-
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
 LOCAL_SRC_FILES := ext2simg.c
 LOCAL_MODULE := ext2simg
 LOCAL_MODULE_TAGS := optional
@@ -160,3 +169,5 @@
 LOCAL_IS_HOST_MODULE := true
 
 include $(BUILD_PREBUILT)
+
+endif
diff --git a/ext4_utils/contents.c b/ext4_utils/contents.c
index c7607ab..d64f7e0 100644
--- a/ext4_utils/contents.c
+++ b/ext4_utils/contents.c
@@ -26,6 +26,10 @@
 #include "extent.h"
 #include "indirect.h"
 
+#ifdef USE_MINGW
+#define S_IFLNK 0  /* used by make_link, not needed under mingw */
+#endif
+
 static u32 dentry_size(u32 entries, struct dentry *dentries)
 {
 	u32 len = 24;
diff --git a/ext4_utils/ext4_utils.c b/ext4_utils/ext4_utils.c
index 3d5895e..9bb523f 100644
--- a/ext4_utils/ext4_utils.c
+++ b/ext4_utils/ext4_utils.c
@@ -23,12 +23,17 @@
 #include "extent.h"
 
 #include <fcntl.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <string.h>
 
+#ifdef USE_MINGW
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#endif
+
 #if defined(__linux__)
 #include <linux/fs.h>
 #elif defined(__APPLE__) && defined(__MACH__)
@@ -514,4 +519,3 @@
 
 	return num;
 }
-
diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h
index bb9c09e..5b835ed 100644
--- a/ext4_utils/ext4_utils.h
+++ b/ext4_utils/ext4_utils.h
@@ -64,7 +64,9 @@
 #define EXT4_SUPER_MAGIC 0xEF53
 #define EXT4_JNL_BACKUP_BLOCKS 1
 
+#ifndef min /* already defined by windows.h */
 #define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
 
 #define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
 #define ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
diff --git a/ext4_utils/ext4fixup.c b/ext4_utils/ext4fixup.c
index 5e04602..c664ac3 100644
--- a/ext4_utils/ext4fixup.c
+++ b/ext4_utils/ext4fixup.c
@@ -24,10 +24,13 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/mman.h>
 #include <fcntl.h>
 #include <unistd.h>
 
+#ifndef USE_MINGW
+#include <sys/mman.h>
+#endif
+
 #if defined(__APPLE__) && defined(__MACH__)
 #define lseek64 lseek
 #define off64_t off_t
diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c
index dbffc8d..c11bebb 100644
--- a/ext4_utils/make_ext4fs.c
+++ b/ext4_utils/make_ext4fs.c
@@ -22,6 +22,7 @@
 #include "uuid.h"
 #include "backed_block.h"
 
+#include <assert.h>
 #include <dirent.h>
 #include <libgen.h>
 #include <stdio.h>
@@ -35,6 +36,31 @@
 #include <private/android_filesystem_config.h>
 #endif
 
+#ifdef USE_MINGW
+
+#include <winsock2.h>
+
+/* These match the Linux definitions of these flags.
+   L_xx is defined to avoid conflicting with the win32 versions.
+*/
+#define L_S_IRUSR 00400
+#define L_S_IWUSR 00200
+#define L_S_IXUSR 00100
+#define S_IRWXU (L_S_IRUSR | L_S_IWUSR | L_S_IXUSR)
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+
+#endif
+
 /* TODO: Not implemented:
    Allocating blocks in the same block group as the file inode
    Hash or binary tree directories
@@ -67,6 +93,7 @@
 	return root_inode;
 }
 
+#ifndef USE_MINGW
 /* Read a local directory and create the same tree in the generated filesystem.
    Calls itself recursively with each directory in the given directory */
 static u32 build_directory_structure(const char *full_path, const char *dir_path,
@@ -184,6 +211,7 @@
 	free(dentries);
 	return inode;
 }
+#endif
 
 static u32 compute_block_size()
 {
@@ -345,10 +373,16 @@
 	if (info.feat_compat & EXT4_FEATURE_COMPAT_RESIZE_INODE)
 		ext4_create_resize_inode();
 
+#ifdef USE_MINGW
+	// Windows needs only 'create an empty fs image' functionality
+	assert(!directory);
+	root_inode_num = build_default_directory_structure();
+#else
 	if (directory)
 		root_inode_num = build_directory_structure(directory, mountpoint, 0, android);
 	else
 		root_inode_num = build_default_directory_structure();
+#endif
 
 	root_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
 	inode_set_permissions(root_inode_num, root_mode, 0, 0, 0);
diff --git a/ext4_utils/output_file.c b/ext4_utils/output_file.c
index 7b44020..7af48de 100644
--- a/ext4_utils/output_file.c
+++ b/ext4_utils/output_file.c
@@ -23,12 +23,16 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/mman.h>
 #include <unistd.h>
 #include <fcntl.h>
-
 #include <zlib.h>
 
+#ifndef USE_MINGW
+#include <sys/mman.h>
+#define O_BINARY 0
+#endif
+
+
 #if defined(__APPLE__) && defined(__MACH__)
 #define lseek64 lseek
 #define off64_t off_t
@@ -370,7 +374,7 @@
 		}
 	} else {
 		if (strcmp(filename, "-")) {
-			out->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+			out->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
 			if (out->fd < 0) {
 				error_errno("open");
 				free(out);
@@ -512,6 +516,7 @@
 	int ret;
 	off64_t aligned_offset;
 	int aligned_diff;
+	int buffer_size;
 
 	if (off + len >= (u64) info.len) {
 		error("attempted to write block %llu past end of filesystem",
@@ -519,7 +524,7 @@
 		return;
 	}
 
-	int file_fd = open(file, O_RDONLY);
+	int file_fd = open(file, O_RDONLY | O_BINARY);
 	if (file_fd < 0) {
 		error_errno("open");
 		return;
@@ -527,14 +532,25 @@
 
 	aligned_offset = offset & ~(4096 - 1);
 	aligned_diff = offset - aligned_offset;
+	buffer_size = len + aligned_diff;
 
-	u8 *data = mmap64(NULL, len + aligned_diff, PROT_READ, MAP_SHARED, file_fd,
+#ifndef USE_MINGW
+	u8 *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, file_fd,
 			aligned_offset);
 	if (data == MAP_FAILED) {
 		error_errno("mmap64");
 		close(file_fd);
 		return;
 	}
+#else
+	u8 *data = malloc(buffer_size);
+	if (!data) {
+		error_errno("malloc");
+		close(file_fd);
+		return;
+	}
+	memset(data, 0, buffer_size);
+#endif
 
 	if (out->sparse) {
 		write_chunk_raw(out, off, data + aligned_diff, len);
@@ -549,6 +565,11 @@
 	}
 
 err:
-	munmap(data, len + aligned_diff);
+#ifndef USE_MINGW
+	munmap(data, buffer_size);
+#else
+	write(file_fd, data, buffer_size);
+	free(data);
+#endif
 	close(file_fd);
 }
diff --git a/ext4_utils/sha1.c b/ext4_utils/sha1.c
index 1db9134..463ec38 100644
--- a/ext4_utils/sha1.c
+++ b/ext4_utils/sha1.c
@@ -17,7 +17,9 @@
 
 #define SHA1HANDSOFF		/* Copies data before messing with it. */
 
+#ifndef USE_MINGW
 #include <sys/cdefs.h>
+#endif
 #include <sys/types.h>
 #include <assert.h>
 #include <string.h>
diff --git a/ext4_utils/sha1.h b/ext4_utils/sha1.h
index 71334c8..9a8f7e3 100644
--- a/ext4_utils/sha1.h
+++ b/ext4_utils/sha1.h
@@ -9,10 +9,21 @@
 #ifndef _SYS_SHA1_H_
 #define	_SYS_SHA1_H_
 
-#include <sys/cdefs.h>
 #include <sys/types.h>
 #include <stdint.h>
 
+#ifdef USE_MINGW
+typedef unsigned char u_char;
+typedef unsigned int uint32_t;
+typedef unsigned int u_int32_t;
+typedef unsigned int u_int;
+
+#define __BEGIN_DECLS
+#define __END_DECLS
+#else
+#include <sys/cdefs.h>
+#endif
+
 #define SHA1_DIGEST_LENGTH		20
 #define SHA1_DIGEST_STRING_LENGTH	41
 
diff --git a/ext4_utils/uuid.c b/ext4_utils/uuid.c
index d518476..33d2494 100644
--- a/ext4_utils/uuid.c
+++ b/ext4_utils/uuid.c
@@ -15,7 +15,12 @@
  */
 
 #include <string.h>
+
+#ifdef USE_MINGW
+#include <winsock2.h>
+#else
 #include <arpa/inet.h>
+#endif
 
 #include "ext4_utils.h"
 #include "sha1.h"