Index: dir.c =================================================================== --- dir.c (revision 24594) +++ dir.c (working copy) @@ -892,6 +892,14 @@ #define dir_s_chroot rb_f_notimplement #endif +#ifndef pi_mkdir +static int dir_s_mkdir_internal(VALUE path, int mode) +{ + return mkdir(RSTRING_PTR(path), mode); +} +#define pi_mkdir(path, mode) dir_s_mkdir_internal(path, mode) +#endif + /* * call-seq: * Dir.mkdir( string [, integer] ) => 0 @@ -919,7 +927,7 @@ } check_dirname(&path); - if (mkdir(RSTRING_PTR(path), mode) == -1) + if (pi_mkdir(path, mode) == -1) rb_sys_fail(RSTRING_PTR(path)); return INT2FIX(0); Index: include/ruby/win32.h =================================================================== --- include/ruby/win32.h (revision 24594) +++ include/ruby/win32.h (working copy) @@ -164,8 +164,8 @@ #define isatty(h) rb_w32_isatty(h) #endif -#undef mkdir -#define mkdir(p, m) rb_w32_mkdir(p, m) +#undef pi_mkdir +#define pi_mkdir(p, m) rb_w32_mkdir(p, m) #undef rmdir #define rmdir(p) rb_w32_rmdir(p) #undef unlink @@ -273,7 +273,7 @@ #if !defined(__BORLANDC__) extern int rb_w32_isatty(int); #endif -extern int rb_w32_mkdir(const char *, int); +extern int rb_w32_mkdir(unsigned long, int); extern int rb_w32_rmdir(const char *); extern int rb_w32_unlink(const char *); extern int rb_w32_stati64(const char *, struct stati64 *); @@ -577,4 +577,4 @@ } /* extern "C" { */ #endif -#endif /* RUBY_WIN32_H */ +#endif /* RUBY_WIN32_H */ \ No newline at end of file Index: win32/win32.c =================================================================== --- win32/win32.c (revision 24594) +++ win32/win32.c (working copy) @@ -569,6 +569,20 @@ NtSocketsInitialized = 1; } +static rb_encoding * +w32_utf16(void) +{ + static rb_encoding *w32_utf16 = (rb_encoding *)-1; + + if (w32_utf16 == (rb_encoding *)-1) { + w32_utf16 = rb_enc_find("UTF-16LE"); + if (w32_utf16 == rb_ascii8bit_encoding()) + w32_utf16 = NULL; + } + + return w32_utf16; +} + // // Initialization stuff // @@ -5115,19 +5129,36 @@ } int -rb_w32_mkdir(const char *path, int mode) -{ +rb_w32_mkdir(VALUE path, int mode) +{ int ret = -1; - RUBY_CRITICAL(do { - if (CreateDirectory(path, NULL) == FALSE) { - errno = map_errno(GetLastError()); - break; - } - if (chmod(path, mode) == -1) { - RemoveDirectory(path); - break; - } - ret = 0; + + RUBY_CRITICAL(do { + if (w32_utf16()) { + VALUE wpath = rb_str_encode(path, rb_enc_from_encoding(w32_utf16()), 0, + Qnil); + rb_enc_str_buf_cat(wpath, "", 1, w32_utf16()); /* workaround */ + + if (CreateDirectoryW((WCHAR*) RSTRING_PTR(wpath), NULL) == FALSE) { + errno = map_errno(GetLastError()); + break; + } + if (_wchmod((WCHAR*) RSTRING_PTR(wpath), mode) == -1) { + RemoveDirectoryW((WCHAR*) RSTRING_PTR(wpath)); + break; + } + } + else { + if (CreateDirectory(RSTRING_PTR(path), NULL) == FALSE) { + errno = map_errno(GetLastError()); + break; + } + if (chmod(RSTRING_PTR(path), mode) == -1) { + RemoveDirectory(RSTRING_PTR(path)); + break; + } + } + ret = 0; } while (0)); return ret; }