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