Home | History | Annotate | Download | only in MagickCore
      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