Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 26984)
+++ include/ruby/intern.h	(working copy)
@@ -838,6 +838,10 @@
 void rb_frame_pop(void);
 int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
 
+#ifdef _WIN32
+int  w32_conv_to_utf16(volatile VALUE *strp);
+#endif
+
 #if defined(__cplusplus)
 #if 0
 { /* satisfy cc-mode */
Index: include/ruby/win32.h
===================================================================
--- include/ruby/win32.h	(revision 26984)
+++ include/ruby/win32.h	(working copy)
@@ -274,6 +274,7 @@
 extern int rb_w32_isatty(int);
 #endif
 extern int rb_w32_mkdir(const char *, int);
+extern int rb_w32_wmkdir(const WCHAR *, int);
 extern int rb_w32_rmdir(const char *);
 extern int rb_w32_unlink(const char *);
 extern int rb_w32_stati64(const char *, struct stati64 *);
Index: io.c
===================================================================
--- io.c	(revision 26984)
+++ io.c	(working copy)
@@ -4411,35 +4411,6 @@
 #endif
 };
 
-#ifdef _WIN32
-static rb_encoding *
-w32_utf16(void)
-{
-    static rb_encoding *utf16 = (rb_encoding *)-1;
-    if (utf16 == (rb_encoding *)-1) {
-	utf16 = rb_enc_find("UTF-16LE");
-	if (utf16 == rb_ascii8bit_encoding())
-	    utf16 = NULL;
-    }
-    return utf16;
-}
-
-static int
-w32_conv_to_utf16(volatile VALUE *strp)
-{
-    rb_encoding *utf16 = w32_utf16();
-    if (utf16) {
-	VALUE wstr = rb_str_encode(*strp, rb_enc_from_encoding(utf16), 0, Qnil);
-	rb_enc_str_buf_cat(wstr, "", 1, utf16); /* workaround */
-	*strp = wstr;
-	return 1;
-    }
-    else {
-	return 0;
-    }
-}
-#endif
-
 static VALUE
 sysopen_func(void *ptr)
 {
Index: dir.c
===================================================================
--- dir.c	(revision 26984)
+++ dir.c	(working copy)
@@ -937,6 +937,9 @@
 dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
 {
     VALUE path, vmode;
+#ifdef _WIN32
+    VALUE wpath;
+#endif
     int mode;
 
     if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
@@ -947,6 +950,15 @@
     }
 
     check_dirname(&path);
+#ifdef _WIN32
+    wpath = path;
+    if (w32_conv_to_utf16(&wpath) != 0) {
+	OBJ_FREEZE(wpath);
+	if (rb_w32_wmkdir((WCHAR *)RSTRING_PTR(wpath), mode) == -1)
+	    rb_sys_fail(RSTRING_PTR(path));
+    }
+    else
+#endif
     if (mkdir(RSTRING_PTR(path), mode) == -1)
 	rb_sys_fail(RSTRING_PTR(path));
 
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 26984)
+++ win32/win32.c	(working copy)
@@ -5162,6 +5162,24 @@
 }
 
 int
+rb_w32_wmkdir(const WCHAR *wpath, int mode)
+{
+    int ret = -1;
+    RUBY_CRITICAL(do {
+	if (CreateDirectoryW(wpath, NULL) == FALSE) {
+	    errno = map_errno(GetLastError());
+	    break;
+	}
+	if (_wchmod(wpath, mode) == -1) {
+	    RemoveDirectoryW(wpath);
+	    break;
+	}
+	ret = 0;
+    } while (0));
+    return ret;
+}
+
+int
 rb_w32_rmdir(const char *path)
 {
     int ret = 0;
@@ -5291,3 +5309,31 @@
     return *ip < 0;
 }
 #endif
+
+
+static rb_encoding *
+w32_utf16(void)
+{
+    static rb_encoding *utf16 = (rb_encoding *)-1;
+    if (utf16 == (rb_encoding *)-1) {
+	utf16 = rb_enc_find("UTF-16LE");
+	if (utf16 == rb_ascii8bit_encoding())
+	    utf16 = NULL;
+    }
+    return utf16;
+}
+
+int
+w32_conv_to_utf16(volatile VALUE *strp)
+{
+    rb_encoding *utf16 = w32_utf16();
+    if (utf16) {
+	VALUE wstr = rb_str_encode(*strp, rb_enc_from_encoding(utf16), 0, Qnil);
+	rb_enc_str_buf_cat(wstr, "", 1, utf16); /* workaround */
+	*strp = wstr;
+	return 1;
+    }
+    else {
+	return 0;
+    }
+}
 
