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