mke2fs, libext2fs: fix bugs on windows

Added O_BINARY to open output files on windows, otherwise they're
written as text files and have invalid data.

Use '(filename):block_count:block_size' for sparse file name because
windows file name can contain ':', e.g. 'c:\output_file'.

Bug: 23686092

Change-Id: I731c13e5df0be8c831464c431b8949d33438fb24
(cherry picked from commit 0dcf8ec6a429ce4f024fe7838fee2d5636e8ba4d)
diff --git a/contrib/android/e2fsdroid.c b/contrib/android/e2fsdroid.c
index 1ae133d..223ea68 100644
--- a/contrib/android/e2fsdroid.c
+++ b/contrib/android/e2fsdroid.c
@@ -118,9 +118,17 @@
 		fprintf(stderr, "Expected filename after options\n");
 		exit(EXIT_FAILURE);
 	}
-	in_file = strdup(argv[optind]);
 
-	io_mgr = android_sparse_file ? sparse_io_manager: unix_io_manager;
+	if (android_sparse_file) {
+		io_mgr = sparse_io_manager;
+		if (asprintf(&in_file, "(%s)", argv[optind]) == -1) {
+			fprintf(stderr, "Failed to allocate file name\n");
+			exit(EXIT_FAILURE);
+		}
+	} else {
+		io_mgr = unix_io_manager;
+		in_file = strdup(argv[optind]);
+	}
 	retval = ext2fs_open(in_file, flags, 0, 0, io_mgr, &fs);
 	if (retval) {
 		com_err(prog_name, retval, "while opening file %s\n", in_file);
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 32f4321..99fedcd 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -28,6 +28,10 @@
 #include "ext2_fs.h"
 #include "ext2fs.h"
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 #if defined(__linux__)    &&	defined(EXT2_OS_LINUX)
 #define CREATOR_OS EXT2_OS_LINUX
 #else
@@ -124,6 +128,7 @@
 		io_flags |= IO_FLAG_EXCLUSIVE;
 	if (flags & EXT2_FLAG_DIRECT_IO)
 		io_flags |= IO_FLAG_DIRECT_IO;
+	io_flags |= O_BINARY;
 	retval = manager->open(name, io_flags, &fs->io);
 	if (retval)
 		goto cleanup;
diff --git a/lib/ext2fs/sparse_io.c b/lib/ext2fs/sparse_io.c
index a307859..a83baf1 100644
--- a/lib/ext2fs/sparse_io.c
+++ b/lib/ext2fs/sparse_io.c
@@ -7,6 +7,10 @@
 #include "ext2_fs.h"
 #include "ext2fs.h"
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 #if !defined(ENABLE_LIBSPARSE)
 static errcode_t sparse_open(const char *name EXT2FS_ATTR((unused)),
 			     int flags EXT2FS_ATTR((unused)),
@@ -155,7 +159,7 @@
 			goto err_alloc;
 		}
 		if (params->fd < 0) {
-			sm->fd = open(params->file, O_CREAT | O_RDWR | O_TRUNC,
+			sm->fd = open(params->file, O_CREAT | O_RDWR | O_TRUNC | O_BINARY,
 				      0644);
 			if (sm->fd < 0) {
 				retval = errno;
@@ -206,11 +210,11 @@
 	}
 
 	if (is_fd) {
-		ret = sscanf(name, "%d:%llu:%u", &sparse_params->fd,
+		ret = sscanf(name, "(%d):%llu:%u", &sparse_params->fd,
 			     (unsigned long long *)&sparse_params->blocks_count,
 			     &sparse_params->block_size);
 	} else {
-		ret = sscanf(name, "%[^:]%*[:]%llu%*[:]%u", sparse_params->file,
+		ret = sscanf(name, "(%[^)])%*[:]%llu%*[:]%u", sparse_params->file,
 			     (unsigned long long *)&sparse_params->blocks_count,
 			     &sparse_params->block_size);
 	}
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 4d12947..0fa72f7 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -2820,7 +2820,7 @@
 				_("in malloc for android_sparse_params"));
 			exit(1);
 		}
-		snprintf(android_sparse_params, PATH_MAX + 32, "%s:%u:%u",
+		snprintf(android_sparse_params, PATH_MAX + 32, "(%s):%u:%u",
 			 device_name, fs_param.s_blocks_count,
 			 1024 << fs_param.s_log_block_size);
 		retval = ext2fs_initialize(android_sparse_params, flags,