MagickCore  6.9.10
Convert, Edit, Or Compose Bitmap Images
utility-private.h
Go to the documentation of this file.
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.
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"
23 #include "magick/nt-base-private.h"
24 
25 #if defined(__cplusplus) || defined(c_plusplus)
26 extern "C" {
27 #endif
28 
30  ShredFile(const char *);
31 
32 static 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)
50 static 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)
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)
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 
96 static 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 
122 static inline FILE *fopen_utf8(const char *path,const char *mode)
123 {
124 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
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 
150 static 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__)
168 typedef int
169  mode_t;
170 #endif
171 
172 static inline int open_utf8(const char *path,int flags,mode_t mode)
173 {
174 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
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 
192 static inline FILE *popen_utf8(const char *command,const char *type)
193 {
194 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
195  return(popen(command,type));
196 #else
197  FILE
198  *file;
199 
200  wchar_t
201  *type_wide,
202  *command_wide;
203 
204  command_wide=create_wchar_path(command);
205  if (command_wide == (wchar_t *) NULL)
206  return((FILE *) NULL);
207  type_wide=create_wchar_path(type);
208  if (type_wide == (wchar_t *) NULL)
209  {
210  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
211  return((FILE *) NULL);
212  }
213  file=_wpopen(command_wide,type_wide);
214  type_wide=(wchar_t *) RelinquishMagickMemory(type_wide);
215  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
216  return(file);
217 #endif
218 }
219 
220 static inline char *realpath_utf8(const char *path)
221 {
222 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
223 #if defined(MAGICKCORE_HAVE_REALPATH)
224  return(realpath(path,(char *) NULL));
225 #else
226  return(AcquireString(path));
227 #endif
228 #else
229  char
230  *real_path;
231 
232  DWORD
233  final_path_length,
234  full_path_length;
235 
236  HANDLE
237  file_handle;
238 
239  int
240  length,
241  utf8_length,
242 
243  wchar_t
244  *clean_path,
245  *final_path,
246  *full_path,
247  *wide_path;
248 
249  /*
250  Convert UTF-8 to UTF-16.
251  */
252  if (path == (const char *) NULL)
253  return((char *) NULL);
254  length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
255  if (length <= 0)
256  return((char *) NULL);
257  wide_path=(wchar_t *) AcquireQuantumMeory(length,sizeof(wchar_t));
258  if (wide_path == (wchar_t *) NULL)
259  return((char *) NULL);
260  MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
261  /*
262  Normalize syntactically.
263  */
264  full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
265  if (full_path_length == 0)
266  {
267  wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
268  return((char *) NULL);
269  }
270  full_path=(wchar_t *) AcquireQuantumMemory(full_path_length,sizeof(wchar_t));
271  if (full_path == (wchar_t *) NULL);
272  {
273  wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
274  return((char *) NULL);
275  }
276  GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
277  wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
278  /*
279  Open the file/directory to resolve symlinks.
280  */
281  file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
282  FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
283  FILE_FLAG_BACKUP_SEMANTICS,NULL);
284  if (file_handle == INVALID_HANDLE_VALUE)
285  {
286  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
287  return((char *) NULL);
288  }
289  /*
290  Resolve final canonical path.
291  */
292  final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
293  FILE_NAME_NORMALIZED);
294  if (final_path_length == 0)
295  {
296  CloseHandle(file_handle);
297  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
298  return((char *) NULL);
299  }
300  final_path=(wchar_t *) AcquireQuantumMemory(final_path_length,
301  sizeof(wchar_t));
302  if (final_path == (wchar_t *) NULL)
303  {
304  CloseHandle(file_handle);
305  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
306  return((char *) NULL);
307  }
308  GetFinalPathNameByHandleW(file_handle,final_path,final_path_length,
309  FILE_NAME_NORMALIZED);
310  CloseHandle(file_handle);
311  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
312  /*
313  Remove \\?\ prefix for POSIX-like behavior.
314  */
315  clean_path=final_path;
316  if (wcsncmp(final_path,L"\\\\?\\",4) == 0)
317  clean_path=final_path+4;
318  /*
319  Convert UTF-16 to UTF-8.
320  */
321  utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
322  if (utf8_length <= 0)
323  {
324  final_path=(wchar_t *) RelinquishMagickMemory(final_path);
325  return NULL;
326  }
327  real_path=(char *) AcquireQuantumMemory(utf8_length,sizeof(char));
328  if (real_path == (char *) NULL)
329  {
330  final_path=(wchar_t *) RelinquishMagickMemory(final_path);
331  return NULL;
332  }
333  WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
334  final_path=(wchar_t *) RelinquishMagickMemory(final_path);
335  return(real_path);
336 #endif
337 }
338 
339 static inline int remove_utf8(const char *path)
340 {
341 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
342  return(unlink(path));
343 #else
344  int
345  status;
346 
347  wchar_t
348  *path_wide;
349 
350  path_wide=create_wchar_path(path);
351  if (path_wide == (wchar_t *) NULL)
352  return(-1);
353  status=_wremove(path_wide);
354  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
355  return(status);
356 #endif
357 }
358 
359 static inline int rename_utf8(const char *source,const char *destination)
360 {
361 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
362  return(rename(source,destination));
363 #else
364  int
365  status;
366 
367  wchar_t
368  *destination_wide,
369  *source_wide;
370 
371  source_wide=create_wchar_path(source);
372  if (source_wide == (wchar_t *) NULL)
373  return(-1);
374  destination_wide=create_wchar_path(destination);
375  if (destination_wide == (wchar_t *) NULL)
376  {
377  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
378  return(-1);
379  }
380  status=_wrename(source_wide,destination_wide);
381  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
382  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
383  return(status);
384 #endif
385 }
386 
387 static inline int stat_utf8(const char *path,struct stat *attributes)
388 {
389 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
390  return(stat(path,attributes));
391 #else
392  int
393  status;
394 
395  wchar_t
396  *path_wide;
397 
398  path_wide=create_wchar_path(path);
399  if (path_wide == (WCHAR *) NULL)
400  return(-1);
401  status=wstat(path_wide,attributes);
402  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
403  return(status);
404 #endif
405 }
406 
407 #if defined(__cplusplus) || defined(c_plusplus)
408 }
409 #endif
410 
411 #endif
static FILE * popen_utf8(const char *command, const char *type)
Definition: utility-private.h:192
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:502
static void getcwd_utf8(char *path, size_t extent)
Definition: utility-private.h:150
char * path
Definition: type.h:56
Definition: mac.h:53
Definition: mac.h:41
static int stat_utf8(const char *path, struct stat *attributes)
Definition: utility-private.h:387
MagickBooleanType
Definition: magick-type.h:191
MagickExport char * AcquireString(const char *source)
Definition: string.c:125
static int remove_utf8(const char *path)
Definition: utility-private.h:339
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:544
static FILE * fopen_utf8(const char *path, const char *mode)
Definition: utility-private.h:122
#define MaxTextExtent
Definition: method-attribute.h:89
static int open_utf8(const char *path, int flags, mode_t mode)
Definition: utility-private.h:172
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1823
MagickExport struct dirent * readdir(DIR *)
static int rename_utf8(const char *source, const char *destination)
Definition: utility-private.h:359
static int access_utf8(const char *path, int mode)
Definition: utility-private.h:96
static int MagickReadDirectory(DIR *directory, struct dirent *entry, struct dirent **result)
Definition: utility-private.h:32
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1095
#define MagickPrivate
Definition: method-attribute.h:81
static char * realpath_utf8(const char *path)
Definition: utility-private.h:220