18#ifndef MAGICKCORE_UTILITY_PRIVATE_H
19#define MAGICKCORE_UTILITY_PRIVATE_H
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)
28#if defined(__cplusplus) || defined(c_plusplus)
32extern MagickPrivate
char
33 **GetPathComponents(
const char *,
size_t *),
34 **ListFiles(
const char *,
const char *,
size_t *);
36extern MagickPrivate MagickBooleanType
37 GetExecutionPath(
char *,
const size_t),
38 ShredFile(
const char *);
40extern MagickPrivate ssize_t
41 GetMagickPageSize(
void);
43extern MagickPrivate
void
44 ChopPathComponents(
char *,
const size_t),
45 ExpandFilename(
char *);
47static inline int MagickReadDirectory(DIR *directory,
struct dirent *entry,
48 struct dirent **result)
52 *result=readdir(directory);
60#if defined(MAGICKCORE_WINDOWS_SUPPORT)
61static inline wchar_t *create_wchar_path(
const char *utf8)
69 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
70 if ((count > MAX_PATH) && (strncmp(utf8,
"\\\\?\\",4) != 0) &&
71 (NTLongPathsEnabled() == MagickFalse))
74 buffer[MagickPathExtent];
80 (void) FormatLocaleString(buffer,MagickPathExtent,
"\\\\?\\%s",utf8);
82 longPath=(
wchar_t *) NTAcquireQuantumMemory((
size_t) count,
84 if (longPath == (
wchar_t *) NULL)
85 return((
wchar_t *) NULL);
86 count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
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);
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);
103static inline wchar_t *create_wchar_mode(
const char *mode)
111 count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
112 wide=(
wchar_t *) AcquireQuantumMemory((
size_t) count+1,
114 if (wide == (
wchar_t *) NULL)
115 return((
wchar_t *) NULL);
116 if (MultiByteToWideChar(CP_UTF8,0,mode,-1,wide,count) == 0)
118 wide=(
wchar_t *) RelinquishMagickMemory(wide);
119 return((
wchar_t *) NULL);
123 wide[count-1] = L
'N';
128static inline int access_utf8(
const char *path,
int mode)
130 if (path == (
const char *) NULL)
132#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
133 return(access(path,mode));
141 path_wide=create_wchar_path(path);
142 if (path_wide == (
wchar_t *) NULL)
144 status=_waccess(path_wide,mode);
145 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
150static inline FILE *fopen_utf8(
const char *path,
const char *mode)
152#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
153 return(fopen(path,mode));
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)
168 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
169 return((FILE *) NULL);
171 file=_wfopen(path_wide,mode_wide);
172 mode_wide=(
wchar_t *) RelinquishMagickMemory(mode_wide);
173 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
178static inline void getcwd_utf8(
char *path,
size_t extent)
180#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
184 directory=getcwd(path,extent);
188 wide_path[MagickPathExtent];
190 (void) _wgetcwd(wide_path,MagickPathExtent-1);
191 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(
int) extent,NULL,NULL);
195#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
200static inline int open_utf8(
const char *path,
int flags,mode_t mode)
202#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
203 return(open(path,flags,mode));
211 path_wide=create_wchar_path(path);
212 if (path_wide == (
wchar_t *) NULL)
215 status=_wopen(path_wide,flags | O_NOINHERIT,mode);
216 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
221static inline FILE *popen_utf8(
const char *command,
const char *type)
223#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
224 return(popen(command,type));
237 length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
240 length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
243 command_wide=(
wchar_t *) AcquireQuantumMemory((
size_t) length,
244 sizeof(*command_wide));
245 if (command_wide == (
wchar_t *) NULL)
247 length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
249 file=_wpopen(command_wide,type_wide);
250 command_wide=(
wchar_t *) RelinquishMagickMemory(command_wide);
255static inline char *realpath_utf8(
const char *path)
257#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
258#if defined(MAGICKCORE_HAVE_REALPATH)
259 return(realpath(path,(
char *) NULL));
261 return(AcquireString(path));
286 if (path == (
const char *) NULL)
287 return((
char *) NULL);
288 length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
290 return((
char *) NULL);
291 wide_path=(
wchar_t *) AcquireQuantumMemory(length,
sizeof(
wchar_t));
292 if (wide_path == (
wchar_t *) NULL)
293 return((
char *) NULL);
294 MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
298 full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
299 if (full_path_length == 0)
301 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
302 return((
char *) NULL);
304 full_path=(
wchar_t *) AcquireQuantumMemory(full_path_length,
sizeof(
wchar_t));
305 if (full_path == (
wchar_t *) NULL)
307 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
308 return((
char *) NULL);
310 GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
311 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
315 file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
316 FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
317 FILE_FLAG_BACKUP_SEMANTICS,NULL);
318 if (file_handle != INVALID_HANDLE_VALUE)
323 final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
324 FILE_NAME_NORMALIZED);
325 if (final_path_length == 0)
327 CloseHandle(file_handle);
328 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
329 return((
char *) NULL);
331 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
332 full_path=(
wchar_t *) AcquireQuantumMemory(final_path_length,
334 if (full_path == (
wchar_t *) NULL)
336 CloseHandle(file_handle);
337 return((
char *) NULL);
339 GetFinalPathNameByHandleW(file_handle,full_path,final_path_length,
340 FILE_NAME_NORMALIZED);
341 CloseHandle(file_handle);
346 clean_path=full_path;
347 if (wcsncmp(full_path,L
"\\\\?\\",4) == 0)
348 clean_path=full_path+4;
352 utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
353 if (utf8_length <= 0)
355 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
358 real_path=(
char *) AcquireQuantumMemory(utf8_length,
sizeof(
char));
359 if (real_path == (
char *) NULL)
361 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
364 WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
365 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
370static inline int remove_utf8(
const char *path)
372#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
373 return(unlink(path));
381 path_wide=create_wchar_path(path);
382 if (path_wide == (
wchar_t *) NULL)
384 status=_wremove(path_wide);
385 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
390static inline int rename_utf8(
const char *source,
const char *destination)
392#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
393 return(rename(source,destination));
402 source_wide=create_wchar_path(source);
403 if (source_wide == (
wchar_t *) NULL)
405 destination_wide=create_wchar_path(destination);
406 if (destination_wide == (
wchar_t *) NULL)
408 source_wide=(
wchar_t *) RelinquishMagickMemory(source_wide);
411 status=_wrename(source_wide,destination_wide);
412 destination_wide=(
wchar_t *) RelinquishMagickMemory(destination_wide);
413 source_wide=(
wchar_t *) RelinquishMagickMemory(source_wide);
418static inline int set_file_timestamp(
const char *path,
struct stat *attributes)
423#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
424#if defined(MAGICKCORE_HAVE_UTIMENSAT)
425#if defined(__APPLE__) || defined(__NetBSD__)
426#define st_atim st_atimespec
427#define st_ctim st_ctimespec
428#define st_mtim st_mtimespec
434 timestamp[0].tv_sec=attributes->st_atim.tv_sec;
435 timestamp[0].tv_nsec=attributes->st_atim.tv_nsec;
436 timestamp[1].tv_sec=attributes->st_mtim.tv_sec;
437 timestamp[1].tv_nsec=attributes->st_mtim.tv_nsec;
438 status=utimensat(AT_FDCWD,path,timestamp,0);
443 timestamp.actime=attributes->st_atime;
444 timestamp.modtime=attributes->st_mtime;
445 status=utime(path,×tamp);
455 path_wide=create_wchar_path(path);
456 if (path_wide == (WCHAR *) NULL)
458 handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
459 FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
460 if (handle != (HANDLE) NULL)
470 date_time.QuadPart=(ULONGLONG) (attributes->st_ctime*10000000LL)+
471 116444736000000000LL;
472 creation_time.dwLowDateTime=date_time.LowPart;
473 creation_time.dwHighDateTime=date_time.HighPart;
474 date_time.QuadPart=(ULONGLONG) (attributes->st_atime*10000000LL)+
475 116444736000000000LL;
476 last_access_time.dwLowDateTime=date_time.LowPart;
477 last_access_time.dwHighDateTime=date_time.HighPart;
478 date_time.QuadPart=(ULONGLONG) (attributes->st_mtime*10000000LL)+
479 116444736000000000LL;
480 last_write_time.dwLowDateTime=date_time.LowPart;
481 last_write_time.dwHighDateTime=date_time.HighPart;
482 status=SetFileTime(handle,&creation_time,&last_access_time,&last_write_time);
486 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
491static inline int stat_utf8(
const char *path,
struct stat *attributes)
493#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
494 return(stat(path,attributes));
502 path_wide=create_wchar_path(path);
503 if (path_wide == (WCHAR *) NULL)
505 status=_wstati64(path_wide,attributes);
506 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
511#if defined(__cplusplus) || defined(c_plusplus)