diff --git a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-creating-reparse-points.patch b/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-creating-reparse-points.patch deleted file mode 100644 index ee903956..00000000 --- a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-creating-reparse-points.patch +++ /dev/null @@ -1,413 +0,0 @@ -From 5f3feef99f8c9740f04dbe0ee1b23ca27d60548e Mon Sep 17 00:00:00 2001 -From: "Erich E. Hoover" -Date: Thu, 16 Jan 2014 20:56:49 -0700 -Subject: [PATCH] ntdll: Add support for creating reparse points. - -Signed-off-by: Erich E. Hoover ---- - configure.ac | 2 + - dlls/ntdll/Makefile.in | 2 +- - dlls/ntdll/unix/file.c | 302 +++++++++++++++++++++++++++++++++++++++++ - include/ddk/ntifs.h | 5 + - 4 files changed, 310 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index b675da34d58..63e3bb5bdc7 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2137,6 +2137,8 @@ AC_CHECK_FUNCS(\ - process_vm_writev \ - sched_getcpu \ - sched_yield \ -+ renameat \ -+ renameat2 \ - setproctitle \ - setprogname \ - sigprocmask \ -diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in -index 3c0dfa7a895..b9a8bcba4cf 100644 ---- a/dlls/ntdll/Makefile.in -+++ b/dlls/ntdll/Makefile.in -@@ -5,7 +5,7 @@ IMPORTLIB = ntdll - IMPORTS = $(TOMCRYPT_PE_LIBS) $(MUSL_PE_LIBS) - EXTRAINCL = $(TOMCRYPT_PE_CFLAGS) - UNIX_CFLAGS = $(UNWIND_CFLAGS) $(HWLOC_CFLAGS) --UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS) $(HWLOC_LIBS) -+UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS) $(HWLOC_LIBS) -lm - - EXTRADLLFLAGS = -nodefaultlibs - i386_EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000 -diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index 7ab1dbb2b55..5b4fcb3711d 100644 ---- a/dlls/ntdll/unix/file.c -+++ b/dlls/ntdll/unix/file.c -@@ -36,6 +36,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #ifdef HAVE_MNTENT_H -@@ -121,6 +123,7 @@ - #include "wine/list.h" - #include "wine/debug.h" - #include "unix_private.h" -+#include "ddk/ntifs.h" - - WINE_DEFAULT_DEBUG_CHANNEL(file); - WINE_DECLARE_DEBUG_CHANNEL(winediag); -@@ -132,6 +135,12 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); - #undef EXT2_IOC_GETFLAGS - #undef EXT4_CASEFOLD_FL - -+#ifndef RENAME_EXCHANGE -+#define RENAME_EXCHANGE (1 << 1) -+#endif -+ -+#define SYM_MAX (PATH_MAX-1) /* PATH_MAX includes the NUL character */ -+ - #ifdef linux - - /* We want the real kernel dirent structure, not the libc one */ -@@ -249,6 +258,95 @@ static const BOOL is_case_sensitive = FALSE; - static pthread_mutex_t dir_mutex = PTHREAD_MUTEX_INITIALIZER; - static pthread_mutex_t mnt_mutex = PTHREAD_MUTEX_INITIALIZER; - -+#ifndef HAVE_RENAMEAT2 -+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath, -+ unsigned int flags ) -+{ -+ if (flags == 0) -+ return renameat( olddirfd, oldpath, newdirfd, newpath ); -+#if defined(__NR_renameat2) -+ return syscall( __NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags ); -+#elif defined(RENAME_SWAP) -+ return renameatx_np(olddirfd, oldpath, newdirfd, newpath, -+ (flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+#endif /* HAVE_RENAMEAT2 */ -+ -+static char *itoa( int i ) -+{ -+ static char buffer[11]; -+ -+ snprintf(buffer, sizeof(buffer), "%d", i); -+ return buffer; -+} -+ -+/* base64url (RFC 4648 §5) encode a binary string -+ * 1) start with base64 -+ * 2) replace '+' by '-' and replace '/' by '_' -+ * 3) do not add padding characters -+ * 4) do not add line separators -+ */ -+static UINT encode_base64url( const char *bin, unsigned int len, char *base64 ) -+{ -+ UINT n = 0, x; -+ static const char base64enc[] = -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; -+ -+ while (len > 0) -+ { -+ /* first 6 bits, all from bin[0] */ -+ base64[n++] = base64enc[(bin[0] & 0xfc) >> 2]; -+ x = (bin[0] & 3) << 4; -+ -+ /* next 6 bits, 2 from bin[0] and 4 from bin[1] */ -+ if (len == 1) -+ { -+ base64[n++] = base64enc[x]; -+ break; -+ } -+ base64[n++] = base64enc[x | ((bin[1] & 0xf0) >> 4)]; -+ x = (bin[1] & 0x0f) << 2; -+ -+ /* next 6 bits 4 from bin[1] and 2 from bin[2] */ -+ if (len == 2) -+ { -+ base64[n++] = base64enc[x]; -+ break; -+ } -+ base64[n++] = base64enc[x | ((bin[2] & 0xc0) >> 6)]; -+ -+ /* last 6 bits, all from bin [2] */ -+ base64[n++] = base64enc[bin[2] & 0x3f]; -+ bin += 3; -+ len -= 3; -+ } -+ base64[n] = 0; -+ return n; -+} -+ -+/* create a directory and all the needed parent directories */ -+static int mkdir_p( int dirfd, const char *path, mode_t mode ) -+{ -+ char path_tmp[PATH_MAX], *p; -+ -+ strcpy( path_tmp, path ); -+ for (p = path_tmp + 1; *p; p++) { -+ if (*p == '/') { -+ *p = '\0'; -+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST) -+ return -1; -+ *p = '/'; -+ } -+ } -+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST) -+ return -1; -+ return 0; -+} -+ - /* check if a given Unicode char is OK in a DOS short name */ - static inline BOOL is_invalid_dos_char( WCHAR ch ) - { -@@ -1653,6 +1751,28 @@ static int parse_samba_dos_attrib_data( char *data, int len ) - } - - -+/* determine whether a reparse point is meant to be a directory or a file */ -+static int is_reparse_dir( int fd, const char *path, BOOL *is_dir ) -+{ -+ char link_path[PATH_MAX], *p; -+ int ret; -+ -+ if ((ret = readlinkat( fd, path, link_path, sizeof(link_path) )) < 0) -+ return ret; -+ /* confirm that this file is a reparse point */ -+ if (strncmp( link_path, ".REPARSE_POINT/", 15) != 0) -+ return -1; -+ /* skip past the reparse point indicator and the filename */ -+ p = &link_path[15]; -+ if ((p = strchr( p, '/' )) == NULL) -+ return -1; -+ p++; -+ /* read the flag indicating whether this reparse point is a directory */ -+ if (is_dir) *is_dir = (*p == '.'); -+ return 0; -+} -+ -+ - static BOOL fd_is_mount_point( int fd, const struct stat *st ) - { - struct stat parent; -@@ -3455,6 +3575,181 @@ done: - } - - -+/* -+ * Retrieve the unix name corresponding to a file handle, remove that directory, and then symlink -+ * the requested directory to the location of the old directory. -+ */ -+NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer) -+{ -+ int buffer_len = buffer->ReparseDataLength+FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer); -+ char target_path[PATH_MAX], link_path[PATH_MAX], link_dir[PATH_MAX]; -+ int encoded_len = (int)ceil(buffer_len*4/3.0) + 1, chunk_len; -+ char tmpdir[PATH_MAX], tmplink[PATH_MAX], *d; -+ BOOL needs_close, tempdir_created = FALSE; -+ char filename_buf[PATH_MAX], *filename; -+ char *unix_src = NULL, *encoded = NULL; -+ int i = 0, j = 0, depth = 0, fd; -+ int link_dir_fd = -1; -+ NTSTATUS status; -+ struct stat st; -+ BOOL is_dir; -+ -+ if (buffer_len > 16*1024) -+ return STATUS_IO_REPARSE_DATA_INVALID; -+ -+ if ((status = server_get_unix_fd( handle, FILE_SPECIAL_ACCESS, &fd, &needs_close, NULL, NULL ))) -+ return status; -+ if (fstat( fd, &st ) == -1) -+ { -+ status = errno_to_status( errno ); -+ goto cleanup; -+ } -+ if ((status = server_get_unix_name( handle, &unix_src ))) -+ goto cleanup; -+ is_dir = S_ISDIR( st.st_mode ); -+ is_reparse_dir( AT_FDCWD, unix_src, &is_dir ); /* keep type (replace existing reparse point) */ -+ encoded = malloc( encoded_len ); -+ if (!encoded) -+ { -+ status = STATUS_NO_MEMORY; -+ goto cleanup; -+ } -+ encoded_len = encode_base64url( (const char *)buffer, buffer_len, encoded ); -+ -+ TRACE( "Linking %s to %s\n", debugstr_a(unix_src), encoded ); -+ strcpy( filename_buf, unix_src ); -+ filename = basename( filename_buf ); -+ -+ /* Create the symlink that represents the initial data in the reparse tag: -+ * *) Begin all reparse tags with the hidden folder .REPARSE_POINT. This serves two purposes: -+ * 1) it makes it easy to identify reparse points -+ * 2) if the reparse buffer exceeds what can be stored in a single symlink (4095+1 bytes) -+ * then we need to store additional data, so link to it and store it in a hidden folder -+ * *) Append the filename of the reparse point to the hidden folder, this ensures that if -+ * multiple reparse points contain the same data that there is no possibility of collision -+ * *) Append a special flag to indicate whether this is a directory (./) or file (/) -+ * *) Append the base64-url encoded reparse point buffer -+ * *) Append the filename of the first continuing symlink (0) in case we need it -+ */ -+ strcpy( target_path, ".REPARSE_POINT/" ); -+ strcat( target_path, filename ); -+ strcat( target_path, "/" ); -+ if (is_dir) -+ strcat( target_path, "." ); -+ strcat( target_path, "/" ); -+ i = 0; -+ for (depth=0; i