From: dirk Date: Sat, 8 Mar 2014 08:40:20 +0000 (+0000) Subject: UTF8/WideChar conversion fixes for Windows. X-Git-Tag: 7.0.1-0~2607 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c63cd3c5cc38057bd777fba385c7cae647cf2b1;p=imagemagick UTF8/WideChar conversion fixes for Windows. --- diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c index bb54c2714..472b6e776 100644 --- a/MagickCore/nt-base.c +++ b/MagickCore/nt-base.c @@ -54,6 +54,7 @@ #include "MagickCore/string_.h" #include "MagickCore/string-private.h" #include "MagickCore/utility.h" +#include "MagickCore/utility-private.h" #include "MagickCore/version.h" #if defined(MAGICKCORE_LTDL_DELEGATE) # include "ltdl.h" @@ -162,16 +163,20 @@ BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) ssize_t count; - module_path=(char *) AcquireQuantumMemory(MaxTextExtent, - sizeof(*module_path)); - if (module_path == (char *) NULL) + wchar_t + *wide_path; + + wide_path=(wchar_t *) AcquireQuantumMemory(MaxTextExtent, + sizeof(*wide_path)); + if (wide_path == (wchar_t *) NULL) return(FALSE); - count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent); + count=(ssize_t) GetModuleFileNameW(handle,wide_path,MaxTextExtent); if (count != 0) { char *path; + module_path=create_utf8_string(wide_path); for ( ; count > 0; count--) if (module_path[count] == '\\') { @@ -183,6 +188,7 @@ BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) if (path == (char *) NULL) { module_path=DestroyString(module_path); + wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); return(FALSE); } count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent); @@ -199,6 +205,7 @@ BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) { path=DestroyString(path); module_path=DestroyString(module_path); + wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); return(FALSE); } (void) FormatLocaleString(variable,16*MaxTextExtent, @@ -208,8 +215,9 @@ BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) } } path=DestroyString(path); + module_path=DestroyString(module_path); } - module_path=DestroyString(module_path); + wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); break; } case DLL_PROCESS_DETACH: @@ -392,23 +400,14 @@ MagickPrivate char **NTArgvToUTF8(const int argc,wchar_t **argv) ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV"); for (i=0; i < (ssize_t) argc; i++) { - ssize_t - count; - - count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,NULL,0,NULL,NULL); - if (count < 0) - count=0; - utf8[i]=(char *) AcquireQuantumMemory(count+1,sizeof(**utf8)); + utf8[i]=create_utf8_string(argv[i]); if (utf8[i] == (char *) NULL) { for (i--; i >= 0; i--) utf8[i]=DestroyString(utf8[i]); - utf8=(char **) RelinquishMagickMemory(utf8); ThrowFatalException(ResourceLimitFatalError, "UnableToConvertStringToARGV"); } - count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,utf8[i],count,NULL,NULL); - utf8[i][count]=0; } return(utf8); } @@ -716,7 +715,12 @@ MagickPrivate MagickBooleanType NTGatherRandomData(const size_t length, MagickPrivate MagickBooleanType NTGetExecutionPath(char *path, const size_t extent) { - GetModuleFileName(0,path,(DWORD) extent); + wchar_t + wide_path[MaxTextExtent]; + + (void) GetModuleFileNameW(0,wide_path,(DWORD) extent); + (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL, + NULL); return(MagickTrue); } @@ -1514,15 +1518,15 @@ MagickPrivate void *NTMapMemory(char *address,size_t length,int protection, */ MagickPrivate DIR *NTOpenDirectory(const char *path) { - wchar_t - file_specification[MaxTextExtent]; - DIR *entry; size_t length; + wchar_t + file_specification[MaxTextExtent]; + assert(path != (const char *) NULL); length=MultiByteToWideChar(CP_UTF8,0,path,-1,file_specification, MaxTextExtent); @@ -1616,23 +1620,29 @@ static UINT ChangeErrorMode(void) return SetErrorMode(mode); } -MagickPrivate void *NTOpenLibrary(const char *filename) +static inline void *NTLoadLibrary(const char *filename) { -#define MaxPathElements 31 + int + length; - char - buffer[MaxTextExtent]; + wchar_t + path[MaxTextExtent]; - int - index; + length=MultiByteToWideChar(CP_UTF8,0,filename,-1,path,MaxTextExtent); + if (length == 0) + return((void *) NULL); + return (void *) LoadLibraryExW(path,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); +} + +MagickPrivate void *NTOpenLibrary(const char *filename) +{ + char + path[MaxTextExtent]; register const char *p, *q; - register int - i; - UINT mode; @@ -1640,35 +1650,25 @@ MagickPrivate void *NTOpenLibrary(const char *filename) *handle; mode=ChangeErrorMode(); - handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); - if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL)) + handle=NTLoadLibrary(filename); + if (handle == (void *) NULL) { - SetErrorMode(mode); - return(handle); - } - p=(char *) GetSearchPath(); - index=0; - while (index < MaxPathElements) - { - q=strchr(p,DirectoryListSeparator); - if (q == (char *) NULL) + p=GetSearchPath(); + while (p != (const char*) NULL) { - (void) CopyMagickString(buffer,p,MaxTextExtent); - (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); - (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); - handle=(void *) LoadLibraryEx(buffer,NULL, - LOAD_WITH_ALTERED_SEARCH_PATH); - break; + q=strchr(p,DirectoryListSeparator); + if (q != (const char*) NULL) + (void) CopyMagickString(path,p,q-p+1); + else + (void) CopyMagickString(path,p,MaxTextExtent); + (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent); + (void) ConcatenateMagickString(path,filename,MaxTextExtent); + handle=NTLoadLibrary(path); + if (handle != (void *) NULL || q == (const char*) NULL) + break; + p=q+1; } - i=q-p; - (void) CopyMagickString(buffer,p,i+1); - (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); - (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); - handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); - if (handle != (void *) NULL) - break; - p=q+1; - } + } SetErrorMode(mode); return(handle); } diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h index 783c46fe5..be6fd7c8e 100644 --- a/MagickCore/utility-private.h +++ b/MagickCore/utility-private.h @@ -46,216 +46,224 @@ extern MagickPrivate void Windows UTF8 compatibility methods. */ -static inline int access_utf8(const char *path,int mode) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(access(path,mode)); -#else - int - count, - status; - - WCHAR - *path_wide; - - path_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); - path_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*path_wide)); - if (path_wide == (WCHAR *) NULL) - return(-1); - count=MultiByteToWideChar(CP_UTF8,0,path,-1,path_wide,count); - status=_waccess(path_wide,mode); - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return(status); -#endif -} - -static inline FILE *fopen_utf8(const char *path,const char *mode) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(fopen(path,mode)); -#else - FILE - *file; - - int - count; - - WCHAR - *mode_wide, - *path_wide; - - path_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); - path_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*path_wide)); - if (path_wide == (WCHAR *) NULL) - return((FILE *) NULL); - count=MultiByteToWideChar(CP_UTF8,0,path,-1,path_wide,count); - count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0); - mode_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*mode_wide)); - if (mode_wide == (WCHAR *) NULL) - { - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return((FILE *) NULL); - } - count=MultiByteToWideChar(CP_UTF8,0,mode,-1,mode_wide,count); - file=_wfopen(path_wide,mode_wide); - mode_wide=(WCHAR *) RelinquishMagickMemory(mode_wide); - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return(file); -#endif -} - -#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) -typedef int - mode_t; -#endif - -static inline int open_utf8(const char *path,int flags,mode_t mode) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(open(path,flags,mode)); -#else - int - count, - status; - - WCHAR - *path_wide; - - path_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); - path_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*path_wide)); - if (path_wide == (WCHAR *) NULL) - return(-1); - count=MultiByteToWideChar(CP_UTF8,0,path,-1,path_wide,count); - status=_wopen(path_wide,flags,mode); - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return(status); -#endif -} - -static inline FILE *popen_utf8(const char *command,const char *type) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(popen(command,type)); -#else - FILE - *file; - - int - count; - - WCHAR - *type_wide, - *command_wide; - - command_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0); - command_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*command_wide)); - if (command_wide == (WCHAR *) NULL) - return((FILE *) NULL); - count=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,count); - count=MultiByteToWideChar(CP_UTF8,0,type,-1,NULL,0); - type_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*type_wide)); - if (type_wide == (WCHAR *) NULL) - { - command_wide=(WCHAR *) RelinquishMagickMemory(command_wide); - return((FILE *) NULL); - } - count=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,count); - file=_wpopen(command_wide,type_wide); - type_wide=(WCHAR *) RelinquishMagickMemory(type_wide); - command_wide=(WCHAR *) RelinquishMagickMemory(command_wide); - return(file); -#endif -} - -static inline int remove_utf8(const char *path) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(unlink(path)); -#else - int - count, - status; - - WCHAR - *path_wide; - - path_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); - path_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*path_wide)); - if (path_wide == (WCHAR *) NULL) - return(-1); - count=MultiByteToWideChar(CP_UTF8,0,path,-1,path_wide,count); - status=_wremove(path_wide); - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return(status); -#endif -} - -static inline int rename_utf8(const char *source,const char *destination) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(rename(source,destination)); -#else - int - count, - status; - - WCHAR - *destination_wide, - *source_wide; - - source_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,source,-1,NULL,0); - source_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*source_wide)); - if (source_wide == (WCHAR *) NULL) - return(-1); - count=MultiByteToWideChar(CP_UTF8,0,source,-1,source_wide,count); - count=MultiByteToWideChar(CP_UTF8,0,destination,-1,NULL,0); - destination_wide=(WCHAR *) AcquireQuantumMemory(count, - sizeof(*destination_wide)); - if (destination_wide == (WCHAR *) NULL) - { - source_wide=(WCHAR *) RelinquishMagickMemory(source_wide); - return(-1); - } - count=MultiByteToWideChar(CP_UTF8,0,destination,-1,destination_wide,count); - status=_wrename(source_wide,destination_wide); - destination_wide=(WCHAR *) RelinquishMagickMemory(destination_wide); - source_wide=(WCHAR *) RelinquishMagickMemory(source_wide); - return(status); -#endif -} - -static inline int stat_utf8(const char *path,struct stat *attributes) -{ -#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) - return(stat(path,attributes)); -#else - int - count, - status; - - WCHAR - *path_wide; - - path_wide=(WCHAR *) NULL; - count=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); - path_wide=(WCHAR *) AcquireQuantumMemory(count,sizeof(*path_wide)); - if (path_wide == (WCHAR *) NULL) - return(-1); - count=MultiByteToWideChar(CP_UTF8,0,path,-1,path_wide,count); - status=wstat(path_wide,attributes); - path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); - return(status); -#endif -} - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif +#if defined(MAGICKCORE_WINDOWS_SUPPORT) +static inline wchar_t *create_wchar_string(const char *utf8) +{ + int + count; + + wchar_t + *wideChar; + + count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0); + wideChar=(WCHAR *) AcquireQuantumMemory(count,sizeof(*wideChar)); + if (wideChar == (WCHAR *) NULL) + return((WCHAR *) NULL); + count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count); + if (count == 0) + { + wideChar=(WCHAR *) RelinquishMagickMemory(wideChar); + return((WCHAR *) NULL); + } + return(wideChar); +} + +static inline char *create_utf8_string(const wchar_t *wideChar) +{ + char + *utf8; + + int + count; + + count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,NULL,0,NULL,NULL); + if (count < 0) + return((char *) NULL); + utf8=(char *) AcquireQuantumMemory(count+1,sizeof(*utf8)); + if (utf8 == (char *) NULL) + return((char *) NULL); + count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,utf8,count,NULL,NULL); + if (count == 0) + { + utf8=DestroyString(utf8); + return((char *) NULL); + } + utf8[count]=0; + return(utf8); +} +#endif + +static inline int access_utf8(const char *path,int mode) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(access(path,mode)); +#else + int + status; + + wchar_t + *path_wide; + + path_wide=create_wchar_string(path); + if (path_wide == (wchar_t *) NULL) + return(-1); + status=_waccess(path_wide,mode); + path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); + return(status); +#endif +} + +static inline FILE *fopen_utf8(const char *path,const char *mode) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(fopen(path,mode)); +#else + FILE + *file; + + wchar_t + *mode_wide, + *path_wide; + + path_wide=create_wchar_string(path); + if (path_wide == (wchar_t *) NULL) + return((FILE *) NULL); + mode_wide=create_wchar_string(mode); + if (mode_wide == (wchar_t *) NULL) + { + path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); + return((FILE *) NULL); + } + file=_wfopen(path_wide,mode_wide); + mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide); + path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); + return(file); +#endif +} + +#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) +typedef int + mode_t; +#endif + +static inline int open_utf8(const char *path,int flags,mode_t mode) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(open(path,flags,mode)); +#else + int + status; + + wchar_t + *path_wide; + + path_wide=create_wchar_string(path); + if (path_wide == (wchar_t *) NULL) + return(-1); + status=_wopen(path_wide,flags,mode); + path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); + return(status); +#endif +} + +static inline FILE *popen_utf8(const char *command,const char *type) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(popen(command,type)); +#else + FILE + *file; + + wchar_t + *type_wide, + *command_wide; + + command_wide=create_wchar_string(command); + if (command_wide == (wchar_t *) NULL) + return((FILE *) NULL); + type_wide=create_wchar_string(type); + if (type_wide == (wchar_t *) NULL) + { + command_wide=(wchar_t *) RelinquishMagickMemory(command_wide); + return((FILE *) NULL); + } + file=_wpopen(command_wide,type_wide); + type_wide=(wchar_t *) RelinquishMagickMemory(type_wide); + command_wide=(wchar_t *) RelinquishMagickMemory(command_wide); + return(file); +#endif +} + +static inline int remove_utf8(const char *path) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(unlink(path)); +#else + int + status; + + wchar_t + *path_wide; + + path_wide=create_wchar_string(path); + if (path_wide == (wchar_t *) NULL) + return(-1); + status=_wremove(path_wide); + path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); + return(status); +#endif +} + +static inline int rename_utf8(const char *source,const char *destination) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(rename(source,destination)); +#else + int + status; + + wchar_t + *destination_wide, + *source_wide; + + source_wide=create_wchar_string(source); + if (source_wide == (wchar_t *) NULL) + return(-1); + destination_wide=create_wchar_string(destination); + if (destination_wide == (wchar_t *) NULL) + { + source_wide=(wchar_t *) RelinquishMagickMemory(source_wide); + return(-1); + } + status=_wrename(source_wide,destination_wide); + destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide); + source_wide=(wchar_t *) RelinquishMagickMemory(source_wide); + return(status); +#endif +} + +static inline int stat_utf8(const char *path,struct stat *attributes) +{ +#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + return(stat(path,attributes)); +#else + int + status; + + wchar_t + *path_wide; + + path_wide=create_wchar_string(path); + if (path_wide == (WCHAR *) NULL) + return(-1); + status=wstat(path_wide,attributes); + path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); + return(status); +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif