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
MagickReadDirectory(DIR * directory,struct dirent * entry,struct dirent ** result)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)
create_wchar_path(const char * utf8)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
access_utf8(const char * path,int mode)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
fopen_utf8(const char * path,const char * mode)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
getcwd_utf8(char * path,size_t extent)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
open_utf8(const char * path,int flags,mode_t mode)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
popen_utf8(const char * command,const char * type)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
remove_utf8(const char * path)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
rename_utf8(const char * source,const char * destination)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
stat_utf8(const char * path,struct stat * attributes)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