Commit ddb2e4200 for imagemagick.org
commit ddb2e4200f30d34c110dc05c9eab9d860d32122d
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Fri Apr 17 12:46:21 2026 +0200
Simplify windows (sym)link check and moved it to nt-base where the rest of the methods are.
diff --git a/MagickCore/nt-base-private.h b/MagickCore/nt-base-private.h
index e839f42d6..550c339f0 100644
--- a/MagickCore/nt-base-private.h
+++ b/MagickCore/nt-base-private.h
@@ -190,6 +190,7 @@ extern MagickPrivate MagickBooleanType
NTReportEvent(const char *,const MagickBooleanType);
extern MagickExport MagickBooleanType
+ NTIsLinkWide(const char *),
NTLongPathsEnabled(void);
extern MagickPrivate struct dirent
diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c
index 21d6a083d..d2966cf94 100644
--- a/MagickCore/nt-base.c
+++ b/MagickCore/nt-base.c
@@ -1617,6 +1617,45 @@ MagickPrivate void NTGhostscriptUnLoadDLL(void)
% %
% %
% %
+% N T I s L i n k W i d e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NTIsLinkWide() returns a boolean value indicating whether the specified path
+% is a a link.
+%
+% The format of the NTIsLinkWide method is:
+%
+% MagickBooleanType NTIsLinkWide(const char *path)
+%
+% A description of each parameter follows:
+%
+% o path: the file path.
+%
+*/
+MagickExport MagickBooleanType NTIsLinkWide(const char *path)
+{
+ DWORD
+ attributes;
+
+ wchar_t
+ *path_wide;
+
+ path_wide=NTCreateWidePath(path);
+ attributes=GetFileAttributesW(path_wide);
+ if (attributes == INVALID_FILE_ATTRIBUTES)
+ return(MagickFalse);
+ return(((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) ? MagickTrue :
+ MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% N T L o n g P a t h s E n a b l e d %
% %
% %
diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h
index a088cae59..ae2928dc5 100644
--- a/MagickCore/utility-private.h
+++ b/MagickCore/utility-private.h
@@ -82,76 +82,10 @@ static inline FILE *fopen_utf8(const char *path,const char *mode)
#endif
}
-#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(FSCTL_GET_REPARSE_POINT)
-#define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#endif
-
-#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(REPARSE_DATA_BUFFER)
-typedef struct _REPARSE_DATA_BUFFER {
- ULONG ReparseTag;
- USHORT ReparseDataLength;
- USHORT Reserved;
- union {
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- ULONG Flags;
- WCHAR PathBuffer[1];
- } SymbolicLinkReparseBuffer;
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- WCHAR PathBuffer[1];
- } MountPointReparseBuffer;
- struct {
- UCHAR DataBuffer[1];
- } GenericReparseBuffer;
- };
-} REPARSE_DATA_BUFFER;
-#endif
-
static inline MagickBooleanType is_link_utf8(const char *path)
{
-#if defined(MAGICKCORE_WINDOWS_SUPPORT)
- int count = MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0);
- if (count <= 0)
- return(MagickFalse);
- wchar_t *wide = (wchar_t *) malloc(count*sizeof(wchar_t));
- if (wide == NULL)
- return(MagickFalse);
- MultiByteToWideChar(CP_UTF8,0,path,-1,wide,count);
- DWORD attributes = GetFileAttributesW(wide);
- if (attributes == INVALID_FILE_ATTRIBUTES)
- {
- free(wide);
- return(MagickFalse);
- }
- if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
- {
- free(wide);
- return(MagickFalse);
- }
- HANDLE file_handle = CreateFileW(wide,0,FILE_SHARE_READ | FILE_SHARE_WRITE |
- FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT |
- FILE_FLAG_BACKUP_SEMANTICS,NULL);
- free(wide);
- if (file_handle == INVALID_HANDLE_VALUE)
- return(MagickFalse);
- BYTE buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- DWORD bytes;
- BOOL ok = DeviceIoControl(file_handle,FSCTL_GET_REPARSE_POINT,NULL,0,buffer,
- sizeof(buffer),&bytes,NULL);
- CloseHandle(file_handle);
- if (ok == 0)
- return(MagickFalse);
- REPARSE_DATA_BUFFER *reparse_buffer = (REPARSE_DATA_BUFFER *) buffer;
- return(reparse_buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK ? MagickTrue :
- MagickFalse);
-#elif defined(MAGICKCORE_POSIX_SUPPORT)
+#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
+#if defined(MAGICKCORE_POSIX_SUPPORT)
struct stat
status;
@@ -161,6 +95,9 @@ static inline MagickBooleanType is_link_utf8(const char *path)
#else
return(MagickFalse);
#endif
+#else
+ return(NTIsLinkWide(path));
+#endif
}
static inline int open_utf8(const char *path,int flags,mode_t mode)