2.5のマルチバイトパス対策パッチ

とりあえずできた。
外部とのアクセスの前後でutf8とローカルの文字コードとを変換するようにした。FindFirstFile, FindNextFile, stat, chdir, gzopenあたりのファイルパスを引数に取る関数や、SHGetSpecialFolderPathなどのパスを返す関数が対象。
内部をutf8で統一して出入り口を押さえるのがいいと思う。もう少しバージョンが進んで外部フォント指定のインターフェースが公開されたら送ってみようかな。

Index: blender/blenkernel/intern/exotic.c
===================================================================
--- blender/blenkernel/intern/exotic.c	(revision 27274)
+++ blender/blenkernel/intern/exotic.c	(working copy)
@@ -1777,6 +1777,9 @@
 
 }
 
+#ifdef WIN32
+#include <windows.h>
+#endif
 int BKE_read_exotic(Scene *scene, char *name)
 {
 	ListBase lbase={0, 0};
@@ -1790,6 +1793,18 @@
 
 	len= strlen(name);
 	if (name[len-1] !='/' && name[len-1] != '\\') {
+#ifdef WIN32
+		{
+			// utf8 to local encoding
+			wchar_t unicode[MAX_PATH];
+			char oem[MAX_PATH];
+			int size;
+			size=MultiByteToWideChar(CP_UTF8, 0, name, -1, unicode, MAX_PATH);
+			size=WideCharToMultiByte(CP_OEMCP, 0, unicode, size, 
+					oem, MAX_PATH, 0, NULL);
+			strcpy(name, oem);
+		}
+#endif
 		gzfile = gzopen(name,"rb");
 
 		if (NULL == gzfile ) {
Index: blender/blenlib/BLI_winstuff.h
===================================================================
--- blender/blenlib/BLI_winstuff.h	(revision 27274)
+++ blender/blenlib/BLI_winstuff.h	(working copy)
@@ -86,7 +86,7 @@
 #define write _write
 #define read _read
 #define getcwd _getcwd
-#define chdir _chdir
+//#define chdir _chdir
 #define strdup _strdup
 #define lseek _lseek
 #define getpid _getpid
@@ -115,8 +115,8 @@
 
 typedef struct _DIR {
 	HANDLE handle;
-	WIN32_FIND_DATA data;
-	char path[MAX_PATH];
+	WIN32_FIND_DATAW data;
+	wchar_t path[MAX_PATH];
 	long dd_loc;
 	long dd_size;
 	char dd_buf[4096];
@@ -132,6 +132,8 @@
 void get_default_root(char *root);
 int check_file_chars(char *filename);
 char *dirname(char *path);
+int BLI_chdir(const char *dirname);
+int BLI_stat(const char *path, struct _stat64 *buf);
 
 #ifdef WIN32
 int BLI_getInstallationDir(char *str);
Index: blender/blenlib/intern/storage.c
===================================================================
--- blender/blenlib/intern/storage.c	(revision 27274)
+++ blender/blenlib/intern/storage.c	(working copy)
@@ -80,6 +80,8 @@
 #include <io.h>
 #include <direct.h>
 #include "BLI_winstuff.h"
+//#include <shlwapi.h>
+#pragma comment(lib, "shlwapi")
 #endif
 
 
@@ -228,7 +230,11 @@
 		rellen++;
 	}
 
+#ifdef WIN32
+	if (BLI_chdir(dirname) == -1){
+#else
 	if (chdir(dirname) == -1){
+#endif
 		perror(dirname);
 		return;
 	}
@@ -264,11 +270,13 @@
 					files[actnum].path = BLI_strdupcat(dirname, dlink->name);
 // use 64 bit file size, only needed for WIN32 and WIN64. 
 // Excluding other than current MSVC compiler until able to test.
-#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500)
-					_stat64(dlink->name,&files[actnum].s);
+// move to winstuff
+#ifdef WIN32
+					BLI_stat(dlink->name,&files[actnum].s);
 #else
 					stat(dlink->name,&files[actnum].s);
 #endif
+
 					files[actnum].type=files[actnum].s.st_mode;
 					files[actnum].flags = 0;
 					totnum++;
@@ -449,25 +457,16 @@
 	return size;
 }
 
-
+#ifndef WIN32
 int BLI_exist(char *name)
 {
 	struct stat st;
-#ifdef WIN32
-	/*  in Windows stat doesn't recognize dir ending on a slash 
-		To not break code where the ending slash is expected we
-		don't mess with the argument name directly here - elubie */
-	char tmp[FILE_MAXDIR+FILE_MAXFILE];
-	int len;
-	BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
-	len = strlen(tmp);
-	if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
-	if (stat(tmp,&st)) return(0);
-#else
-	if (stat(name,&st)) return(0);	
-#endif
+	if (stat(name,&st)){
+	 	return(0);
+	}
 	return(st.st_mode);
 }
+#endif
 
 /* would be better in fileops.c except that it needs stat.h so add here */
 int BLI_is_dir(char *file) {
Index: blender/blenlib/intern/winstuff.c
===================================================================
--- blender/blenlib/intern/winstuff.c	(revision 27274)
+++ blender/blenlib/intern/winstuff.c	(working copy)
@@ -28,6 +28,8 @@
  * Windows-posix compatibility layer, windows-specific functions.
  */
 
+#include <shlwapi.h>
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -98,22 +100,33 @@
 
 DIR *opendir (const char *path) {
 	if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) {
+		int size;
+
 		DIR *newd= MEM_mallocN(sizeof(DIR), "opendir");
 
 		newd->handle = INVALID_HANDLE_VALUE;
-		sprintf(newd->path, "%s\\*",path);
-		
+		size=MultiByteToWideChar(CP_UTF8, 0, path, -1, newd->path, MAX_PATH);
+		newd->path[size-1]=L'\\';
+		newd->path[size]=L'*';
+		newd->path[size+1]=0;
 		newd->direntry.d_ino= 0;
 		newd->direntry.d_off= 0;
 		newd->direntry.d_reclen= 0;
 		newd->direntry.d_name= NULL;
-		
+
 		return newd;
 	} else {
 		return NULL;
 	}
 }
 
+static char* BLI_strdup_wide2utf8(const wchar_t *unicode) {
+	char utf8[MAX_PATH*2];
+	int size;
+	size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, MAX_PATH*2, 0, NULL);
+	return BLI_strdup(utf8);
+}
+
 struct dirent *readdir(DIR *dp) {
 	if (dp->direntry.d_name) {
 		MEM_freeN(dp->direntry.d_name);
@@ -121,15 +134,15 @@
 	}
 		
 	if (dp->handle==INVALID_HANDLE_VALUE) {
-		dp->handle= FindFirstFile(dp->path, &(dp->data));
+		dp->handle= FindFirstFileW(dp->path, &(dp->data));
 		if (dp->handle==INVALID_HANDLE_VALUE)
 			return NULL;
 			
-		dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
+		dp->direntry.d_name= BLI_strdup_wide2utf8(dp->data.cFileName);
 
 		return &dp->direntry;
-	} else if (FindNextFile (dp->handle, &(dp->data))) {
-		dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
+	} else if (FindNextFileW(dp->handle, &(dp->data))) {
+		dp->direntry.d_name= BLI_strdup_wide2utf8(dp->data.cFileName);
 
 		return &dp->direntry;
 	} else {
@@ -243,6 +256,46 @@
 }
 /* End of copied part */
 
+#include <sys/stat.h>
+int BLI_stat(const char *path, struct _stat64 *buf)
+{
+	wchar_t unicode[MAX_PATH];
+	int size;
+	size=MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, 
+			path, -1, unicode, MAX_PATH);
+	return _wstat64(unicode, buf);
+}
+
+#include <direct.h>
+int BLI_chdir(const char *path)
+{
+	wchar_t unicode[MAX_PATH];
+	int size;
+	size=MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, 
+			path, -1, unicode, MAX_PATH);
+	return _wchdir(unicode);
+}
+
+int BLI_exist(char *name)
+{
+	wchar_t unicode[MAX_PATH];
+	int size;
+	struct  _stat64 st;
+	size=MultiByteToWideChar(CP_UTF8, 0, name, -1, unicode, MAX_PATH);
+	if(size==4 && unicode[1]==L':'){
+		// C:/, D:/...
+	}
+	else if(size>3 && unicode[size-2]==0x005c){ // '\\'
+		unicode[size-2]=0x0000;
+	}
+
+	if(_wstat64(unicode, &st)){
+		return 0;
+	}
+	return st.st_mode;
+}
+
+
 #else
 
 /* intentionally empty for UNIX */
Index: blender/blenfont/intern/blf.c
===================================================================
--- blender/blenfont/intern/blf.c	(revision 27274)
+++ blender/blenfont/intern/blf.c	(working copy)
@@ -298,7 +298,7 @@
 		global_font_default= blf_search("default");
 
 	if (global_font_default == -1) {
-		printf("Warning: Can't found default font!!\n");
+		//printf("Warning: Can't found default font!!\n");
 		return;
 	}
 
Index: blender/editors/space_file/fsmenu.c
===================================================================
--- blender/editors/space_file/fsmenu.c	(revision 27274)
+++ blender/editors/space_file/fsmenu.c	(working copy)
@@ -258,7 +258,9 @@
 	/* Add the drive names to the listing */
 	{
 		__int64 tmp;
-		char folder[256];
+		wchar_t unicode[256];
+		char folder[1024];
+		int size;
 		char tmps[4];
 		int i;
 			
@@ -276,9 +278,12 @@
 		}
 
 		/* Adding Desktop and My Documents */
-		SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
+		SHGetSpecialFolderPathW(0, unicode, CSIDL_PERSONAL, 0);
+		size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, folder, 1024, 0, NULL);
 		fsmenu_insert_entry(fsmenu,FS_CATEGORY_BOOKMARKS, folder, 1, 0);
-		SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
+
+		SHGetSpecialFolderPathW(0, unicode, CSIDL_DESKTOPDIRECTORY, 0);
+		size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, folder, 1024, 0, NULL);
 		fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, folder, 1, 0);
 	}
 #else
Index: blender/editors/interface/interface_style.c
===================================================================
--- blender/editors/interface/interface_style.c	(revision 27274)
+++ blender/editors/interface/interface_style.c	(working copy)
@@ -270,14 +270,18 @@
 	
 	/* recover from uninitialized dpi */
 	CLAMP(U.dpi, 72, 240);
-	
+
 	/* default builtin */
 	if(font==NULL) {
 		font= MEM_callocN(sizeof(uiFont), "ui font");
 		BLI_addtail(&U.uifonts, font);
-		
+		/*
 		strcpy(font->filename, "default");
 		font->uifont_id= UIFONT_DEFAULT;
+		*/
+		strcpy(font->filename, "msgothic.ttc");
+		font->uifont_id= UIFONT_CUSTOM1;
+		BLF_dir_add("C:/WINDOWS/Fonts");
 	}
 	
 	for(font= U.uifonts.first; font; font= font->next) {