MagickCore  7.1.1-43
Convert, Edit, Or Compose Bitmap Images
utility-private.h
1 /*
2  Copyright @ 1999 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. You may
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 "MagickCore/memory_.h"
22 #include "MagickCore/nt-base.h"
23 #include "MagickCore/nt-base-private.h"
24 #if defined(MAGICKCORE_HAVE_UTIME_H)
25 #include <utime.h>
26 #endif
27 
28 #if defined(__cplusplus) || defined(c_plusplus)
29 extern "C" {
30 #endif
31 
32 extern MagickPrivate char
33  **GetPathComponents(const char *,size_t *),
34  **ListFiles(const char *,const char *,size_t *);
35 
36 extern MagickPrivate MagickBooleanType
37  GetExecutionPath(char *,const size_t),
38  ShredFile(const char *);
39 
40 extern MagickPrivate ssize_t
41  GetMagickPageSize(void);
42 
43 extern MagickPrivate void
44  ChopPathComponents(char *,const size_t),
45  ExpandFilename(char *);
46 
47 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
48  struct dirent **result)
49 {
50  (void) entry;
51  errno=0;
52  *result=readdir(directory);
53  return(errno);
54 }
55 
56 /*
57  Windows UTF8 compatibility methods.
58 */
59 
60 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
61 static inline wchar_t *create_wchar_path(const char *utf8)
62 {
63  int
64  count;
65 
66  wchar_t
67  *wide;
68 
69  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
70  if ((count > MAX_PATH) && (strncmp(utf8,"\\\\?\\",4) != 0) &&
71  (NTLongPathsEnabled() == MagickFalse))
72  {
73  char
74  buffer[MagickPathExtent];
75 
76  wchar_t
77  shortPath[MAX_PATH],
78  *longPath;
79 
80  (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8);
81  count+=4;
82  longPath=(wchar_t *) NTAcquireQuantumMemory((size_t) count,
83  sizeof(*longPath));
84  if (longPath == (wchar_t *) NULL)
85  return((wchar_t *) NULL);
86  count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
87  if (count != 0)
88  count=(int) GetShortPathNameW(longPath,shortPath,MAX_PATH);
89  longPath=(wchar_t *) RelinquishMagickMemory(longPath);
90  if ((count < 5) || (count >= MAX_PATH))
91  return((wchar_t *) NULL);
92  wide=(wchar_t *) NTAcquireQuantumMemory((size_t) count-3,sizeof(*wide));
93  wcscpy(wide,shortPath+4);
94  return(wide);
95  }
96  wide=(wchar_t *) NTAcquireQuantumMemory((size_t) count,sizeof(*wide));
97  if ((wide != (wchar_t *) NULL) &&
98  (MultiByteToWideChar(CP_UTF8,0,utf8,-1,wide,count) == 0))
99  wide=(wchar_t *) RelinquishMagickMemory(wide);
100  return(wide);
101 }
102 
103 static inline wchar_t *create_wchar_mode(const char *mode)
104 {
105  int
106  count;
107 
108  wchar_t
109  *wide;
110 
111  count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
112  wide=(wchar_t *) AcquireQuantumMemory((size_t) count+1,
113  sizeof(*wide));
114  if (wide == (wchar_t *) NULL)
115  return((wchar_t *) NULL);
116  if (MultiByteToWideChar(CP_UTF8,0,mode,-1,wide,count) == 0)
117  {
118  wide=(wchar_t *) RelinquishMagickMemory(wide);
119  return((wchar_t *) NULL);
120  }
121  /* Specifies that the file is not inherited by child processes */
122  wide[count] = L'\0';
123  wide[count-1] = L'N';
124  return(wide);
125 }
126 #endif
127 
128 static inline int access_utf8(const char *path,int mode)
129 {
130  if (path == (const char *) NULL)
131  return(-1);
132 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
133  return(access(path,mode));
134 #else
135  int
136  status;
137 
138  wchar_t
139  *path_wide;
140 
141  path_wide=create_wchar_path(path);
142  if (path_wide == (wchar_t *) NULL)
143  return(-1);
144  status=_waccess(path_wide,mode);
145  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
146  return(status);
147 #endif
148 }
149 
150 static inline FILE *fopen_utf8(const char *path,const char *mode)
151 {
152 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
153  return(fopen(path,mode));
154 #else
155  FILE
156  *file;
157 
158  wchar_t
159  *mode_wide,
160  *path_wide;
161 
162  path_wide=create_wchar_path(path);
163  if (path_wide == (wchar_t *) NULL)
164  return((FILE *) NULL);
165  mode_wide=create_wchar_mode(mode);
166  if (mode_wide == (wchar_t *) NULL)
167  {
168  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
169  return((FILE *) NULL);
170  }
171  file=_wfopen(path_wide,mode_wide);
172  mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
173  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
174  return(file);
175 #endif
176 }
177 
178 static inline void getcwd_utf8(char *path,size_t extent)
179 {
180 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
181  char
182  *directory;
183 
184  directory=getcwd(path,extent);
185  (void) directory;
186 #else
187  wchar_t
188  wide_path[MagickPathExtent];
189 
190  (void) _wgetcwd(wide_path,MagickPathExtent-1);
191  (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
192 #endif
193 }
194 
195 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
196 typedef int
197  mode_t;
198 #endif
199 
200 static inline int open_utf8(const char *path,int flags,mode_t mode)
201 {
202 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
203  return(open(path,flags,mode));
204 #else
205  int
206  status;
207 
208  wchar_t
209  *path_wide;
210 
211  path_wide=create_wchar_path(path);
212  if (path_wide == (wchar_t *) NULL)
213  return(-1);
214  /* O_NOINHERIT specifies that the file is not inherited by child processes */
215  status=_wopen(path_wide,flags | O_NOINHERIT,mode);
216  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
217  return(status);
218 #endif
219 }
220 
221 static inline FILE *popen_utf8(const char *command,const char *type)
222 {
223 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
224  return(popen(command,type));
225 #else
226  FILE
227  *file;
228 
229  int
230  length;
231 
232  wchar_t
233  *command_wide,
234  type_wide[5];
235 
236  file=(FILE *) NULL;
237  length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
238  if (length == 0)
239  return(file);
240  length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
241  if (length == 0)
242  return(file);
243  command_wide=(wchar_t *) AcquireQuantumMemory((size_t) length,
244  sizeof(*command_wide));
245  if (command_wide == (wchar_t *) NULL)
246  return(file);
247  length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
248  if (length != 0)
249  file=_wpopen(command_wide,type_wide);
250  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
251  return(file);
252 #endif
253 }
254 
255 static inline int remove_utf8(const char *path)
256 {
257 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
258  return(unlink(path));
259 #else
260  int
261  status;
262 
263  wchar_t
264  *path_wide;
265 
266  path_wide=create_wchar_path(path);
267  if (path_wide == (wchar_t *) NULL)
268  return(-1);
269  status=_wremove(path_wide);
270  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
271  return(status);
272 #endif
273 }
274 
275 static inline int rename_utf8(const char *source,const char *destination)
276 {
277 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
278  return(rename(source,destination));
279 #else
280  int
281  status;
282 
283  wchar_t
284  *destination_wide,
285  *source_wide;
286 
287  source_wide=create_wchar_path(source);
288  if (source_wide == (wchar_t *) NULL)
289  return(-1);
290  destination_wide=create_wchar_path(destination);
291  if (destination_wide == (wchar_t *) NULL)
292  {
293  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
294  return(-1);
295  }
296  status=_wrename(source_wide,destination_wide);
297  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
298  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
299  return(status);
300 #endif
301 }
302 
303 static inline int set_file_timestamp(const char *path,struct stat *attributes)
304 {
305  int
306  status;
307 
308 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
309 #if defined(MAGICKCORE_HAVE_UTIMENSAT)
310 #if defined(__APPLE__) || defined(__NetBSD__)
311 #define st_atim st_atimespec
312 #define st_ctim st_ctimespec
313 #define st_mtim st_mtimespec
314 #endif
315 
316  struct timespec
317  timestamp[2];
318 
319  timestamp[0].tv_sec=attributes->st_atim.tv_sec;
320  timestamp[0].tv_nsec=attributes->st_atim.tv_nsec;
321  timestamp[1].tv_sec=attributes->st_mtim.tv_sec;
322  timestamp[1].tv_nsec=attributes->st_mtim.tv_nsec;
323  status=utimensat(AT_FDCWD,path,timestamp,0);
324 #else
325  struct utimbuf
326  timestamp;
327 
328  timestamp.actime=attributes->st_atime;
329  timestamp.modtime=attributes->st_mtime;
330  status=utime(path,&timestamp);
331 #endif
332 #else
333  HANDLE
334  handle;
335 
336  wchar_t
337  *path_wide;
338 
339  status=(-1);
340  path_wide=create_wchar_path(path);
341  if (path_wide == (WCHAR *) NULL)
342  return(status);
343  handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
344  FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
345  if (handle != (HANDLE) NULL)
346  {
347  FILETIME
348  creation_time,
349  last_access_time,
350  last_write_time;
351 
352  ULARGE_INTEGER
353  date_time;
354 
355  date_time.QuadPart=(ULONGLONG) (attributes->st_ctime*10000000LL)+
356  116444736000000000LL;
357  creation_time.dwLowDateTime=date_time.LowPart;
358  creation_time.dwHighDateTime=date_time.HighPart;
359  date_time.QuadPart=(ULONGLONG) (attributes->st_atime*10000000LL)+
360  116444736000000000LL;
361  last_access_time.dwLowDateTime=date_time.LowPart;
362  last_access_time.dwHighDateTime=date_time.HighPart;
363  date_time.QuadPart=(ULONGLONG) (attributes->st_mtime*10000000LL)+
364  116444736000000000LL;
365  last_write_time.dwLowDateTime=date_time.LowPart;
366  last_write_time.dwHighDateTime=date_time.HighPart;
367  status=SetFileTime(handle,&creation_time,&last_access_time,&last_write_time);
368  CloseHandle(handle);
369  status=0;
370  }
371  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
372 #endif
373  return(status);
374 }
375 
376 static inline int stat_utf8(const char *path,struct stat *attributes)
377 {
378 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
379  return(stat(path,attributes));
380 #else
381  int
382  status;
383 
384  wchar_t
385  *path_wide;
386 
387  path_wide=create_wchar_path(path);
388  if (path_wide == (WCHAR *) NULL)
389  return(-1);
390  status=_wstati64(path_wide,attributes);
391  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
392  return(status);
393 #endif
394 }
395 
396 #if defined(__cplusplus) || defined(c_plusplus)
397 }
398 #endif
399 
400 #endif