Commit afc7d4aff for imagemagick.org

commit afc7d4aff34cfb085bfdae303f0b69ceb653d839
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Fri Feb 6 12:00:38 2026 +0100

    Moved all windows implementations in utility-private to nt-base-private.

diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index addf50b5a..48fd4e66f 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -3254,7 +3254,7 @@ static inline gzFile gzopen_utf8(const char *path,const char *mode)
    wchar_t
      *path_wide;

-   path_wide=create_wchar_path(path);
+   path_wide=NTCreateWidePath(path);
    if (path_wide == (wchar_t *) NULL)
      return((gzFile) NULL);
    file=gzopen_w(path_wide,mode);
diff --git a/MagickCore/nt-base-private.h b/MagickCore/nt-base-private.h
index 2b9b4525d..e839f42d6 100644
--- a/MagickCore/nt-base-private.h
+++ b/MagickCore/nt-base-private.h
@@ -114,6 +114,9 @@ struct timezone
     tz_minuteswest,
     tz_dsttime;
 };
+
+typedef int
+  mode_t;
 #endif

 #endif
@@ -132,6 +135,9 @@ static inline void *NTAcquireQuantumMemory(const size_t count,
   return(AcquireMagickMemory(size));
 }

+extern MagickExport char
+  *NTRealPathWide(const char *);
+
 extern MagickPrivate char
   *NTGetEnvironmentValue(const char *);

@@ -151,6 +157,18 @@ extern MagickPrivate double
   NTElapsedTime(void),
   NTErf(double);

+extern MagickExport FILE
+  *NTOpenFileWide(const char *,const char *),
+  *NTOpenPipeWide(const char *,const char *);
+
+extern MagickExport int
+  NTAccessWide(const char *,int),
+  NTOpenWide(const char *,int,mode_t),
+  NTRemoveWide(const char *),
+  NTRenameWide(const char *, const char *),
+  NTSetFileTimestamp(const char *,struct stat *),
+  NTStatWide(const char *,struct stat *);
+
 extern MagickPrivate int
 #if !defined(__MINGW32__)
   gettimeofday(struct timeval *,struct timezone *),
@@ -189,6 +207,9 @@ extern MagickPrivate void
   NTWindowsGenesis(void),
   NTWindowsTerminus(void);

+extern MagickExport wchar_t
+  *NTCreateWidePath(const char *);
+
 #endif /* !XS_VERSION */

 #endif /* MAGICKCORE_WINDOWS_SUPPORT */
diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c
index d9109aacd..c9e138199 100644
--- a/MagickCore/nt-base.c
+++ b/MagickCore/nt-base.c
@@ -436,6 +436,46 @@ MagickPrivate int gettimeofday (struct timeval *time_value,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   N T A c c e s s W i d e                                                   %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NTAccessWide() checks the file accessibility of a file path.
+#
+# The format of the NTAccessWide method is:
+%
+%     int NTAccessWide(const char *path, int mode)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+%    o mode: the accessibility mode.
+%
+*/
+MagickExport int NTAccessWide(const char *path, int mode)
+{
+  int
+    status;
+
+  wchar_t
+    *path_wide;
+
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (wchar_t *) NULL)
+    return(-1);
+  status=_waccess(path_wide,mode);
+  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
+  return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   N T A r g v T o U T F 8                                                   %
 %                                                                             %
 %                                                                             %
@@ -540,6 +580,74 @@ MagickPrivate int NTCloseLibrary(void *handle)
   return(FreeLibrary((HINSTANCE) handle) ? 0 : 1);
 }

+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   N T C r e a t e W i d e P a t h                                           %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTCreateWidePath() returns the wide-character version of the specified
+%  UTF-8 path.
+%
+%  The format of the NTCreateWidePath method is:
+%
+%      void NTCreateWidePath(void *handle)
+%
+%  A description of each parameter follows:
+%
+%    o utf8: Specifies a handle to a previously loaded dynamic module.
+%
+*/
+MagickExport wchar_t* NTCreateWidePath(const char *utf8)
+{
+  int
+    count;
+
+  wchar_t
+    *wide;
+
+  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
+  if ((count > MAX_PATH) && (strncmp(utf8,"\\\\?\\",4) != 0) &&
+      (NTLongPathsEnabled() == MagickFalse))
+    {
+      char
+        buffer[MagickPathExtent];
+
+      wchar_t
+        shortPath[MAX_PATH],
+        *longPath;
+
+      size_t
+        length;
+
+      (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8);
+      count+=4;
+      longPath=(wchar_t *) NTAcquireQuantumMemory((size_t) count,
+        sizeof(*longPath));
+      if (longPath == (wchar_t *) NULL)
+        return((wchar_t *) NULL);
+      count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
+      if (count != 0)
+        count=(int) GetShortPathNameW(longPath,shortPath,MAX_PATH);
+      longPath=(wchar_t *) RelinquishMagickMemory(longPath);
+      if ((count < 5) || (count >= MAX_PATH))
+        return((wchar_t *) NULL);
+      length=(size_t) count-3;
+      wide=(wchar_t *) NTAcquireQuantumMemory(length,sizeof(*wide));
+      wcscpy_s(wide,length,shortPath+4);
+      return(wide);
+    }
+  wide=(wchar_t *) NTAcquireQuantumMemory((size_t) count,sizeof(*wide));
+  if ((wide != (wchar_t *) NULL) &&
+      (MultiByteToWideChar(CP_UTF8,0,utf8,-1,wide,count) == 0))
+    wide=(wchar_t *) RelinquishMagickMemory(wide);
+  return(wide);
+}

 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -645,7 +753,6 @@ MagickPrivate double NTErf(double x)
   return(sign*y);
 }

-
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -972,8 +1079,7 @@ void *NTGetLibrarySymbol(void *handle,const char *name)
     return((void *) NULL);
   return((void *) proc_address);
 }
-
-
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -1734,7 +1840,6 @@ MagickPrivate DIR *NTOpenDirectory(const char *path)
 %      is to be loaded.
 %
 */
-
 static UINT ChangeErrorMode(void)
 {
   typedef UINT
@@ -1771,7 +1876,7 @@ static inline void *NTLoadLibrary(const char *filename)
     *path;

   library=(void *) NULL;
-  path=create_wchar_path(filename);
+  path=NTCreateWidePath(filename);
   if (path != (wchar_t *) NULL)
     {
       library=LoadLibraryExW(path,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -1826,6 +1931,177 @@ MagickPrivate void *NTOpenLibrary(const char *filename)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%  N T O p e n F i l e W i d e                                                %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTOpenFileWide() opens a file and returns a file pointer.
+%
+%  The format of the NTOpenFileWide method is:
+%
+%      FILE *NTOpenFileWide(const char* path, const char* mode)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+%    o mode: the file open mode.
+%
+*/
+static inline wchar_t *create_wchar_mode(const char *mode)
+{
+  int
+    count;
+
+  wchar_t
+    *wide;
+
+  count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
+  wide=(wchar_t *) AcquireQuantumMemory((size_t) count+1,
+    sizeof(*wide));
+  if (wide == (wchar_t *) NULL)
+    return((wchar_t *) NULL);
+  if (MultiByteToWideChar(CP_UTF8,0,mode,-1,wide,count) == 0)
+    {
+      wide=(wchar_t *) RelinquishMagickMemory(wide);
+      return((wchar_t *) NULL);
+    }
+  /* Specifies that the file is not inherited by child processes */
+  wide[count] = L'\0';
+  wide[count-1] = L'N';
+  return(wide);
+}
+
+MagickExport FILE *NTOpenFileWide(const char* path, const char* mode)
+{
+  FILE
+    *file;
+
+  wchar_t
+    *mode_wide,
+    *path_wide;
+
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (wchar_t *) NULL)
+    return((FILE *) NULL);
+  mode_wide=create_wchar_mode(mode);
+  if (mode_wide == (wchar_t *) NULL)
+    {
+      path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
+      return((FILE *) NULL);
+    }
+  if (_wfopen_s(&file,path_wide,mode_wide) != 0)
+    file=(FILE *) NULL;
+  mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
+  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
+  return(file);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%  N T O p e n P i p e W i d e                                                %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTOpenPipeWide() opens a pipe and returns a file pointer.
+%
+%  The format of the NTOpenPipeWide method is:
+%
+%      FILE *NTOpenPipeWide(const char* command, const char* type)
+%
+%  A description of each parameter follows:
+%
+%    o command: the command to execute.
+%
+%    o type: the file open mode.
+%
+*/
+MagickExport FILE *NTOpenPipeWide(const char *command,const char *type)
+{
+  FILE
+    *file;
+
+  int
+    length;
+
+  wchar_t
+    *command_wide,
+    type_wide[5];
+
+  file=(FILE *) NULL;
+  length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
+  if (length == 0)
+    return(file);
+  length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
+  if (length == 0)
+    return(file);
+  command_wide=(wchar_t *) AcquireQuantumMemory((size_t) length,
+    sizeof(*command_wide));
+  if (command_wide == (wchar_t *) NULL)
+    return(file);
+  length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
+  if (length != 0)
+    file=_wpopen(command_wide,type_wide);
+  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
+  return(file);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%  N T O p e n W i d e                                                        %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTOpenWide() opens the file specified by path and mode.
+%
+%  The format of the NTOpenWide method is:
+%
+%      FILE *NTOpenWide(const char* path, const char* mode)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+%    o flags: the file open flags.
+%
+%    o mode: the file open mode.
+%
+*/
+MagickExport int NTOpenWide(const char* path,int flags,mode_t mode)
+{
+  int
+    file_handle,
+    status;
+
+  wchar_t
+    *path_wide;
+
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (wchar_t *) NULL)
+    return(-1);
+  /* O_NOINHERIT specifies that the file is not inherited by child processes */
+  status=_wsopen_s(&file_handle,path_wide,flags | O_NOINHERIT,_SH_DENYNO,mode);
+  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
+  return(status == 0 ? file_handle : -1);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %    N T R e a d D i r e c t o r y                                            %
 %                                                                             %
 %                                                                             %
@@ -1875,6 +2151,135 @@ MagickPrivate struct dirent *NTReadDirectory(DIR *entry)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%    N T R e a l P a t h W i d e                                              %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTRealPathWide returns the absolute path of the specified path.
+%
+%  The format of the NTRealPathWide method is:
+%
+%      char *NTRealPathWide(const char *path)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+*/
+MagickExport char *NTRealPathWide(const char *path)
+{
+  char
+    *real_path;
+
+  DWORD
+    final_path_length,
+    full_path_length;
+
+  HANDLE
+    file_handle;
+
+  int
+    length,
+    utf8_length;
+
+  wchar_t
+    *clean_path,
+    *full_path,
+    *wide_path;
+
+  /*
+    Convert UTF-8 to UTF-16.
+  */
+  if (path == (const char *) NULL)
+    return((char *) NULL);
+  length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
+  if (length <= 0)
+    return((char *) NULL);
+  wide_path=(wchar_t *) AcquireQuantumMemory(length,sizeof(wchar_t));
+  if (wide_path == (wchar_t *) NULL)
+    return((char *) NULL);
+  MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
+  /*
+    Normalize syntactically.
+  */
+  full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
+  if (full_path_length == 0)
+    {
+      wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
+      return((char *) NULL);
+    }
+  full_path=(wchar_t *) AcquireQuantumMemory(full_path_length,sizeof(wchar_t));
+  if (full_path == (wchar_t *) NULL)
+    {
+      wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
+      return((char *) NULL);
+    }
+  GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
+  wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
+  /*
+    Open the file/directory to resolve symlinks.
+  */
+  file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
+    FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
+    FILE_FLAG_BACKUP_SEMANTICS,NULL);
+  if (file_handle != INVALID_HANDLE_VALUE)
+    {
+      /*
+        Resolve final canonical path.
+      */
+      final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
+        FILE_NAME_NORMALIZED);
+      if (final_path_length == 0)
+        {
+          CloseHandle(file_handle);
+          full_path=(wchar_t *) RelinquishMagickMemory(full_path);
+          return((char *) NULL);
+        }
+      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
+      full_path=(wchar_t *) AcquireQuantumMemory(final_path_length,
+        sizeof(wchar_t));
+      if (full_path == (wchar_t *) NULL)
+        {
+          CloseHandle(file_handle);
+          return((char *) NULL);
+        }
+      GetFinalPathNameByHandleW(file_handle,full_path,final_path_length,
+        FILE_NAME_NORMALIZED);
+      CloseHandle(file_handle);
+    }
+  /*
+    Remove \\?\ prefix for POSIX-like behavior.
+  */
+  clean_path=full_path;
+  if (wcsncmp(full_path,L"\\\\?\\",4) == 0)
+    clean_path=full_path+4;
+  /*
+    Convert UTF-16 to UTF-8.
+  */
+  utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
+  if (utf8_length <= 0)
+    {
+      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
+      return NULL;
+    }
+  real_path=(char *) AcquireQuantumMemory(utf8_length,sizeof(char));
+  if (real_path == (char *) NULL)
+    {
+      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
+      return NULL;
+    }
+  WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
+  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
+  return(real_path);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   N T R e g i s t r y K e y L o o k u p                                     %
 %                                                                             %
 %                                                                             %
@@ -1924,6 +2329,92 @@ MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   N T R e m o v e W i d e                                                   %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTRemoveWide() removes the specified file.
+%
+%  The format of the NTRemoveWide method is:
+%
+%      int NTRemoveWide(const char *path)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+*/
+MagickExport int NTRemoveWide(const char *path)
+{
+  int
+    status;
+
+  wchar_t
+    *path_wide;
+
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (wchar_t *) NULL)
+    return(-1);
+  status=_wremove(path_wide);
+  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
+  return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   N T R e n a m e W i d e                                                   %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTRenameWide() renames a file.
+%
+%  The format of the NTRenameWide method is:
+%
+%      int NTRenameWide(const char *source, const char *destination)
+%
+%  A description of each parameter follows:
+%
+%    o source: the source file path.
+%
+%    o destination: the destination file path.
+%
+*/
+MagickExport int NTRenameWide(const char* source, const char* destination)
+{
+ int
+   status;
+
+  wchar_t
+    *destination_wide,
+    *source_wide;
+
+  source_wide=NTCreateWidePath(source);
+  if (source_wide == (wchar_t *) NULL)
+    return(-1);
+  destination_wide=NTCreateWidePath(destination);
+  if (destination_wide == (wchar_t *) NULL)
+    {
+      source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
+      return(-1);
+    }
+  status=_wrename(source_wide,destination_wide);
+  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
+  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
+  return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   N T R e p o r t E v e n t                                                 %
 %                                                                             %
 %                                                                             %
@@ -2059,6 +2550,117 @@ MagickPrivate unsigned char *NTResourceToBlob(const char *id)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   NT S e t F i l e T i m e s t a m p                                        %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTSetFileTimestamp() sets the file timestamps for a specified file.
+%
+%  The format of the NTSetFileTimestamp method is:
+%
+%      int NTSetFileTimestamp(const char *path, struct stat *attributes)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+%    o attributes: the file attributes.
+%
+*/
+MagickExport int NTSetFileTimestamp(const char *path, struct stat *attributes)
+{
+  HANDLE
+    handle;
+
+  int
+    status;
+
+  wchar_t
+    *path_wide;
+
+  status=(-1);
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (WCHAR *) NULL)
+    return(status);
+  handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
+    FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
+  if (handle != (HANDLE) NULL)
+    {
+      FILETIME
+        creation_time,
+        last_access_time,
+        last_write_time;
+
+      ULARGE_INTEGER
+        date_time;
+
+      date_time.QuadPart=(ULONGLONG) (attributes->st_ctime*10000000LL)+
+        116444736000000000LL;
+      creation_time.dwLowDateTime=date_time.LowPart;
+      creation_time.dwHighDateTime=date_time.HighPart;
+      date_time.QuadPart=(ULONGLONG) (attributes->st_atime*10000000LL)+
+        116444736000000000LL;
+      last_access_time.dwLowDateTime=date_time.LowPart;
+      last_access_time.dwHighDateTime=date_time.HighPart;
+      date_time.QuadPart=(ULONGLONG) (attributes->st_mtime*10000000LL)+
+        116444736000000000LL;
+      last_write_time.dwLowDateTime=date_time.LowPart;
+      last_write_time.dwHighDateTime=date_time.HighPart;
+      status=SetFileTime(handle,&creation_time,&last_access_time,&last_write_time);
+      CloseHandle(handle);
+      status=0;
+    }
+  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
+  return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   N T S t a t W i d e                                                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTStatWide() gets the file attributes for a specified file.
+%
+%  The format of the NTStatWide method is:
+%
+%      int NTStatWide(const char *path,struct stat *attributes)
+%
+%  A description of each parameter follows:
+%
+%    o path: the file path.
+%
+%    o attributes: the file attributes.
+%
+*/
+MagickExport int NTStatWide(const char *path,struct stat *attributes)
+{
+  int
+    status;
+
+  wchar_t
+    *path_wide;
+
+  path_wide=NTCreateWidePath(path);
+  if (path_wide == (WCHAR *) NULL)
+    return(-1);
+  status=wstat(path_wide,attributes);
+  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
+  return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   N T S y s t e m C o m m a n d                                             %
 %                                                                             %
 %                                                                             %
@@ -2441,7 +3043,6 @@ MagickPrivate void NTWarningHandler(const ExceptionType severity,
 %      void NTWindowsGenesis(void)
 %
 */
-
 MagickPrivate void NTWindowsGenesis(void)
 {
   char
@@ -2492,8 +3093,7 @@ MagickPrivate void NTWindowsGenesis(void)
   }
 #endif
 }
-
-
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h
index d8b68e0e1..dea9cf71a 100644
--- a/MagickCore/utility-private.h
+++ b/MagickCore/utility-private.h
@@ -56,82 +56,6 @@ static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
   return(errno);
 }

-/*
-  Windows UTF8 compatibility methods.
-*/
-
-#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__)
-static inline wchar_t *create_wchar_path(const char *utf8)
-{
-  int
-    count;
-
-  wchar_t
-    *wide;
-
-  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
-  if ((count > MAX_PATH) && (strncmp(utf8,"\\\\?\\",4) != 0) &&
-      (NTLongPathsEnabled() == MagickFalse))
-    {
-      char
-        buffer[MagickPathExtent];
-
-      wchar_t
-        shortPath[MAX_PATH],
-        *longPath;
-
-      size_t
-        length;
-
-      (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8);
-      count+=4;
-      longPath=(wchar_t *) NTAcquireQuantumMemory((size_t) count,
-        sizeof(*longPath));
-      if (longPath == (wchar_t *) NULL)
-        return((wchar_t *) NULL);
-      count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
-      if (count != 0)
-        count=(int) GetShortPathNameW(longPath,shortPath,MAX_PATH);
-      longPath=(wchar_t *) RelinquishMagickMemory(longPath);
-      if ((count < 5) || (count >= MAX_PATH))
-        return((wchar_t *) NULL);
-      length=(size_t) count-3;
-      wide=(wchar_t *) NTAcquireQuantumMemory(length,sizeof(*wide));
-      wcscpy_s(wide,length,shortPath+4);
-      return(wide);
-    }
-  wide=(wchar_t *) NTAcquireQuantumMemory((size_t) count,sizeof(*wide));
-  if ((wide != (wchar_t *) NULL) &&
-      (MultiByteToWideChar(CP_UTF8,0,utf8,-1,wide,count) == 0))
-    wide=(wchar_t *) RelinquishMagickMemory(wide);
-  return(wide);
-}
-
-static inline wchar_t *create_wchar_mode(const char *mode)
-{
-  int
-    count;
-
-  wchar_t
-    *wide;
-
-  count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
-  wide=(wchar_t *) AcquireQuantumMemory((size_t) count+1,
-    sizeof(*wide));
-  if (wide == (wchar_t *) NULL)
-    return((wchar_t *) NULL);
-  if (MultiByteToWideChar(CP_UTF8,0,mode,-1,wide,count) == 0)
-    {
-      wide=(wchar_t *) RelinquishMagickMemory(wide);
-      return((wchar_t *) NULL);
-    }
-  /* Specifies that the file is not inherited by child processes */
-  wide[count] = L'\0';
-  wide[count-1] = L'N';
-  return(wide);
-}
-#endif
-
 static inline int access_utf8(const char *path,int mode)
 {
   if (path == (const char *) NULL)
@@ -139,18 +63,7 @@ static inline int access_utf8(const char *path,int mode)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(access(path,mode));
 #else
-  int
-    status;
-
-  wchar_t
-    *path_wide;
-
-  path_wide=create_wchar_path(path);
-  if (path_wide == (wchar_t *) NULL)
-    return(-1);
-  status=_waccess(path_wide,mode);
-  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
-  return(status);
+  return(NTAccessWide(path,mode));
 #endif
 }

@@ -165,71 +78,16 @@ static inline FILE *fopen_utf8(const char *path,const char *mode)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(fopen(path,mode));
 #else
-  FILE
-    *file;
-
-  wchar_t
-    *mode_wide,
-    *path_wide;
-
-  path_wide=create_wchar_path(path);
-  if (path_wide == (wchar_t *) NULL)
-    return((FILE *) NULL);
-  mode_wide=create_wchar_mode(mode);
-  if (mode_wide == (wchar_t *) NULL)
-    {
-      path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
-      return((FILE *) NULL);
-    }
-  if (_wfopen_s(&file,path_wide,mode_wide) != 0)
-    file=(FILE *) NULL;
-  mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
-  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
-  return(file);
-#endif
-}
-
-static inline void getcwd_utf8(char *path,size_t extent)
-{
-#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
-  char
-    *directory;
-
-   directory=getcwd(path,extent);
-   (void) directory;
-#else
-  wchar_t
-    wide_path[MagickPathExtent];
-
-  (void) _wgetcwd(wide_path,MagickPathExtent-1);
-  (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
+  return(NTOpenFileWide(path,mode));
 #endif
 }

-#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
-typedef int
-  mode_t;
-#endif
-
 static inline int open_utf8(const char *path,int flags,mode_t mode)
 {
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(open(path,flags,mode));
 #else
-  int
-    file_handle,
-    status;
-
-  wchar_t
-    *path_wide;
-
-  path_wide=create_wchar_path(path);
-  if (path_wide == (wchar_t *) NULL)
-    return(-1);
-  /* O_NOINHERIT specifies that the file is not inherited by child processes */
-  status=_wsopen_s(&file_handle,path_wide,flags | O_NOINHERIT,_SH_DENYNO,mode);
-  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
-  return(status == 0 ? file_handle : -1);
+  return(NTOpenWide(path,flags,mode));
 #endif
 }

@@ -238,32 +96,7 @@ static inline FILE *popen_utf8(const char *command,const char *type)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(popen(command,type));
 #else
-  FILE
-    *file;
-
-  int
-    length;
-
-  wchar_t
-    *command_wide,
-    type_wide[5];
-
-  file=(FILE *) NULL;
-  length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
-  if (length == 0)
-    return(file);
-  length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
-  if (length == 0)
-    return(file);
-  command_wide=(wchar_t *) AcquireQuantumMemory((size_t) length,
-    sizeof(*command_wide));
-  if (command_wide == (wchar_t *) NULL)
-    return(file);
-  length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
-  if (length != 0)
-    file=_wpopen(command_wide,type_wide);
-  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
-  return(file);
+  return(NTOpenPipeWide(command,type));
 #endif
 }

@@ -276,109 +109,7 @@ static inline char *realpath_utf8(const char *path)
   return(AcquireString(path));
 #endif
 #else
-  char
-    *real_path;
-
-  DWORD
-    final_path_length,
-    full_path_length;
-
-  HANDLE
-    file_handle;
-
-  int
-    length,
-    utf8_length;
-
-  wchar_t
-    *clean_path,
-    *full_path,
-    *wide_path;
-
-  /*
-    Convert UTF-8 to UTF-16.
-  */
-  if (path == (const char *) NULL)
-    return((char *) NULL);
-  length=MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
-  if (length <= 0)
-    return((char *) NULL);
-  wide_path=(wchar_t *) AcquireQuantumMemory(length,sizeof(wchar_t));
-  if (wide_path == (wchar_t *) NULL)
-    return((char *) NULL);
-  MultiByteToWideChar(CP_UTF8,0,path,-1,wide_path,length);
-  /*
-    Normalize syntactically.
-  */
-  full_path_length=GetFullPathNameW(wide_path,0,NULL,NULL);
-  if (full_path_length == 0)
-    {
-      wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
-      return((char *) NULL);
-    }
-  full_path=(wchar_t *) AcquireQuantumMemory(full_path_length,sizeof(wchar_t));
-  if (full_path == (wchar_t *) NULL)
-    {
-      wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
-      return((char *) NULL);
-    }
-  GetFullPathNameW(wide_path,full_path_length,full_path,NULL);
-  wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
-  /*
-    Open the file/directory to resolve symlinks.
-  */
-  file_handle=CreateFileW(full_path,GENERIC_READ,FILE_SHARE_READ |
-    FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,
-    FILE_FLAG_BACKUP_SEMANTICS,NULL);
-  if (file_handle != INVALID_HANDLE_VALUE)
-    {
-      /*
-        Resolve final canonical path.
-      */
-      final_path_length=GetFinalPathNameByHandleW(file_handle,NULL,0,
-        FILE_NAME_NORMALIZED);
-      if (final_path_length == 0)
-        {
-          CloseHandle(file_handle);
-          full_path=(wchar_t *) RelinquishMagickMemory(full_path);
-          return((char *) NULL);
-        }
-      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
-      full_path=(wchar_t *) AcquireQuantumMemory(final_path_length,
-        sizeof(wchar_t));
-      if (full_path == (wchar_t *) NULL)
-        {
-          CloseHandle(file_handle);
-          return((char *) NULL);
-        }
-      GetFinalPathNameByHandleW(file_handle,full_path,final_path_length,
-        FILE_NAME_NORMALIZED);
-      CloseHandle(file_handle);
-    }
-  /*
-    Remove \\?\ prefix for POSIX-like behavior.
-  */
-  clean_path=full_path;
-  if (wcsncmp(full_path,L"\\\\?\\",4) == 0)
-    clean_path=full_path+4;
-  /*
-    Convert UTF-16 to UTF-8.
-  */
-  utf8_length=WideCharToMultiByte(CP_UTF8,0,clean_path,-1,NULL,0,NULL,NULL);
-  if (utf8_length <= 0)
-    {
-      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
-      return NULL;
-    }
-  real_path=(char *) AcquireQuantumMemory(utf8_length,sizeof(char));
-  if (real_path == (char *) NULL)
-    {
-      full_path=(wchar_t *) RelinquishMagickMemory(full_path);
-      return NULL;
-    }
-  WideCharToMultiByte(CP_UTF8,0,clean_path,-1,real_path,utf8_length,NULL,NULL);
-  full_path=(wchar_t *) RelinquishMagickMemory(full_path);
-  return(real_path);
+  return(NTRealPathWide(path));
 #endif
 }

@@ -387,18 +118,7 @@ static inline int remove_utf8(const char *path)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(unlink(path));
 #else
-  int
-    status;
-
-  wchar_t
-    *path_wide;
-
-  path_wide=create_wchar_path(path);
-  if (path_wide == (wchar_t *) NULL)
-    return(-1);
-  status=_wremove(path_wide);
-  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
-  return(status);
+  return(NTRemoveWide(path));
 #endif
 }

@@ -407,26 +127,7 @@ static inline int rename_utf8(const char *source,const char *destination)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(rename(source,destination));
 #else
- int
-   status;
-
-  wchar_t
-    *destination_wide,
-    *source_wide;
-
-  source_wide=create_wchar_path(source);
-  if (source_wide == (wchar_t *) NULL)
-    return(-1);
-  destination_wide=create_wchar_path(destination);
-  if (destination_wide == (wchar_t *) NULL)
-    {
-      source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
-      return(-1);
-    }
-  status=_wrename(source_wide,destination_wide);
-  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
-  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
-  return(status);
+  return(NTRenameWide(source,destination));
 #endif
 }

@@ -460,45 +161,7 @@ static inline int set_file_timestamp(const char *path,struct stat *attributes)
   status=utime(path,&timestamp);
 #endif
 #else
-  HANDLE
-    handle;
-
-  wchar_t
-    *path_wide;
-
-  status=(-1);
-  path_wide=create_wchar_path(path);
-  if (path_wide == (WCHAR *) NULL)
-    return(status);
-  handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
-    FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
-  if (handle != (HANDLE) NULL)
-    {
-      FILETIME
-        creation_time,
-        last_access_time,
-        last_write_time;
-
-      ULARGE_INTEGER
-        date_time;
-
-      date_time.QuadPart=(ULONGLONG) (attributes->st_ctime*10000000LL)+
-        116444736000000000LL;
-      creation_time.dwLowDateTime=date_time.LowPart;
-      creation_time.dwHighDateTime=date_time.HighPart;
-      date_time.QuadPart=(ULONGLONG) (attributes->st_atime*10000000LL)+
-        116444736000000000LL;
-      last_access_time.dwLowDateTime=date_time.LowPart;
-      last_access_time.dwHighDateTime=date_time.HighPart;
-      date_time.QuadPart=(ULONGLONG) (attributes->st_mtime*10000000LL)+
-        116444736000000000LL;
-      last_write_time.dwLowDateTime=date_time.LowPart;
-      last_write_time.dwHighDateTime=date_time.HighPart;
-      status=SetFileTime(handle,&creation_time,&last_access_time,&last_write_time);
-      CloseHandle(handle);
-      status=0;
-    }
-  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
+  status=NTSetFileTimestamp(path,attributes);
 #endif
   return(status);
 }
@@ -508,18 +171,7 @@ static inline int stat_utf8(const char *path,struct stat *attributes)
 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
   return(stat(path,attributes));
 #else
-  int
-    status;
-
-  wchar_t
-    *path_wide;
-
-  path_wide=create_wchar_path(path);
-  if (path_wide == (WCHAR *) NULL)
-    return(-1);
-  status=wstat(path_wide,attributes);
-  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
-  return(status);
+  return(NTStatWide(path,attributes));
 #endif
 }

diff --git a/MagickCore/utility.c b/MagickCore/utility.c
index 4e78d2891..acb344149 100644
--- a/MagickCore/utility.c
+++ b/MagickCore/utility.c
@@ -745,6 +745,23 @@ MagickPrivate void ExpandFilename(char *path)
 %      line arguments.
 %
 */
+static inline void getcwd_utf8(char *path,size_t extent)
+{
+#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
+  char
+    *directory;
+
+   directory=getcwd(path,extent);
+   (void) directory;
+#else
+  wchar_t
+    wide_path[MagickPathExtent];
+
+  (void) _wgetcwd(wide_path,MagickPathExtent-1);
+  (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
+#endif
+}
+
 MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
   char ***arguments)
 {
diff --git a/coders/dng.c b/coders/dng.c
index 8b619ea36..93af18fbd 100644
--- a/coders/dng.c
+++ b/coders/dng.c
@@ -493,7 +493,7 @@ static Image *ReadDNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
       wchar_t
         *path;

-      path=create_wchar_path(image->filename);
+      path=NTCreateWidePath(image->filename);
       if (path != (wchar_t *) NULL)
         {
           errcode=libraw_open_wfile(raw_info,path);
diff --git a/coders/emf.c b/coders/emf.c
index a9cb7017b..787b1f01c 100644
--- a/coders/emf.c
+++ b/coders/emf.c
@@ -714,7 +714,7 @@ static Image *ReadEMFImage(const ImageInfo *image_info,
     Gdiplus::Status::Ok)
     ThrowReaderException(CoderError, "GdiplusStartupFailed");
   source=(Gdiplus::Image *) NULL;
-  path=create_wchar_path(image->filename);
+  path=NTCreateWidePath(image->filename);
   if (path != (wchar_t *) NULL)
     {
       source=Gdiplus::Image::FromFile(path);