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
116#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__)
117#define close_utf8 _close
118#else
119#define close_utf8 close
120#endif
121
122static inline FILE *fopen_utf8(const char *path,const char *mode)
123{
124#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
125 return(fopen(path,mode));
126#else
127 FILE
128 *file;
129
130 wchar_t
131 *mode_wide,
132 *path_wide;
133
134 path_wide=create_wchar_path(path);
135 if (path_wide == (wchar_t *) NULL)
136 return((FILE *) NULL);
137 mode_wide=create_wchar_path(mode);
138 if (mode_wide == (wchar_t *) NULL)
139 {
140 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
141 return((FILE *) NULL);
142 }
143 file=_wfopen(path_wide,mode_wide);
144 mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
145 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
146 return(file);
147#endif
148}
149
150static inline void getcwd_utf8(char *path,size_t extent)
151{
152#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
153 char
154 *directory;
155
156 directory=getcwd(path,extent);
157 (void) directory;
158#else
159 wchar_t
160 wide_path[MaxTextExtent];
161
162 (void) _wgetcwd(wide_path,MaxTextExtent-1);
163 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
164#endif
165}
166
167#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
168typedef int
169 mode_t;
170#endif
171
172static inline int open_utf8(const char *path,int flags,mode_t mode)
173{
174#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
175 return(open(path,flags,mode));
176#else
177 int
178 status;
179
180 wchar_t
181 *path_wide;
182
183 path_wide=create_wchar_path(path);
184 if (path_wide == (wchar_t *) NULL)
185 return(-1);
186 status=_wopen(path_wide,flags,mode);
187 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
188 return(status);
189#endif
190}
191
192static inline FILE *popen_utf8(const char *command,const char *type)
193{
194#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
195 return(popen(command,type));
196#else
197 FILE
198 *file;
199
200 int
201 length;
202
203 wchar_t
204 *command_wide,
205 type_wide[5];
206
207 file=(FILE *) NULL;
208 length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
209 if (length == 0)
210 return(file);
211 length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
212 if (length == 0)
213 return(file);
214 command_wide=(wchar_t *) AcquireQuantumMemory(length,sizeof(*command_wide));
215 if (command_wide == (wchar_t *) NULL)
216 return(file);
217 length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
218 if (length != 0)
219 file=_wpopen(command_wide,type_wide);
220 command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
221 return(file);
222#endif
223}
224
225static inline char *realpath_utf8(const char *path)
226{
227#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
228#if defined(MAGICKCORE_HAVE_REALPATH)
229 return(realpath(path,(char *) NULL));
230#else
231 return(AcquireString(path));
232#endif
233#else
234 char
235 *real_path;
236
237 DWORD
238 final_path_length,
239 full_path_length;
240
241 HANDLE
242 file_handle;
243
244 int
245 length,
246 utf8_length,
247
248 wchar_t
249 *clean_path,
250 *final_path,
251 *full_path,
252 *wide_path;
253
254 /*
255 Convert UTF-8 to UTF-16.
256 */
257 if (path == (const char *) NULL)
258 return((char *) NULL);
259 length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
260 if (length <= 0)
261 return((char *) NULL);
262 wide_path=(wchar_t *) AcquireQuantumMeory(length,sizeof(wchar_t));
263 if (wide_path == (wchar_t *) NULL)
264 return((char *) NULL);
265 MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
266 /*
267 Normalize syntactically.
268 */
269 full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
270 if (full_path_length == 0)
271 {
272 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
273 return((char *) NULL);
274 }
275 full_path=(wchar_t *) AcquireQuantumMemory(full_path_length,sizeof(wchar_t));
276 if (full_path == (wchar_t *) NULL);
277 {
278 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
279 return((char *) NULL);
280 }
281 GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
282 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
283 /*
284 Open the file/directory to resolve symlinks.
285 */
286 file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
287 FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
288 FILE_FLAG_BACKUP_SEMANTICS,NULL);
289 if (file_handle == INVALID_HANDLE_VALUE)
290 {
291 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
292 return((char *) NULL);
293 }
294 /*
295 Resolve final canonical path.
296 */
297 final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
298 FILE_NAME_NORMALIZED);
299 if (final_path_length == 0)
300 {
301 CloseHandle(file_handle);
302 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
303 return((char *) NULL);
304 }
305 final_path=(wchar_t *) AcquireQuantumMemory(final_path_length,
306 sizeof(wchar_t));
307 if (final_path == (wchar_t *) NULL)
308 {
309 CloseHandle(file_handle);
310 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
311 return((char *) NULL);
312 }
313 GetFinalPathNameByHandleW(file_handle,final_path,final_path_length,
314 FILE_NAME_NORMALIZED);
315 CloseHandle(file_handle);
316 full_path=(wchar_t *) RelinquishMagickMemory(full_path);
317 /*
318 Remove \\?\ prefix for POSIX-like behavior.
319 */
320 clean_path=final_path;
321 if (wcsncmp(final_path,L"\\\\?\\",4) == 0)
322 clean_path=final_path+4;
323 /*
324 Convert UTF-16 to UTF-8.
325 */
326 utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
327 if (utf8_length <= 0)
328 {
329 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
330 return NULL;
331 }
332 real_path=(char *) AcquireQuantumMemory(utf8_length,sizeof(char));
333 if (real_path == (char *) NULL)
334 {
335 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
336 return NULL;
337 }
338 WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
339 final_path=(wchar_t *) RelinquishMagickMemory(final_path);
340 return(real_path);
341#endif
342}
343
344static inline int remove_utf8(const char *path)
345{
346#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
347 return(unlink(path));
348#else
349 int
350 status;
351
352 wchar_t
353 *path_wide;
354
355 path_wide=create_wchar_path(path);
356 if (path_wide == (wchar_t *) NULL)
357 return(-1);
358 status=_wremove(path_wide);
359 path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
360 return(status);
361#endif
362}
363
364static inline int rename_utf8(const char *source,const char *destination)
365{
366#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
367 return(rename(source,destination));
368#else
369 int
370 status;
371
372 wchar_t
373 *destination_wide,
374 *source_wide;
375
376 source_wide=create_wchar_path(source);
377 if (source_wide == (wchar_t *) NULL)
378 return(-1);
379 destination_wide=create_wchar_path(destination);
380 if (destination_wide == (wchar_t *) NULL)
381 {
382 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
383 return(-1);
384 }
385 status=_wrename(source_wide,destination_wide);
386 destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
387 source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
388 return(status);
389#endif
390}
391
392static inline int stat_utf8(const char *path,struct stat *attributes)
393{
394#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
395 return(stat(path,attributes));
396#else
397 int
398 status;
399
400 wchar_t
401 *path_wide;
402
403 path_wide=create_wchar_path(path);
404 if (path_wide == (WCHAR *) NULL)
405 return(-1);
406 status=wstat(path_wide,attributes);
407 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
408 return(status);
409#endif
410}
411
412#if defined(__cplusplus) || defined(c_plusplus)
413}
414#endif
415
416#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:172
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:122
static int remove_utf8(const char *path)
Definition: utility-private.h:344
static char * realpath_utf8(const char *path)
Definition: utility-private.h:225
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:392
static void getcwd_utf8(char *path, size_t extent)
Definition: utility-private.h:150
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1844
static int rename_utf8(const char *source, const char *destination)
Definition: utility-private.h:364
static FILE * popen_utf8(const char *command, const char *type)
Definition: utility-private.h:192