diff -ru glib2.0-2.18.2-orig/glib/goption.c glib2.0-2.18.2/glib/goption.c
--- glib2.0-2.18.2-orig/glib/goption.c	2008-10-16 16:31:58.000000000 +0200
+++ glib2.0-2.18.2/glib/goption.c	2008-12-24 20:41:31.000000000 +0100
@@ -33,6 +33,12 @@
 #include <stdio.h>
 #include <errno.h>
 
+#ifdef G_OS_WIN32
+#define STRICT
+#include <windows.h>
+#undef STRICT
+#endif
+
 #define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str)))
 
 #define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE ||       \
@@ -1002,11 +1008,17 @@
     case G_OPTION_ARG_STRING:
       {
 	gchar *data;
-	
+#ifdef G_OS_WIN32
+	data = g_strdup (value);
+#else
 	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
 
 	if (!data)
 	  return FALSE;
+#endif
+
+	if (!data)
+	  return FALSE;
 
 	change = get_change (context, G_OPTION_ARG_STRING,
 			     entry->arg_data);
@@ -1021,11 +1033,17 @@
     case G_OPTION_ARG_STRING_ARRAY:
       {
 	gchar *data;
-
+#ifdef G_OS_WIN32
+	data = g_strdup (value);
+#else
 	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
 
 	if (!data)
 	  return FALSE;
+#endif
+
+	if (!data)
+	  return FALSE;
 
 	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
 			     entry->arg_data);
@@ -1054,14 +1072,8 @@
       {
 	gchar *data;
 
-#ifdef G_OS_WIN32
-	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
-	
-	if (!data)
-	  return FALSE;
-#else
 	data = g_strdup (value);
-#endif
+
 	change = get_change (context, G_OPTION_ARG_FILENAME,
 			     entry->arg_data);
 	g_free (change->allocated.str);
@@ -1077,14 +1089,8 @@
       {
 	gchar *data;
 	
-#ifdef G_OS_WIN32
-	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
-	
-	if (!data)
-	  return FALSE;
-#else
 	data = g_strdup (value);
-#endif
+
 	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
 			     entry->arg_data);
 
@@ -1134,14 +1140,19 @@
 	  data = NULL;
 	else if (entry->flags & G_OPTION_FLAG_FILENAME)
 	  {
+	    data = g_strdup (value);
+	  }
+	else
+	  {
 #ifdef G_OS_WIN32
-  	    data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
-#else
 	    data = g_strdup (value);
+#else
+	    data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+	    if (!data)
+	      return FALSE;
 #endif
 	  }
-	else
-	  data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
 
 	if (!(entry->flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG)) && 
 	    !data)
@@ -1502,6 +1513,69 @@
   context->pending_nulls = NULL;
 }
 
+#ifdef G_OS_WIN32
+/* Returns a newly allocated argument vector converted to UTF-8. Tries to use
+ * the process's Unicode command line if possible. */
+static gchar **
+prepare_utf8_argv (const gint    *argc,
+		   const gchar ***argv)
+{
+  gint unicode_argc, i, j, original_argc = __argc;
+  gchar **replacement_argv = NULL, **original_argv = __argv;
+  gchar **unicode_argv = (gchar **) CommandLineToArgvW (GetCommandLineW (), &unicode_argc);
+
+  if (G_UNLIKELY (!unicode_argv))
+    return NULL;
+
+  if (argc && argv)
+    {
+      gboolean argv_comes_from_main = ( *argv == original_argv &&
+					*argc == original_argc &&
+					*argc == unicode_argc );
+
+      /* build a replacement UTF-8 argument vector */
+      replacement_argv = g_malloc0 (*argc * sizeof (gchar*));
+
+      for (i = 0; i < *argc; ++i)
+	{
+	  /* If argv comes from the parameters of main(), convert the Unicode
+	   * command line, ignoring contents of argv */
+	  if (argv_comes_from_main)
+	    replacement_argv[i] = g_convert (unicode_argv[i], wcslen (unicode_argv[i]) * 2,
+					     "UTF-8", "UTF-16", NULL, NULL, NULL);
+	  else
+	    {
+	      /* If argv doesn't come from main(), check whether any
+	       * of the argument pointers are identical; if they are, convert
+	       * the corresponding Unicode argument */
+	      for (j = 0; j < unicode_argc; ++j)
+		{
+		  if ((*argv)[i] == original_argv[j])
+		    {
+		      replacement_argv[i] = g_convert (unicode_argv[j], wcslen (unicode_argv[j]) * 2,
+						       "UTF-8", "UTF-16", NULL, NULL, NULL);
+		      break;
+		    }
+		}
+	      if (!replacement_argv[i])
+		replacement_argv[i] =  g_locale_to_utf8 ((*argv)[i], -1, NULL, NULL, NULL);
+	    }
+
+	  if (G_UNLIKELY (!replacement_argv[i]))
+	    {
+	      /* clean up after conversion attempt */
+	      for (j = 0; j < i; ++j)
+		g_free (replacement_argv[j]);
+
+	      g_free (replacement_argv);
+	      return NULL;
+	    }
+	}
+    }
+  return replacement_argv;
+}
+#endif
+
 /**
  * g_option_context_parse:
  * @context: a #GOptionContext
@@ -1527,11 +1601,25 @@
  * this function will produce help output to stdout and
  * call <literal>exit (0)</literal>.
  *
- * Note that function depends on the 
+ * On Windows, some filenames may not be representable in the
+ * system codepage. This will cause the arguments of main()
+ * to contain broken filenames. To fix them, the original
+ * Unicode command line retrieved using <literal>GetCommandLineW</literal>
+ * is looked up. If @argc and @argv point to arguments of main(),
+ * and the Unicode command line has the same argument count,
+ * the Unicode command line is used. Otherwise, @argv and @argc
+ * are used, but when a <type>char</type> pointer in @argv is
+ * the same as in the argument of main(), the corresponding
+ * Unicode argument is used instead. Effectively, this means that
+ * this function will not behave correctly on Windows if you modify
+ * the arguments of main(). Use copies of them if you want to
+ * manipulate them in some way before parsing with this function.
+ *
+ * Note that the function depends on the 
  * <link linkend="setlocale">current locale</link> for 
  * automatic character set conversion of string and filename
- * arguments.
- * 
+ * arguments - it assumes that @argv is in locale encoding.
+ *
  * Return value: %TRUE if the parsing was successful, 
  *               %FALSE if an error occurred
  *
@@ -1546,6 +1634,22 @@
   gint i, j, k;
   GList *list;
 
+#ifdef G_OS_WIN32
+  gchar ***passed_argv = argv;
+
+  if (argc && argv)
+    {
+      gchar **replacement_argv = prepare_utf8_argv (argc, argv);
+      if (!replacement_argv)
+	{
+	  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+		       "Failed to convert the command line to UTF-8");
+	  goto fail;
+	}
+      argv = &replacement_argv;
+    }
+#endif
+
   /* Set program name */
   if (!g_get_prgname())
     {
@@ -1831,6 +1935,12 @@
 	}      
     }
 
+#ifdef G_OS_WIN32
+  /* return unparsed arguments */
+  if (argc && passed_argv)
+    *passed_argv = *argv;
+#endif
+
   return TRUE;
 
  fail:
