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