MagickCore 6.9.11-60
Convert, Edit, Or Compose Bitmap Images
utility-private.h
Go to the documentation of this file.
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 "magick/memory_.h"
22#include "magick/nt-base.h"
24
25#if defined(__cplusplus) || defined(c_plusplus)
26extern "C" {
27#endif
28
30 ShredFile(const char *);
31
32static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
33 struct dirent **result)
34{
35#if defined(MAGICKCORE_HAVE_READDIR_R)
36 return(readdir_r(directory,entry,result));
37#else
38 (void) entry;
39 errno=0;
40 *result=readdir(directory);
41 return(errno);
42#endif
43}
44
45/*
46 Windows UTF8 compatibility methods.
47*/
48
49#if defined(MAGICKCORE_WINDOWS_SUPPORT)
50static inline wchar_t *create_wchar_path(const char *utf8)
51{
52 int
53 count;
54
55 wchar_t
56 *wideChar;
57
58 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
59 if ((count > MAX_PATH) && (NTLongPathsEnabled() == MagickFalse))
60 {
61 char
62 buffer[MaxTextExtent];
63
64 wchar_t
65 shortPath[MAX_PATH],
66 *longPath;
67
68 (void) FormatLocaleString(buffer,MaxTextExtent,"\\\\?\\%s",utf8);
69 count+=4;
70 longPath=(wchar_t *) AcquireQuantumMemory(count,sizeof(*longPath));
71 if (longPath == (wchar_t *) NULL)
72 return((wchar_t *) NULL);
73 count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
74 if (count != 0)
75 count=GetShortPathNameW(longPath,shortPath,MAX_PATH);
76 longPath=(wchar_t *) RelinquishMagickMemory(longPath);
77 if ((count < 5) || (count >= MAX_PATH))
78 return((wchar_t *) NULL);
79 wideChar=(wchar_t *) AcquireQuantumMemory(count-3,sizeof(*wideChar));
80 wcscpy(wideChar,shortPath+4);
81 return(wideChar);
82 }
83 wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar));
84 if (wideChar == (wchar_t *) NULL)
85 return((wchar_t *) NULL);
86 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count);
87 if (count == 0)
88 {
89 wideChar=(wchar_t *) RelinquishMagickMemory(wideChar);
90 return((wchar_t *) NULL);
91 }
92 return(wideChar);
93}
94#endif
95
96static inline int access_utf8(const char *path,int mode)
97{
98#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
99 return(access(path,mode));
100#else
101 int
102 status;
103
104 wchar_t
105 *path_wide;
106
107 path_wide=create_wchar_path(path);
108 if (path_wide == (wchar_t *) NULL)
109 return(-1);
110 status=_waccess(path_wide,mode);
111 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
112 return(status);
113#endif
114}
115
116static inline FILE *fopen_utf8(const char *path,const char *mode)
117{
118#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
119 return(fopen(path,mode));
120#else
121 FILE
122 *file;
123
124 wchar_t
125 *mode_wide,
126 *path_wide;
127
128 path_wide=create_wchar_path(path);
129 if (path_wide == (wchar_t *) NULL)
130 return((FILE *) NULL);
131 mode_wide=create_wchar_path(mode);
132 if (mode_wide == (wchar_t *) NULL)
133 {
134 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
135 return((FILE *) NULL);
136 }
137 file=_wfopen(path_wide,mode_wide);
138 mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
139 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
140 return(file);
141#endif
142}
143
144static inline void getcwd_utf8(char *path,size_t extent)
145{
146#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
147 char
148 *directory;
149
150 directory=getcwd(path,extent);
151 (void) directory;
152#else
153 wchar_t
154 wide_path[MaxTextExtent];
155
156 (void) _wgetcwd(wide_path,MaxTextExtent-1);
157 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
158#endif
159}
160
161#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
162typedef int
163 mode_t;
164#endif
165
166static inline int open_utf8(const char *path,int flags,mode_t mode)
167{
168#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
169 return(open(path,flags,mode));
170#else
171 int
172 status;
173
174 wchar_t
175 *path_wide;
176
177 path_wide=create_wchar_path(path);
178 if (path_wide == (wchar_t *) NULL)
179 return(-1);
180 status=_wopen(path_wide,flags,mode);
181 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
182 return(status);
183#endif
184}
185
186static inline FILE *popen_utf8(const char *command,const char *type)
187{
188#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
189 return(popen(command,type));
190#else
191 FILE
192 *file;
193
194 int
195 length;
196
197 wchar_t
198 *command_wide,
199 type_wide[5];
200
201 file=(FILE *) NULL;
202 length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
203 if (length == 0)
204 return(file);
205 length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
206 if (length == 0)
207 return(file);
208 command_wide=(wchar_t *) AcquireQuantumMemory(length,sizeof(*command_wide));
209 if (command_wide == (wchar_t *) NULL)
210 return(file);
211 length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
212 if (length != 0)
213 file=_wpopen(command_wide,type_wide);
214 command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
215 return(file);
216#endif
217}
218
219static inline char *realpath_utf8(const char *path)
220{
221#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
222#if defined(MAGICKCORE_HAVE_REALPATH)
223 return(realpath(path,(char *) NULL));
224#else
225 return(AcquireString(path));
226#endif
227#else
228 char
229 *real_path;
230
231 DWORD
232 final_path_length,
233 full_path_length;
234
235 HANDLE
236 file_handle;
237
238 int
239 length,
240 utf8_length,
241
242 wchar_t
243 *clean_path,
244 *final_path,
245 *full_path,
246 *wide_path;
247
248 /*
249 Convert UTF-8 to UTF-16.
250 */
251 if (path == (const char *) NULL)
252 return((char *) NULL);
253 length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
254 if (length <= 0)
255 return((char *) NULL);
256 wide_path=(wchar_t *) AcquireQuantumMeory(length,sizeof(wchar_t));
257 if (wide_path == (wchar_t *) NULL)
258 return((char *) NULL);
259 MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
260 /*
261 Normalize syntactically.
262 */
263 full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
264 if (full_path_length == 0)
265 {
266 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
267 return((char *) NULL);
268 }
269 full_path=(wchar_t *) AcquireQuantumMemory(full_path_length,sizeof(wchar_t));
270 if (full_path == (wchar_t *) NULL);
271 {
272 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
273 return((char *) NULL);
274 }
275 GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
276 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
277 /*
278 Open the file/directory to resolve symlinks.
279 */
280 file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
281 FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
282 FILE_FLAG_BACKUP_SEMANTICS,NULL);
283 if (file_handle == INVALID_HANDLE_VALUE)
284 {
285 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
286 return((char *) NULL);
287 }
288 /*
289 Resolve final canonical path.
290 */
291 final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
292 FILE_NAME_NORMALIZED);
293 if (final_path_length == 0)
294 {
295 CloseHandle(file_handle);
296 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
297 return((char *) NULL);
298 }
299 final_path=(wchar_t *) AcquireQuantumMemory(final_path_length,
300 sizeof(wchar_t));
301 if (final_path == (wchar_t *) NULL)
302 {
303 CloseHandle(file_handle);
304 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
305 return((char *) NULL);
306 }
307 GetFinalPathNameByHandleW(file_handle,final_path,final_path_length,
308 FILE_NAME_NORMALIZED);
309 CloseHandle(file_handle);
310 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
311 /*
312 Remove \\?\ prefix for POSIX-like behavior.
313 */
314 clean_path=final_path;
315 if (wcsncmp(final_path,L"\\\\?\\",4) == 0)
316 clean_path=final_path+4;
317 /*
318 Convert UTF-16 to UTF-8.
319 */
320 utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
321 if (utf8_length <= 0)
322 {
323 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
324 return NULL;
325 }
326 real_path=(char *) AcquireQuantumMemory(utf8_length,sizeof(char));
327 if (real_path == (char *) NULL)
328 {
329 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
330 return NULL;
331 }
332 WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
333 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
334 return(real_path);
335#endif
336}
337
338static inline int remove_utf8(const char *path)
339{
340#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
341 return(unlink(path));
342#else
343 int
344 status;
345
346 wchar_t
347 *path_wide;
348
349 path_wide=create_wchar_path(path);
350 if (path_wide == (wchar_t *) NULL)
351 return(-1);
352 status=_wremove(path_wide);
353 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
354 return(status);
355#endif
356}
357
358static inline int rename_utf8(const char *source,const char *destination)
359{
360#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
361 return(rename(source,destination));
362#else
363 int
364 status;
365
366 wchar_t
367 *destination_wide,
368 *source_wide;
369
370 source_wide=create_wchar_path(source);
371 if (source_wide == (wchar_t *) NULL)
372 return(-1);
373 destination_wide=create_wchar_path(destination);
374 if (destination_wide == (wchar_t *) NULL)
375 {
376 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
377 return(-1);
378 }
379 status=_wrename(source_wide,destination_wide);
380 destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
381 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
382 return(status);
383#endif
384}
385
386static inline int stat_utf8(const char *path,struct stat *attributes)
387{
388#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
389 return(stat(path,attributes));
390#else
391 int
392 status;
393
394 wchar_t
395 *path_wide;
396
397 path_wide=create_wchar_path(path);
398 if (path_wide == (WCHAR *) NULL)
399 return(-1);
400 status=wstat(path_wide,attributes);
401 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
402 return(status);
403#endif
404}
405
406#if defined(__cplusplus) || defined(c_plusplus)
407}
408#endif
409
410#endif
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:497
MagickExport struct dirent * readdir(DIR *)
MagickBooleanType
Definition: magick-type.h:203
@ MagickFalse
Definition: magick-type.h:204
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
#define MagickPrivate
Definition: method-attribute.h:81
#define MaxTextExtent
Definition: method-attribute.h:89
MagickExport char * AcquireString(const char *source)
Definition: string.c:125
Definition: mac.h:42
Definition: mac.h:54
static int open_utf8(const char *path, int flags, mode_t mode)
Definition: utility-private.h:166
static int MagickReadDirectory(DIR *directory, struct dirent *entry, struct dirent **result)
Definition: utility-private.h:32
static FILE * fopen_utf8(const char *path, const char *mode)
Definition: utility-private.h:116
static int remove_utf8(const char *path)
Definition: utility-private.h:338
static char * realpath_utf8(const char *path)
Definition: utility-private.h:219
static int access_utf8(const char *path, int mode)
Definition: utility-private.h:96
static int stat_utf8(const char *path, struct stat *attributes)
Definition: utility-private.h:386
static void getcwd_utf8(char *path, size_t extent)
Definition: utility-private.h:144
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1836
static int rename_utf8(const char *source, const char *destination)
Definition: utility-private.h:358
static FILE * popen_utf8(const char *command, const char *type)
Definition: utility-private.h:186