Index: intern/utfconv/utfconv.h =================================================================== --- intern/utfconv/utfconv.h (revision 45477) +++ intern/utfconv/utfconv.h (working copy) @@ -91,11 +91,11 @@ wchar_t * alloc_utf16_from_8(const char * in8, size_t add); /* Easy allocation and conversion of new utf-16 string. New string has _16 suffix. Must be deallocated with UTF16_UN_ENCODE in right order*/ -#define UTF16_ENCODE(in8str) if(1){\ +#define UTF16_ENCODE(in8str) do {\ wchar_t * in8str ## _16 = alloc_utf16_from_8((char*)in8str, 0); #define UTF16_UN_ENCODE(in8str) \ - free(in8str ## _16 ); }; + free(in8str ## _16 ); } while(0); #ifdef __cplusplus } Index: source/blender/blenlib/intern/fileops.c =================================================================== --- source/blender/blenlib/intern/fileops.c (revision 45476) +++ source/blender/blenlib/intern/fileops.c (working copy) @@ -187,8 +187,17 @@ FILE *f = BLI_fopen(file,"r+b"); if (f != NULL) { char c = getc(f); + rewind(f); putc(c,f); + + if (c == EOF) { +#ifdef WIN32 + _chsize(fileno(f), 0); +#else + ftruncate(fileno(f), 0); +#endif + } } else { f = BLI_fopen(file,"wb"); @@ -202,8 +211,21 @@ #ifdef WIN32 -static char str[MAXPATHLEN+12]; +static int is_ansi_compatible(const wchar_t *str) +{ + int i= 0; + while (str[i]) { + if (str[i] > 255) { + return 0; + } + + i++; + } + + return 1; +} + FILE *BLI_fopen(const char *filename, const char *mode) { return ufopen(filename, mode); @@ -212,33 +234,51 @@ gzFile BLI_gzopen(const char *filename, const char *mode) { gzFile gzfile; - int fi; - if (!filename || !mode) {return 0;} - else + if (!filename || !mode) { + gzfile= NULL; + } + else { + UTF16_ENCODE(filename); - { - - wchar_t short_name_16 [256]; - char short_name [256]; - int i=0; + if (is_ansi_compatible(filename_16)) { + gzfile= gzopen(filename, mode); + } + else { + wchar_t short_name_16[MAX_PATH]; - /* xxx Creates file before transcribing the path */ - if(mode[0]=='w') - fclose(ufopen(filename,"a")); + /* xxx Creates file before transcribing the path */ + if (strchr(mode, 'w')) { + fclose(ufopen(filename,"a")); + } - UTF16_ENCODE(filename); + /* system generated short names are ansi compatible, so attempt to + get such a name because zlib will not open the file properly + otherwise. Only works if file exists. Can still return a unicode + name since short name generation may be turned off */ + GetShortPathNameW(filename_16, short_name_16, MAX_PATH); - GetShortPathNameW(filename_16,short_name_16,256); + if (is_ansi_compatible(short_name_16)) { + char short_name[MAX_PATH]; + int i; - for (i=0;i<256;i++) {short_name[i]=short_name_16[i];}; + /* This is only this simple because it's confirmed ANSI */ + for (i= 0;i < MAX_PATH; i++) { + short_name[i]= (char)short_name_16[i]; + } + gzfile= gzopen(short_name, mode); + } + else { + /* user will need to rename the file without wide characters */ + callLocalErrorCallBack("The file path contains wide characters that cannot be decoded. As a work-around you may move or rename the file."); + gzfile= NULL; + } + } - gzfile = gzopen(short_name,mode); - UTF16_UN_ENCODE(filename); + } - } return gzfile; } @@ -274,6 +314,7 @@ int BLI_move(const char *file, const char *to) { int err; + char str[MAXPATHLEN+12]; // windows doesn't support moveing to a directory // it has to be 'mv filename filename' and not @@ -305,6 +346,7 @@ int BLI_copy(const char *file, const char *to) { int err; + char str[MAXPATHLEN+12]; // windows doesn't support copying to a directory // it has to be 'cp filename filename' and not @@ -334,10 +376,37 @@ int BLI_create_symlink(const char *file, const char *to) { - callLocalErrorCallBack("Linking files is unsupported on Windows"); - (void)file; - (void)to; - return 1; + typedef BOOLEAN (WINAPI *pfnCreateSymbolicLinkW_t)(LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags); + + static int initialized = 0; + static pfnCreateSymbolicLinkW_t pfnCreateSymbolicLinkW = NULL; + + if (!initialized) { + pfnCreateSymbolicLinkW= + (pfnCreateSymbolicLinkW_t)GetProcAddress( + GetModuleHandleA("kernel32.dll"), + "CreateSymbolicLinkW"); + + initialized = 1; + } + + if (pfnCreateSymbolicLinkW) { + BOOLEAN success; + + UTF16_ENCODE(file) + UTF16_ENCODE(to) + + success= pfnCreateSymbolicLinkW(to_16, file_16, 0); + + UTF16_UN_ENCODE(to) + UTF16_UN_ENCODE(file) + + return success ? 0 : -1; + } + else { + callLocalErrorCallBack("Linking files is not supported by this version of Windows"); + return -1; + } } void BLI_dir_create_recursive(const char *dirname)