1 /* 2 Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization 3 dedicated to making software imaging solutions freely available. 4 5 You may not use this file except in compliance with the License. You may 6 obtain a copy of the License at 7 8 https://imagemagick.org/script/license.php 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 16 MagickCore private utility methods. 17 */ 18 #ifndef MAGICKCORE_UTILITY_PRIVATE_H 19 #define MAGICKCORE_UTILITY_PRIVATE_H 20 21 #include "MagickCore/memory_.h" 22 #include "MagickCore/nt-base.h" 23 #include "MagickCore/nt-base-private.h" 24 25 #if defined(__cplusplus) || defined(c_plusplus) 26 extern "C" { 27 #endif 28 29 extern MagickPrivate char 30 **GetPathComponents(const char *,size_t *), 31 **ListFiles(const char *,const char *,size_t *); 32 33 extern MagickPrivate MagickBooleanType 34 GetExecutionPath(char *,const size_t), 35 ShredFile(const char *); 36 37 extern MagickPrivate ssize_t 38 GetMagickPageSize(void); 39 40 extern MagickPrivate void 41 ChopPathComponents(char *,const size_t), 42 ExpandFilename(char *); 43 44 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry, 45 struct dirent **result) 46 { 47 #if defined(MAGICKCORE_HAVE_READDIR_R) 48 return(readdir_r(directory,entry,result)); 49 #else 50 (void) entry; 51 errno=0; 52 *result=readdir(directory); 53 return(errno); 54 #endif 55 } 56 57 /* 58 Windows UTF8 compatibility methods. 59 */ 60 61 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 62 static inline wchar_t *create_wchar_path(const char *utf8) 63 { 64 int 65 count; 66 67 wchar_t 68 *wideChar; 69 70 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0); 71 if (count > MAX_PATH) 72 { 73 char 74 buffer[MagickPathExtent]; 75 76 wchar_t 77 shortPath[MAX_PATH], 78 *longPath; 79 80 (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8); 81 count+=4; 82 longPath=(wchar_t *) AcquireQuantumMemory(count,sizeof(*longPath)); 83 if (longPath == (wchar_t *) NULL) 84 return((wchar_t *) NULL); 85 count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count); 86 if (count != 0) 87 count=GetShortPathNameW(longPath,shortPath,MAX_PATH); 88 longPath=(wchar_t *) RelinquishMagickMemory(longPath); 89 if (count < 5) 90 return((wchar_t *) NULL); 91 wideChar=(wchar_t *) AcquireQuantumMemory(count-3,sizeof(*wideChar)); 92 wcscpy(wideChar,shortPath+4); 93 return(wideChar); 94 } 95 wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar)); 96 if (wideChar == (wchar_t *) NULL) 97 return((wchar_t *) NULL); 98 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count); 99 if (count == 0) 100 { 101 wideChar=(wchar_t *) RelinquishMagickMemory(wideChar); 102 return((wchar_t *) NULL); 103 } 104 return(wideChar); 105 } 106 #endif 107 108 static inline int access_utf8(const char *path,int mode) 109 { 110 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) 111 return(access(path,mode)); 112 #else 113 int 114 status; 115 116 wchar_t 117 *path_wide; 118 119 path_wide=create_wchar_path(path); 120 if (path_wide == (wchar_t *) NULL) 121 return(-1); 122 status=_waccess(path_wide,mode); 123 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); 124 return(status); 125 #endif 126 } 127 128 static inline FILE *fopen_utf8(const char *path,const char *mode) 129 { 130 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 131 return(fopen(path,mode)); 132 #else 133 FILE 134 *file; 135 136 wchar_t 137 *mode_wide, 138 *path_wide; 139 140 path_wide=create_wchar_path(path); 141 if (path_wide == (wchar_t *) NULL) 142 return((FILE *) NULL); 143 mode_wide=create_wchar_path(mode); 144 if (mode_wide == (wchar_t *) NULL) 145 { 146 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); 147 return((FILE *) NULL); 148 } 149 file=_wfopen(path_wide,mode_wide); 150 mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide); 151 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); 152 return(file); 153 #endif 154 } 155 156 static inline void getcwd_utf8(char *path,size_t extent) 157 { 158 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 159 char 160 *directory; 161 162 directory=getcwd(path,extent); 163 (void) directory; 164 #else 165 wchar_t 166 wide_path[MagickPathExtent]; 167 168 (void) _wgetcwd(wide_path,MagickPathExtent-1); 169 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL); 170 #endif 171 } 172 173 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__) 174 typedef int 175 mode_t; 176 #endif 177 178 static inline int open_utf8(const char *path,int flags,mode_t mode) 179 { 180 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 181 return(open(path,flags,mode)); 182 #else 183 int 184 status; 185 186 wchar_t 187 *path_wide; 188 189 path_wide=create_wchar_path(path); 190 if (path_wide == (wchar_t *) NULL) 191 return(-1); 192 status=_wopen(path_wide,flags,mode); 193 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); 194 return(status); 195 #endif 196 } 197 198 static inline FILE *popen_utf8(const char *command,const char *type) 199 { 200 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 201 return(popen(command,type)); 202 #else 203 FILE 204 *file; 205 206 wchar_t 207 *type_wide, 208 *command_wide; 209 210 command_wide=create_wchar_path(command); 211 if (command_wide == (wchar_t *) NULL) 212 return((FILE *) NULL); 213 type_wide=create_wchar_path(type); 214 if (type_wide == (wchar_t *) NULL) 215 { 216 command_wide=(wchar_t *) RelinquishMagickMemory(command_wide); 217 return((FILE *) NULL); 218 } 219 file=_wpopen(command_wide,type_wide); 220 type_wide=(wchar_t *) RelinquishMagickMemory(type_wide); 221 command_wide=(wchar_t *) RelinquishMagickMemory(command_wide); 222 return(file); 223 #endif 224 } 225 226 static inline int remove_utf8(const char *path) 227 { 228 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 229 return(unlink(path)); 230 #else 231 int 232 status; 233 234 wchar_t 235 *path_wide; 236 237 path_wide=create_wchar_path(path); 238 if (path_wide == (wchar_t *) NULL) 239 return(-1); 240 status=_wremove(path_wide); 241 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide); 242 return(status); 243 #endif 244 } 245 246 static inline int rename_utf8(const char *source,const char *destination) 247 { 248 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 249 return(rename(source,destination)); 250 #else 251 int 252 status; 253 254 wchar_t 255 *destination_wide, 256 *source_wide; 257 258 source_wide=create_wchar_path(source); 259 if (source_wide == (wchar_t *) NULL) 260 return(-1); 261 destination_wide=create_wchar_path(destination); 262 if (destination_wide == (wchar_t *) NULL) 263 { 264 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide); 265 return(-1); 266 } 267 status=_wrename(source_wide,destination_wide); 268 destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide); 269 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide); 270 return(status); 271 #endif 272 } 273 274 static inline int stat_utf8(const char *path,struct stat *attributes) 275 { 276 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__) 277 return(stat(path,attributes)); 278 #else 279 int 280 status; 281 282 wchar_t 283 *path_wide; 284 285 path_wide=create_wchar_path(path); 286 if (path_wide == (WCHAR *) NULL) 287 return(-1); 288 status=wstat(path_wide,attributes); 289 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide); 290 return(status); 291 #endif 292 } 293 294 #if defined(__cplusplus) || defined(c_plusplus) 295 } 296 #endif 297 298 #endif 299