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)
32#define MagickPathTemplate "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
34extern MagickPrivate
char
35 **GetPathComponents(
const char *,
size_t *),
36 **ListFiles(
const char *,
const char *,
size_t *);
38extern MagickPrivate MagickBooleanType
39 GetExecutionPath(
char *,
const size_t),
40 ShredFile(
const char *);
42extern MagickPrivate ssize_t
43 GetMagickPageSize(
void);
45extern MagickPrivate
void
46 ChopPathComponents(
char *,
const size_t),
47 ExpandFilename(
char *);
49static inline MagickBooleanType GetPathSignature(
int file,
char signature[33])
58 hex[] =
"0123456789abcdef";
63#if defined(MAGICKCORE_WINDOWS_SUPPORT)
64 BY_HANDLE_FILE_INFORMATION file_info;
65 HANDLE handle = (HANDLE) _get_osfhandle(file);
66 if (handle == INVALID_HANDLE_VALUE)
68 if (GetFileInformationByHandle(handle,&file_info) == 0)
70 file_identity[0]=(uint64_t) file_info.dwVolumeSerialNumber;
71 file_identity[1]=((uint64_t) file_info.nFileIndexHigh << 32) |
72 (uint64_t) file_info.nFileIndexLow;
74 struct stat file_attributes;
75 if (fstat(file, &file_attributes) != 0)
77 file_identity[0]=(uint64_t) file_attributes.st_dev;
78 file_identity[1]=(uint64_t) file_attributes.st_ino;
85 for (shift=60; shift >= 0; shift-=4)
86 *p++=hex[(file_identity[i] >> shift) & 0xF];
92static inline int MagickReadDirectory(DIR *directory,
struct dirent *entry,
93 struct dirent **result)
97 *result=readdir(directory);
105#if defined(MAGICKCORE_WINDOWS_SUPPORT)
106static inline wchar_t *create_wchar_path(
const char *utf8)
114 count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
115 if ((count > MAX_PATH) && (strncmp(utf8,
"\\\\?\\",4) != 0) &&
116 (NTLongPathsEnabled() == MagickFalse))
119 buffer[MagickPathExtent];
125 (void) FormatLocaleString(buffer,MagickPathExtent,
"\\\\?\\%s",utf8);
127 longPath=(
wchar_t *) NTAcquireQuantumMemory((
size_t) count,
129 if (longPath == (
wchar_t *) NULL)
130 return((
wchar_t *) NULL);
131 count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
133 count=(int) GetShortPathNameW(longPath,shortPath,MAX_PATH);
134 longPath=(
wchar_t *) RelinquishMagickMemory(longPath);
135 if ((count < 5) || (count >= MAX_PATH))
136 return((
wchar_t *) NULL);
137 wide=(
wchar_t *) NTAcquireQuantumMemory((
size_t) count-3,
sizeof(*wide));
138 wcscpy(wide,shortPath+4);
141 wide=(
wchar_t *) NTAcquireQuantumMemory((
size_t) count,
sizeof(*wide));
142 if ((wide != (
wchar_t *) NULL) &&
143 (MultiByteToWideChar(CP_UTF8,0,utf8,-1,wide,count) == 0))
144 wide=(
wchar_t *) RelinquishMagickMemory(wide);
148static inline wchar_t *create_wchar_mode(
const char *mode)
156 count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
157 wide=(
wchar_t *) AcquireQuantumMemory((
size_t) count+1,
159 if (wide == (
wchar_t *) NULL)
160 return((
wchar_t *) NULL);
161 if (MultiByteToWideChar(CP_UTF8,0,mode,-1,wide,count) == 0)
163 wide=(
wchar_t *) RelinquishMagickMemory(wide);
164 return((
wchar_t *) NULL);
168 wide[count-1] = L
'N';
173static inline int access_utf8(
const char *path,
int mode)
175 if (path == (
const char *) NULL)
177#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
178 return(access(path,mode));
186 path_wide=create_wchar_path(path);
187 if (path_wide == (
wchar_t *) NULL)
189 status=_waccess(path_wide,mode);
190 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
195#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
196#define close_utf8 _close
198#define close_utf8 close
201static inline FILE *fopen_utf8(
const char *path,
const char *mode)
203#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
204 return(fopen(path,mode));
213 path_wide=create_wchar_path(path);
214 if (path_wide == (
wchar_t *) NULL)
215 return((FILE *) NULL);
216 mode_wide=create_wchar_mode(mode);
217 if (mode_wide == (
wchar_t *) NULL)
219 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
220 return((FILE *) NULL);
222 file=_wfopen(path_wide,mode_wide);
223 mode_wide=(
wchar_t *) RelinquishMagickMemory(mode_wide);
224 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
229static inline MagickBooleanType is_symlink_utf8(
const char *path)
231#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
232#if defined(MAGICKCORE_POSIX_SUPPORT)
236 if (lstat(path,&status) == -1)
238 return(S_ISLNK(status.st_mode) != 0 ? MagickTrue : MagickFalse);
243 return(NTIsSymlinkWide(path));
247static inline void getcwd_utf8(
char *path,
size_t extent)
249#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
253 directory=getcwd(path,extent);
257 wide_path[MagickPathExtent];
259 (void) _wgetcwd(wide_path,MagickPathExtent-1);
260 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(
int) extent,NULL,NULL);
264#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
269static inline int open_utf8(
const char *path,
int flags,mode_t mode)
271#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
272 return(open(path,flags,mode));
280 path_wide=create_wchar_path(path);
281 if (path_wide == (
wchar_t *) NULL)
284 status=_wopen(path_wide,flags | O_NOINHERIT,mode);
285 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
290static inline FILE *popen_utf8(
const char *command,
const char *type)
292#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
293 return(popen(command,type));
306 length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
309 length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
312 command_wide=(
wchar_t *) AcquireQuantumMemory((
size_t) length,
313 sizeof(*command_wide));
314 if (command_wide == (
wchar_t *) NULL)
316 length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
318 file=_wpopen(command_wide,type_wide);
319 command_wide=(
wchar_t *) RelinquishMagickMemory(command_wide);
324static inline char *realpath_utf8(
const char *path)
326#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
327#if defined(MAGICKCORE_HAVE_REALPATH)
328 return(realpath(path,(
char *) NULL));
330 return(AcquireString(path));
355 if (path == (
const char *) NULL)
356 return((
char *) NULL);
357 length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
359 return((
char *) NULL);
360 wide_path=(
wchar_t *) AcquireQuantumMemory(length,
sizeof(
wchar_t));
361 if (wide_path == (
wchar_t *) NULL)
362 return((
char *) NULL);
363 MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
367 full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
368 if (full_path_length == 0)
370 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
371 return((
char *) NULL);
373 full_path=(
wchar_t *) AcquireQuantumMemory(full_path_length,
sizeof(
wchar_t));
374 if (full_path == (
wchar_t *) NULL)
376 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
377 return((
char *) NULL);
379 GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
380 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
384 file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
385 FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
386 FILE_FLAG_BACKUP_SEMANTICS,NULL);
387 if (file_handle != INVALID_HANDLE_VALUE)
392 final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
393 FILE_NAME_NORMALIZED);
394 if (final_path_length == 0)
396 CloseHandle(file_handle);
397 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
398 return((
char *) NULL);
400 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
401 full_path=(
wchar_t *) AcquireQuantumMemory(final_path_length,
403 if (full_path == (
wchar_t *) NULL)
405 CloseHandle(file_handle);
406 return((
char *) NULL);
408 GetFinalPathNameByHandleW(file_handle,full_path,final_path_length,
409 FILE_NAME_NORMALIZED);
410 CloseHandle(file_handle);
415 clean_path=full_path;
416 if (wcsncmp(full_path,L
"\\\\?\\",4) == 0)
417 clean_path=full_path+4;
421 utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
422 if (utf8_length <= 0)
424 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
427 real_path=(
char *) AcquireQuantumMemory(utf8_length,
sizeof(
char));
428 if (real_path == (
char *) NULL)
430 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
433 WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
434 full_path=(
wchar_t *) RelinquishMagickMemory(full_path);
439static inline int remove_utf8(
const char *path)
441#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
442 return(unlink(path));
450 path_wide=create_wchar_path(path);
451 if (path_wide == (
wchar_t *) NULL)
453 status=_wremove(path_wide);
454 path_wide=(
wchar_t *) RelinquishMagickMemory(path_wide);
459static inline int rename_utf8(
const char *source,
const char *destination)
461#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
462 return(rename(source,destination));
471 source_wide=create_wchar_path(source);
472 if (source_wide == (
wchar_t *) NULL)
474 destination_wide=create_wchar_path(destination);
475 if (destination_wide == (
wchar_t *) NULL)
477 source_wide=(
wchar_t *) RelinquishMagickMemory(source_wide);
480 status=_wrename(source_wide,destination_wide);
481 destination_wide=(
wchar_t *) RelinquishMagickMemory(destination_wide);
482 source_wide=(
wchar_t *) RelinquishMagickMemory(source_wide);
487static inline int set_file_timestamp(
const char *path,
struct stat *attributes)
492#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
493#if defined(MAGICKCORE_HAVE_UTIMENSAT)
494#if defined(__APPLE__) || defined(__NetBSD__)
495#define st_atim st_atimespec
496#define st_ctim st_ctimespec
497#define st_mtim st_mtimespec
503 timestamp[0].tv_sec=attributes->st_atim.tv_sec;
504 timestamp[0].tv_nsec=attributes->st_atim.tv_nsec;
505 timestamp[1].tv_sec=attributes->st_mtim.tv_sec;
506 timestamp[1].tv_nsec=attributes->st_mtim.tv_nsec;
507 status=utimensat(AT_FDCWD,path,timestamp,0);
512 timestamp.actime=attributes->st_atime;
513 timestamp.modtime=attributes->st_mtime;
514 status=utime(path,×tamp);
524 path_wide=create_wchar_path(path);
525 if (path_wide == (WCHAR *) NULL)
527 handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
528 FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
529 if (handle != (HANDLE) NULL)
539 date_time.QuadPart=(ULONGLONG) (attributes->st_ctime*10000000LL)+
540 116444736000000000LL;
541 creation_time.dwLowDateTime=date_time.LowPart;
542 creation_time.dwHighDateTime=date_time.HighPart;
543 date_time.QuadPart=(ULONGLONG) (attributes->st_atime*10000000LL)+
544 116444736000000000LL;
545 last_access_time.dwLowDateTime=date_time.LowPart;
546 last_access_time.dwHighDateTime=date_time.HighPart;
547 date_time.QuadPart=(ULONGLONG) (attributes->st_mtime*10000000LL)+
548 116444736000000000LL;
549 last_write_time.dwLowDateTime=date_time.LowPart;
550 last_write_time.dwHighDateTime=date_time.HighPart;
551 status=SetFileTime(handle,&creation_time,&last_access_time,&last_write_time);
555 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
560static inline int stat_utf8(
const char *path,
struct stat *attributes)
562#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
563 return(stat(path,attributes));
571 path_wide=create_wchar_path(path);
572 if (path_wide == (WCHAR *) NULL)
574 status=_wstati64(path_wide,attributes);
575 path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
580#if defined(__cplusplus) || defined(c_plusplus)