1 /*
2 Copyright 1999-2021 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) && (strncmp(utf8,"\\\\?\\",4) != 0) &&
72 (NTLongPathsEnabled() == MagickFalse))
73 {
74 char
75 buffer[MagickPathExtent];
76
77 wchar_t
78 shortPath[MAX_PATH],
79 *longPath;
80
81 (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8);
82 count+=4;
83 longPath=(wchar_t *) AcquireQuantumMemory(count,sizeof(*longPath));
84 if (longPath == (wchar_t *) NULL)
85 return((wchar_t *) NULL);
86 count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
87 if (count != 0)
88 count=GetShortPathNameW(longPath,shortPath,MAX_PATH);
89 longPath=(wchar_t *) RelinquishMagickMemory(longPath);
90 if ((count < 5) || (count >= MAX_PATH))
91 return((wchar_t *) NULL);
92 wideChar=(wchar_t *) AcquireQuantumMemory(count-3,sizeof(*wideChar));
93 wcscpy(wideChar,shortPath+4);
94 return(wideChar);
95 }
96 wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar));
97 if (wideChar == (wchar_t *) NULL)
98 return((wchar_t *) NULL);
99 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count);
100 if (count == 0)
101 {
102 wideChar=(wchar_t *) RelinquishMagickMemory(wideChar);
103 return((wchar_t *) NULL);
104 }
105 return(wideChar);
106 }
107 #endif
108
access_utf8(const char * path,int mode)109 static inline int access_utf8(const char *path,int mode)
110 {
111 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
112 return(access(path,mode));
113 #else
114 int
115 status;
116
117 wchar_t
118 *path_wide;
119
120 path_wide=create_wchar_path(path);
121 if (path_wide == (wchar_t *) NULL)
122 return(-1);
123 status=_waccess(path_wide,mode);
124 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
125 return(status);
126 #endif
127 }
128
fopen_utf8(const char * path,const char * mode)129 static inline FILE *fopen_utf8(const char *path,const char *mode)
130 {
131 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
132 return(fopen(path,mode));
133 #else
134 FILE
135 *file;
136
137 wchar_t
138 *mode_wide,
139 *path_wide;
140
141 path_wide=create_wchar_path(path);
142 if (path_wide == (wchar_t *) NULL)
143 return((FILE *) NULL);
144 mode_wide=create_wchar_path(mode);
145 if (mode_wide == (wchar_t *) NULL)
146 {
147 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
148 return((FILE *) NULL);
149 }
150 file=_wfopen(path_wide,mode_wide);
151 mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
152 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
153 return(file);
154 #endif
155 }
156
getcwd_utf8(char * path,size_t extent)157 static inline void getcwd_utf8(char *path,size_t extent)
158 {
159 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
160 char
161 *directory;
162
163 directory=getcwd(path,extent);
164 (void) directory;
165 #else
166 wchar_t
167 wide_path[MagickPathExtent];
168
169 (void) _wgetcwd(wide_path,MagickPathExtent-1);
170 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
171 #endif
172 }
173
174 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
175 typedef int
176 mode_t;
177 #endif
178
open_utf8(const char * path,int flags,mode_t mode)179 static inline int open_utf8(const char *path,int flags,mode_t mode)
180 {
181 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
182 return(open(path,flags,mode));
183 #else
184 int
185 status;
186
187 wchar_t
188 *path_wide;
189
190 path_wide=create_wchar_path(path);
191 if (path_wide == (wchar_t *) NULL)
192 return(-1);
193 status=_wopen(path_wide,flags,mode);
194 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
195 return(status);
196 #endif
197 }
198
popen_utf8(const char * command,const char * type)199 static inline FILE *popen_utf8(const char *command,const char *type)
200 {
201 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
202 return(popen(command,type));
203 #else
204 FILE
205 *file;
206
207 int
208 length;
209
210 wchar_t
211 *command_wide,
212 type_wide[5];
213
214 file=(FILE *) NULL;
215 length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
216 if (length == 0)
217 return(file);
218 length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
219 if (length == 0)
220 return(file);
221 command_wide=(wchar_t *) AcquireQuantumMemory(length,sizeof(*command_wide));
222 if (command_wide == (wchar_t *) NULL)
223 return(file);
224 length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
225 if (length != 0)
226 file=_wpopen(command_wide,type_wide);
227 command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
228 return(file);
229 #endif
230 }
231
remove_utf8(const char * path)232 static inline int remove_utf8(const char *path)
233 {
234 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
235 return(unlink(path));
236 #else
237 int
238 status;
239
240 wchar_t
241 *path_wide;
242
243 path_wide=create_wchar_path(path);
244 if (path_wide == (wchar_t *) NULL)
245 return(-1);
246 status=_wremove(path_wide);
247 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
248 return(status);
249 #endif
250 }
251
rename_utf8(const char * source,const char * destination)252 static inline int rename_utf8(const char *source,const char *destination)
253 {
254 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
255 return(rename(source,destination));
256 #else
257 int
258 status;
259
260 wchar_t
261 *destination_wide,
262 *source_wide;
263
264 source_wide=create_wchar_path(source);
265 if (source_wide == (wchar_t *) NULL)
266 return(-1);
267 destination_wide=create_wchar_path(destination);
268 if (destination_wide == (wchar_t *) NULL)
269 {
270 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
271 return(-1);
272 }
273 status=_wrename(source_wide,destination_wide);
274 destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
275 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
276 return(status);
277 #endif
278 }
279
stat_utf8(const char * path,struct stat * attributes)280 static inline int stat_utf8(const char *path,struct stat *attributes)
281 {
282 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
283 return(stat(path,attributes));
284 #else
285 int
286 status;
287
288 wchar_t
289 *path_wide;
290
291 path_wide=create_wchar_path(path);
292 if (path_wide == (WCHAR *) NULL)
293 return(-1);
294 status=wstat(path_wide,attributes);
295 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
296 return(status);
297 #endif
298 }
299
300 #if defined(__cplusplus) || defined(c_plusplus)
301 }
302 #endif
303
304 #endif
305