From: dirk Date: Sat, 8 Mar 2014 11:36:42 +0000 (+0000) Subject: Fix for accessing files with long path names in Windows. X-Git-Tag: 7.0.1-0~2606 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b74b286991ce15fbcb3eb7831346442d39b3dfba;p=imagemagick Fix for accessing files with long path names in Windows. --- diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c index 472b6e776..ffde3e4bb 100644 --- a/MagickCore/nt-base.c +++ b/MagickCore/nt-base.c @@ -106,6 +106,30 @@ const registry_roots[2] = extern "C" BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved); #endif + +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); +} /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h index be6fd7c8e..d144bbc8e 100644 --- a/MagickCore/utility-private.h +++ b/MagickCore/utility-private.h @@ -46,224 +46,224 @@ extern MagickPrivate void Windows UTF8 compatibility methods. */ -#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 +#if defined(MAGICKCORE_WINDOWS_SUPPORT) +static inline wchar_t *create_wchar_path(const char *utf8) +{ + int + count; + + wchar_t + *wideChar; + + count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0); + if (count > MAX_PATH) + { + char + buffer[MaxTextExtent]; + + wchar_t + shortPath[MAX_PATH], + *longPath; + + (void) FormatLocaleString(buffer,MaxTextExtent,"\\\\?\\%s",utf8); + count+=4; + longPath=(wchar_t *) AcquireQuantumMemory(count,sizeof(*longPath)); + if (longPath == (wchar_t *) NULL) + return((wchar_t *) NULL); + count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count); + if (count != 0) + count=GetShortPathNameW(longPath,shortPath,MAX_PATH); + longPath=(wchar_t *) RelinquishMagickMemory(longPath); + if (count < 5) + return((wchar_t *) NULL); + wideChar=(wchar_t *) AcquireQuantumMemory(count-3,sizeof(*wideChar)); + wcscpy(wideChar,shortPath+4); + return(wideChar); + } + wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar)); + if (wideChar == (wchar_t *) NULL) + return((wchar_t *) NULL); + count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count); + if (count == 0) + { + wideChar=(wchar_t *) RelinquishMagickMemory(wideChar); + return((wchar_t *) NULL); + } + return(wideChar); +} +#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_path(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_path(path); + if (path_wide == (wchar_t *) NULL) + return((FILE *) NULL); + mode_wide=create_wchar_path(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_path(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_path(command); + if (command_wide == (wchar_t *) NULL) + return((FILE *) NULL); + type_wide=create_wchar_path(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_path(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_path(source); + if (source_wide == (wchar_t *) NULL) + return(-1); + destination_wide=create_wchar_path(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_path(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