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