diff --git a/gio/gfile.c b/gio/gfile.c
index 1e03735..96b6af5 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -163,6 +163,12 @@ static void               g_file_real_read_async                  (GFile
 								   GCancellable           *cancellable,
 								   GAsyncReadyCallback     callback,
 								   gpointer                user_data);
+static void               g_file_real_read_async_with_flags       (GFile                  *file,
+                                                                   GFileReadFlags          flags,
+								   int                     io_priority,
+								   GCancellable           *cancellable,
+								   GAsyncReadyCallback     callback,
+								   gpointer                user_data);
 static GFileInputStream * g_file_real_read_finish                 (GFile                  *file,
 								   GAsyncResult           *res,
 								   GError                **error);
@@ -304,6 +310,7 @@ g_file_default_init (GFileIface *iface)
   iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
   iface->copy_async = g_file_real_copy_async;
   iface->copy_finish = g_file_real_copy_finish;
+  iface->read_async_with_flags = g_file_real_read_async_with_flags;
 }
 
 
@@ -1437,16 +1444,7 @@ g_file_find_enclosing_mount_finish (GFile         *file,
  * @cancellable: a #GCancellable
  * @error: a #GError, or %NULL
  *
- * Opens a file for reading. The result is a #GFileInputStream that
- * can be used to read the contents of the file.
- *
- * If @cancellable is not %NULL, then the operation can be cancelled by
- * triggering the cancellable object from another thread. If the operation
- * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
- * 
- * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
- * If the file is a directory, the G_IO_ERROR_IS_DIRECTORY error will be returned.
- * Other errors are possible too, and depend on what kind of filesystem the file is on.
+ * Opens a file for reading. See g_file_read_with_flags() for details.
  *
  * Returns: #GFileInputStream or %NULL on error.
  *     Free the returned object with g_object_unref().
@@ -1477,6 +1475,61 @@ g_file_read (GFile         *file,
 }
 
 /**
+ * g_file_read_with_flags:
+ * @file: #GFile to read.
+ * @flags: a set of #GFileReadFlags.
+ * @cancellable: a #GCancellable
+ * @error: a #GError, or %NULL
+ *
+ * Opens a file for reading. The result is a #GFileInputStream that
+ * can be used to read the contents of the file.
+ *
+ * The currently defined flags relate to share modes as supported by
+ * some file systems, mainly local file systems on Windows and the SMB
+ * (CIFS) network file protocol. They are interpreted as hints only:
+ * If an implementation doesn't support share modes, they are
+ * ignored. And even if an implementation does support share modes, it
+ * is left undefined whether they are mandatory or cooperative. If you
+ * need exact semantics, use platform-specific APIs.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
+ * 
+ * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
+ * If the file is a directory, the G_IO_ERROR_IS_DIRECTORY error will be returned.
+ * Other errors are possible too, and depend on what kind of filesystem the file is on.
+ *
+ * Returns: #GFileInputStream or %NULL on error.
+ *     Free the returned object with g_object_unref().
+ *
+ * Since: 2.26
+ **/
+GFileInputStream *
+g_file_read_with_flags (GFile         *file,
+                        GFileReadFlags flags,
+                        GCancellable  *cancellable,
+                        GError       **error)
+{
+  GFileIface *iface;
+  
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+  if (flags == 0)
+    return g_file_read (file, cancellable, error);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return NULL;
+
+  iface = G_FILE_GET_IFACE (file);
+
+  if (iface->read_with_flags == NULL)
+    return g_file_read (file, cancellable, error);
+  
+  return (* iface->read_with_flags) (file, flags, cancellable, error);
+}
+
+/**
  * g_file_append_to:
  * @file: input #GFile.
  * @flags: a set of #GFileCreateFlags.
@@ -1491,6 +1544,14 @@ g_file_read (GFile         *file,
  * will be made readable only to the current user, to the level that
  * is supported on the target filesystem.
  *
+ * Other flags relate to share modes as supported by some file systems,
+ * mainly local file systems on Windows and the SMB (CIFS) network
+ * file protocol. They are interpreted as hints only: If an
+ * implementation doesn't support share modes, they are ignored. And
+ * even if an implementation does support share modes, it is left
+ * undefined whether they are mandatory or cooperative. If you need
+ * exact semantics, use platform-specific APIs.
+ *
  * If @cancellable is not %NULL, then the operation can be cancelled by
  * triggering the cancellable object from another thread. If the operation
  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
@@ -1545,6 +1606,14 @@ g_file_append_to (GFile             *file,
  * will be made readable only to the current user, to the level that
  * is supported on the target filesystem.
  *
+ * Other flags relate to share modes as supported by some file systems,
+ * mainly local file systems on Windows and the SMB (CIFS) network
+ * file protocol. They are interpreted as hints only: If an
+ * implementation doesn't support share modes, they are ignored. And
+ * even if an implementation does support share modes, it is left
+ * undefined whether they are mandatory or cooperative. If you need
+ * exact semantics, use platform-specific APIs.
+ *
  * If @cancellable is not %NULL, then the operation can be cancelled by
  * triggering the cancellable object from another thread. If the operation
  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
@@ -1612,6 +1681,14 @@ g_file_create (GFile             *file,
  * will be made readable only to the current user, to the level that
  * is supported on the target filesystem.
  *
+ * Other flags relate to share modes as supported by some file systems,
+ * mainly local file systems on Windows and the SMB (CIFS) network
+ * file protocol. They are interpreted as hints only: If an
+ * implementation doesn't support share modes, they are ignored. And
+ * even if an implementation does support share modes, it is left
+ * undefined whether they are mandatory or cooperative. If you need
+ * exact semantics, use platform-specific APIs.
+ *
  * If @cancellable is not %NULL, then the operation can be cancelled by
  * triggering the cancellable object from another thread. If the operation
  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
@@ -1876,6 +1953,52 @@ g_file_read_async (GFile               *file,
 }
 
 /**
+ * g_file_read_async_with_flags:
+ * @file: input #GFile
+ * @flags: a set of #GFileReadFlags.
+ * @io_priority: the <link linkend="io-priority">I/O priority</link>
+ *     of the request.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to callback function
+ *
+ * Asynchronously opens @file for reading.
+ *
+ * For more details, see g_file_read_with_flags() which is
+ * the synchronous version of this call.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * g_file_read_finish() to get the result of the operation.
+ **/
+void
+g_file_read_async_with_flags (GFile               *file,
+                              GFileReadFlags       flags,
+                              int                  io_priority,
+                              GCancellable        *cancellable,
+                              GAsyncReadyCallback  callback,
+                              gpointer             user_data)
+{
+  GFileIface *iface;
+  
+  g_return_if_fail (G_IS_FILE (file));
+
+  iface = G_FILE_GET_IFACE (file);
+  if (iface->read_async_with_flags)
+    (* iface->read_async_with_flags) (file,
+                                      flags,
+                                      io_priority,
+                                      cancellable,
+                                      callback,
+                                      user_data);
+  else
+    (* iface->read_async) (file,
+                           io_priority,
+                           cancellable,
+                           callback,
+                           user_data);
+}
+
+/**
  * g_file_read_finish:
  * @file: input #GFile.
  * @res: a #GAsyncResult. 
@@ -5073,6 +5196,73 @@ g_file_real_read_async (GFile               *file,
   g_object_unref (res);
 }
 
+static void
+open_read_async_with_flags_thread (GSimpleAsyncResult *res,
+                                   GObject            *object,
+                                   GCancellable       *cancellable)
+{
+  GFileIface *iface;
+  GFileReadFlags *data;
+  GFileInputStream *stream;
+  GError *error = NULL;
+
+  iface = G_FILE_GET_IFACE (object);
+
+  if (iface->read_with_flags == NULL)
+    {
+      if (iface->read_fn == NULL)
+        {
+          g_set_error_literal (&error, G_IO_ERROR,
+                               G_IO_ERROR_NOT_SUPPORTED,
+                               _("Operation not supported"));
+          
+          g_simple_async_result_set_from_error (res, error);
+          g_error_free (error);
+
+          return;
+        }
+
+      data = g_simple_async_result_get_op_res_gpointer (res);
+
+      stream = iface->read_fn (G_FILE (object), cancellable, &error);
+    }
+  else
+    {
+      data = g_simple_async_result_get_op_res_gpointer (res);
+
+      stream = iface->read_with_flags (G_FILE (object), *data, cancellable, &error);
+    }
+
+  if (stream == NULL)
+    {
+      g_simple_async_result_set_from_error (res, error);
+      g_error_free (error);
+    }
+  else
+    g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
+}
+
+static void
+g_file_real_read_async_with_flags (GFile               *file,
+                                   GFileReadFlags       flags,
+                                   int                  io_priority,
+                                   GCancellable        *cancellable,
+                                   GAsyncReadyCallback  callback,
+                                   gpointer             user_data)
+{
+  GFileReadFlags *data;
+  GSimpleAsyncResult *res;
+  
+  data = g_new0 (GFileReadFlags, 1);
+  *data = flags;
+
+  res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
+  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
+  
+  g_simple_async_result_run_in_thread (res, open_read_async_with_flags_thread, io_priority, cancellable);
+  g_object_unref (res);
+}
+
 static GFileInputStream *
 g_file_real_read_finish (GFile         *file,
 			 GAsyncResult  *res,
diff --git a/gio/gfile.h b/gio/gfile.h
index 918f26a..15d9846 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -152,6 +152,8 @@ typedef struct _GFileIface    		GFileIface;
  * @eject_mountable_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
  * @poll_mountable: Polls a mountable object for media changes. Since 2.22.
  * @poll_mountable_finish: Finishes an poll operation for media changes. Since 2.22.
+ * @read_with_flags: Reads a file, providing a flags argument.
+ * @read_async_with_flags: Reads a file asynchronously, providing a flags argument.
  *
  * An interface for writing VFS file handles.
  **/
@@ -543,6 +545,16 @@ struct _GFileIface
   gboolean            (* poll_mountable_finish)       (GFile                *file,
                                                        GAsyncResult         *result,
                                                        GError              **error);
+  GFileInputStream *  (* read_with_flags)             (GFile                *file,
+                                                       GFileReadFlags        flags,
+                                                       GCancellable         *cancellable,
+                                                       GError              **error);
+  void                (* read_async_with_flags)       (GFile                *file,
+                                                       GFileReadFlags        flags,
+                                                       int                   io_priority,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
 };
 
 GType                   g_file_get_type                   (void) G_GNUC_CONST;
@@ -580,11 +592,21 @@ char *                  g_file_get_uri_scheme             (GFile
 GFileInputStream *      g_file_read                       (GFile                      *file,
 							   GCancellable               *cancellable,
 							   GError                    **error);
+GFileInputStream *      g_file_read_with_flags            (GFile                      *file,
+							   GFileReadFlags              flags,
+							   GCancellable               *cancellable,
+							   GError                    **error);
 void                    g_file_read_async                 (GFile                      *file,
 							   int                         io_priority,
 							   GCancellable               *cancellable,
 							   GAsyncReadyCallback         callback,
 							   gpointer                    user_data);
+void                    g_file_read_async_with_flags      (GFile                      *file,
+							   GFileReadFlags              flags,
+							   int                         io_priority,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
 GFileInputStream *      g_file_read_finish                (GFile                      *file,
 							   GAsyncResult               *res,
 							   GError                    **error);
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 3f61cff..629da3e 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -324,7 +324,9 @@ g_file_is_native
 g_file_has_uri_scheme
 g_file_get_uri_scheme
 g_file_read
+g_file_read_with_flags
 g_file_read_async
+g_file_read_async_with_flags
 g_file_read_finish
 g_file_append_to
 g_file_create
diff --git a/gio/gioenums.h b/gio/gioenums.h
index efd08d5..c89a5b6 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -200,15 +200,38 @@ typedef enum {
  *    You can think of it as "unlink destination" before
  *    writing to it, although the implementation may not
  *    be exactly like that. Since 2.20
+ * @G_FILE_CREATE_WITH_SHARE_MODE: A share mode hint is included in the flags.
+ * @G_FILE_CREATE_SHARE_NONE: No shared access.
+ * @G_FILE_CREATE_SHARE_READ: Shared read access.
+ * @G_FILE_CREATE_SHARE_WRITE: Shared write access.
  *
  * Flags used when an operation may create a file.
  */
 typedef enum {
   G_FILE_CREATE_NONE    = 0,
   G_FILE_CREATE_PRIVATE = (1 << 0),
-  G_FILE_CREATE_REPLACE_DESTINATION = (1 << 1)
+  G_FILE_CREATE_REPLACE_DESTINATION = (1 << 1),
+  G_FILE_CREATE_WITH_SHARE_MODE = (1 << 2),
+  G_FILE_CREATE_SHARE_NONE = 0,
+  G_FILE_CREATE_SHARE_READ = (1 << 3),
+  G_FILE_CREATE_SHARE_WRITE = (1 << 4)
 } GFileCreateFlags;
 
+/**
+ * GFileReadFlags:
+ * @G_FILE_READ_WITH_SHARE_MODE: A share mode hint is included in the flags.
+ * @G_FILE_CREATE_SHARE_NONE: No shared access.
+ * @G_FILE_CREATE_SHARE_READ: Shared read access.
+ * @G_FILE_CREATE_SHARE_WRITE: Shared write access.
+ *
+ * Flags used when an operation opens an existing file.
+ */
+typedef enum {
+  G_FILE_READ_WITH_SHARE_MODE = (1 << 0),
+  G_FILE_READ_SHARE_NONE = 0,
+  G_FILE_READ_SHARE_READ = (1 << 1),
+  G_FILE_READ_SHARE_WRITE = (1 << 2)
+} GFileReadFlags;
 
 /**
  * GMountMountFlags:
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 57dad07..d602212 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -91,6 +91,7 @@
 #define _WIN32_WINNT 0x0500
 #include <windows.h>
 #include <io.h>
+#include <share.h>
 #include <direct.h>
 
 #ifndef FILE_READ_ONLY_VOLUME
@@ -109,6 +110,11 @@
 
 static void g_local_file_file_iface_init (GFileIface *iface);
 
+static GFileInputStream *g_local_file_read_with_flags (GFile         *file,
+						       GFileReadFlags flags,
+						       GCancellable  *cancellable,
+						       GError       **error);
+
 static GFileAttributeInfoList *local_writable_attributes = NULL;
 static /* GFileAttributeInfoList * */ gsize local_writable_namespaces = 0;
 
@@ -1295,11 +1301,52 @@ g_local_file_read (GFile         *file,
 		   GCancellable  *cancellable,
 		   GError       **error)
 {
+  return g_local_file_read_with_flags (file, 0, cancellable, error);
+}
+
+static GFileInputStream *
+g_local_file_read_with_flags (GFile         *file,
+			      GFileReadFlags flags,
+			      GCancellable  *cancellable,
+			      GError       **error)
+{
   GLocalFile *local = G_LOCAL_FILE (file);
   int fd;
   struct stat buf;
   
+#ifdef G_OS_WIN32
+  if (flags & G_FILE_READ_WITH_SHARE_MODE)
+    {
+      int shflag = _SH_DENYRW;
+      wchar_t *wfilename = g_utf8_to_utf16 (local->filename, -1, NULL, NULL, NULL);
+      int save_errno;
+
+      if (wfilename == NULL)
+	{
+	  errno = EINVAL;
+	  fd = -1;
+	}
+      else
+	{
+	  if ((flags & (G_FILE_READ_SHARE_READ|G_FILE_READ_SHARE_WRITE)) == (G_FILE_READ_SHARE_READ|G_FILE_READ_SHARE_WRITE))
+	    shflag = _SH_DENYNO;
+	  else if ((flags & (G_FILE_READ_SHARE_READ|G_FILE_READ_SHARE_WRITE)) == G_FILE_READ_SHARE_READ)
+	    shflag = _SH_DENYWR;
+	  else if ((flags & (G_FILE_READ_SHARE_READ|G_FILE_READ_SHARE_WRITE)) == G_FILE_READ_SHARE_WRITE)
+	    shflag = _SH_DENYRD;
+
+	  fd = _wsopen (wfilename, O_RDONLY|O_BINARY, shflag);
+	  save_errno = errno;
+	  g_free (wfilename);
+	  errno = save_errno;
+	}
+    }
+  else
+    fd = g_open (local->filename, O_RDONLY|O_BINARY, 0);
+#else
   fd = g_open (local->filename, O_RDONLY|O_BINARY, 0);
+#endif
+
   if (fd == -1)
     {
       int errsv = errno;
@@ -1319,7 +1366,7 @@ g_local_file_read (GFile         *file,
                            _("Can't open directory"));
       return NULL;
     }
-  
+
   return _g_local_file_input_stream_new (fd);
 }
 
@@ -1454,6 +1501,8 @@ g_local_file_delete (GFile         *file,
   return TRUE;
 }
 
+#ifndef G_OS_WIN32
+
 static char *
 strip_trailing_slashes (const char *path)
 {
@@ -1578,8 +1627,6 @@ expand_all_symlinks (const char *path)
   return res;
 }
 
-#ifndef G_OS_WIN32
-
 static char *
 find_mountpoint_for (const char *file, 
                      dev_t       dev)
@@ -2401,6 +2448,7 @@ g_local_file_file_iface_init (GFileIface *iface)
   iface->move = g_local_file_move;
   iface->monitor_dir = g_local_file_monitor_dir;
   iface->monitor_file = g_local_file_monitor_file;
+  iface->read_with_flags = g_local_file_read_with_flags;
 
   iface->supports_thread_contexts = TRUE;
 }
diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
index 7916b03..2b71458 100644
--- a/gio/glocalfileoutputstream.c
+++ b/gio/glocalfileoutputstream.c
@@ -45,6 +45,7 @@
 
 #ifdef G_OS_WIN32
 #include <io.h>
+#include <share.h>
 #ifndef S_ISDIR
 #define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
 #endif
@@ -585,6 +586,25 @@ _g_local_file_output_stream_open  (const char        *filename,
   return G_FILE_OUTPUT_STREAM (stream);
 }
 
+#ifdef G_OS_WIN32
+
+static int
+win32_share_to_deny_mode (GFileCreateFlags flags)
+{
+  int share_flags = _SH_DENYRW;
+
+  if ((flags & (G_FILE_CREATE_SHARE_READ|G_FILE_CREATE_SHARE_WRITE)) == (G_FILE_CREATE_SHARE_READ|G_FILE_CREATE_SHARE_WRITE))
+    share_flags = _SH_DENYNO;
+  else if ((flags & (G_FILE_CREATE_SHARE_READ|G_FILE_CREATE_SHARE_WRITE)) == G_FILE_CREATE_SHARE_READ)
+    share_flags = _SH_DENYWR;
+  else if ((flags & (G_FILE_CREATE_SHARE_READ|G_FILE_CREATE_SHARE_WRITE)) == G_FILE_CREATE_SHARE_WRITE)
+    share_flags = _SH_DENYRD;
+
+  return share_flags;
+}
+
+#endif
+
 GFileOutputStream *
 _g_local_file_output_stream_create  (const char        *filename,
 				     gboolean          readable,
@@ -611,7 +631,33 @@ _g_local_file_output_stream_create  (const char        *filename,
   else
     open_flags |= O_WRONLY;
 
+#ifdef G_OS_WIN32
+  if (flags & G_FILE_CREATE_WITH_SHARE_MODE)
+    {
+      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+      int save_errno;
+
+      if (wfilename == NULL)
+	{
+	  errno = EINVAL;
+	  fd = -1;
+	}
+      else
+	{
+	  int share_flags = win32_share_to_deny_mode (flags);
+
+	  fd = _wsopen (wfilename, open_flags, share_flags, mode);
+	  save_errno = errno;
+	  g_free (wfilename);
+	  errno = save_errno;
+	}
+    }
+  else
+    fd = g_open (filename, open_flags, mode);
+#else
   fd = g_open (filename, open_flags, mode);
+#endif
+
   if (fd == -1)
     {
       int errsv = errno;
@@ -656,7 +702,33 @@ _g_local_file_output_stream_append  (const char        *filename,
   else
     mode = 0666;
 
+#ifdef G_OS_WIN32
+  if (flags & G_FILE_CREATE_WITH_SHARE_MODE)
+    {
+      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+      int save_errno;
+
+      if (wfilename == NULL)
+	{
+	  errno = EINVAL;
+	  fd = -1;
+	}
+      else
+	{
+	  int share_flags = win32_share_to_deny_mode (flags);
+
+	  fd = _wsopen (wfilename, O_CREAT | O_APPEND | O_WRONLY | O_BINARY, share_flags, mode);
+	  save_errno = errno;
+	  g_free (wfilename);
+	  errno = save_errno;
+	}
+    }
+  else
+    fd = g_open (filename, O_CREAT | O_APPEND | O_WRONLY | O_BINARY, mode);
+#else
   fd = g_open (filename, O_CREAT | O_APPEND | O_WRONLY | O_BINARY, mode);
+#endif
+
   if (fd == -1)
     {
       int errsv = errno;
@@ -800,7 +872,33 @@ handle_overwrite_open (const char    *filename,
       fd = g_open (filename, open_flags, mode);
     }
 #else
+
+#ifdef G_OS_WIN32
+  if (flags & G_FILE_CREATE_WITH_SHARE_MODE)
+    {
+      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+      int save_errno;
+
+      if (wfilename == NULL)
+	{
+	  errno = EINVAL;
+	  fd = -1;
+	}
+      else
+	{
+	  int share_flags = win32_share_to_deny_mode (flags);
+
+	  fd = _wsopen (wfilename, open_flags, share_flags, mode);
+	  save_errno = errno;
+	  g_free (wfilename);
+	  errno = save_errno;
+	}
+    }
+  else
+    fd = g_open (filename, open_flags, mode);
+#else
   fd = g_open (filename, open_flags, mode);
+#endif
   /* This is racy, but we do it as soon as possible to minimize the race */
   is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
 #endif
@@ -1120,7 +1218,33 @@ _g_local_file_output_stream_replace (const char        *filename,
     open_flags |= O_RDWR;
   else
     open_flags |= O_WRONLY;
+
+#ifdef G_OS_WIN32
+  if (flags & G_FILE_CREATE_WITH_SHARE_MODE)
+    {
+      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+      int save_errno;
+
+      if (wfilename == NULL)
+	{
+	  errno = EINVAL;
+	  fd = -1;
+	}
+      else
+	{
+	  int share_flags = win32_share_to_deny_mode (flags);
+
+	  fd = _wsopen (wfilename, open_flags, share_flags, mode);
+	  save_errno = errno;
+	  g_free (wfilename);
+	  errno = save_errno;
+	}
+    }
+  else
+    fd = g_open (filename, open_flags, mode);
+#else
   fd = g_open (filename, open_flags, mode);
+#endif
 
   if (fd == -1 && errno == EEXIST)
     {
