mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
ntdll-Junction_Points: Updates from Erich E. Hoover.
This commit is contained in:
parent
aabde22767
commit
769ddd9f00
@ -1,24 +1,24 @@
|
||||
From 9fb2b15dba901a3d43fad7e89bdf65fa42d8d3a3 Mon Sep 17 00:00:00 2001
|
||||
From 8919be537a3ada49b59f2686cc14dbfb81a37cb1 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 20:56:49 -0700
|
||||
Subject: [PATCH] ntdll: Add support for creating reparse points.
|
||||
Subject: ntdll: Add support for creating reparse points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
configure.ac | 2 +
|
||||
dlls/ntdll/Makefile.in | 2 +-
|
||||
dlls/ntdll/tests/file.c | 152 ++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 300 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 302 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/Makefile.in | 1 +
|
||||
include/ntifs.h | 42 ++++++
|
||||
6 files changed, 498 insertions(+), 1 deletion(-)
|
||||
6 files changed, 500 insertions(+), 1 deletion(-)
|
||||
create mode 100644 include/ntifs.h
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 41a29cee398..167839c5793 100644
|
||||
index e11f3cfdb63..113d126a002 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2025,6 +2025,8 @@ AC_CHECK_FUNCS(\
|
||||
@@ -2018,6 +2018,8 @@ AC_CHECK_FUNCS(\
|
||||
prctl \
|
||||
proc_pidinfo \
|
||||
sched_yield \
|
||||
@ -217,7 +217,7 @@ index c011733626f..93e50bd6952 100644
|
||||
test_mailslot_name();
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 604ca866890..58310fd8504 100644
|
||||
index 604ca866890..f3d831b0a33 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -36,6 +36,8 @@
|
||||
@ -325,7 +325,7 @@ index 604ca866890..58310fd8504 100644
|
||||
+}
|
||||
+
|
||||
+/* create a directory and all the needed parent directories */
|
||||
+static int mkdir_p(const char *path, mode_t mode)
|
||||
+static int mkdir_p( int dirfd, const char *path, mode_t mode )
|
||||
+{
|
||||
+ char path_tmp[PATH_MAX], *p;
|
||||
+
|
||||
@ -333,12 +333,12 @@ index 604ca866890..58310fd8504 100644
|
||||
+ for (p = path_tmp + 1; *p; p++) {
|
||||
+ if (*p == '/') {
|
||||
+ *p = '\0';
|
||||
+ if (mkdir(path_tmp, mode) != 0 && errno != EEXIST)
|
||||
+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST)
|
||||
+ return -1;
|
||||
+ *p = '/';
|
||||
+ }
|
||||
+ }
|
||||
+ if (mkdir(path_tmp, mode) != 0 && errno != EEXIST)
|
||||
+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
@ -375,7 +375,7 @@ index 604ca866890..58310fd8504 100644
|
||||
static BOOL fd_is_mount_point( int fd, const struct stat *st )
|
||||
{
|
||||
struct stat parent;
|
||||
@@ -3303,6 +3423,179 @@ done:
|
||||
@@ -3303,6 +3423,181 @@ done:
|
||||
}
|
||||
|
||||
|
||||
@ -386,13 +386,14 @@ index 604ca866890..58310fd8504 100644
|
||||
+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], original_dir[PATH_MAX];
|
||||
+ 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;
|
||||
@ -469,14 +470,15 @@ index 604ca866890..58310fd8504 100644
|
||||
+ }
|
||||
+
|
||||
+ /* change to the link folder so that we can build any necessary additional data */
|
||||
+ getcwd( original_dir, PATH_MAX );
|
||||
+ strcpy( link_dir, tmpdir );
|
||||
+ link_dir[strlen(link_dir)-16] = 0;
|
||||
+ chdir( link_dir );
|
||||
+ link_dir_fd = open( link_dir, O_RDONLY|O_DIRECTORY );
|
||||
+
|
||||
+ /* If there is any further information in the reparse tag then store it in the hidden folder */
|
||||
+ while(i < encoded_len)
|
||||
+ {
|
||||
+ int fd;
|
||||
+
|
||||
+ j++;
|
||||
+ strcpy( link_path, target_path );
|
||||
+
|
||||
@ -495,22 +497,21 @@ index 604ca866890..58310fd8504 100644
|
||||
+
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ if (mkdir_p( link_dir, 0777))
|
||||
+ if (mkdir_p( link_dir_fd, link_dir, 0777))
|
||||
+ {
|
||||
+ status = errno_to_status( errno );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (symlink( target_path, link_path ))
|
||||
+ if (symlinkat( target_path, link_dir_fd, link_path ))
|
||||
+ {
|
||||
+ status = errno_to_status( errno );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ chdir( link_dir );
|
||||
+ fd = openat( link_dir_fd, link_dir, O_RDONLY|O_DIRECTORY );
|
||||
+ close( link_dir_fd );
|
||||
+ link_dir_fd = fd;
|
||||
+ }
|
||||
+
|
||||
+ /* revert to the original directory */
|
||||
+ chdir( original_dir );
|
||||
+
|
||||
+ /* Atomically move the initial link into position */
|
||||
+ if (!renameat2( -1, tmplink, -1, unix_src, RENAME_EXCHANGE ))
|
||||
+ {
|
||||
@ -543,6 +544,7 @@ index 604ca866890..58310fd8504 100644
|
||||
+ status = STATUS_SUCCESS;
|
||||
+
|
||||
+cleanup:
|
||||
+ if (link_dir_fd != -1) close( link_dir_fd );
|
||||
+ if (tempdir_created) rmdir( tmpdir );
|
||||
+ if (needs_close) close( fd );
|
||||
+ free( unix_src );
|
||||
@ -555,7 +557,7 @@ index 604ca866890..58310fd8504 100644
|
||||
/******************************************************************************
|
||||
* lookup_unix_name
|
||||
*
|
||||
@@ -6052,6 +6345,13 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6052,6 +6347,13 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -630,5 +632,5 @@ index 00000000000..21d42e17325
|
||||
+
|
||||
+#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
From ded223a1f564442c26860d9e708b963710ecea21 Mon Sep 17 00:00:00 2001
|
||||
From 51f1d4cee59b11181bbf1432ef7c954020269cf3 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 20:57:57 -0700
|
||||
Subject: [PATCH] ntdll: Add support for reading reparse points.
|
||||
Subject: ntdll: Add support for reading reparse points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 21 +++-
|
||||
dlls/ntdll/unix/file.c | 209 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 228 insertions(+), 2 deletions(-)
|
||||
dlls/ntdll/unix/file.c | 212 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 231 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 5f6cb223951..33e49793319 100644
|
||||
index 93e50bd6952..805f5a6a940 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5359,14 +5359,14 @@ static void test_reparse_points(void)
|
||||
@ -55,10 +55,10 @@ index 5f6cb223951..33e49793319 100644
|
||||
|
||||
cleanup:
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 3fb4ded846c..3a1489c35d0 100644
|
||||
index f3d831b0a33..8fe543ded08 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -318,6 +318,84 @@ static UINT encode_base64url( const char *bin, unsigned int len, char *base64 )
|
||||
@@ -315,6 +315,84 @@ static UINT encode_base64url( const char *bin, unsigned int len, char *base64 )
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -141,9 +141,9 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+}
|
||||
+
|
||||
/* create a directory and all the needed parent directories */
|
||||
static int mkdir_p(const char *path, mode_t mode)
|
||||
static int mkdir_p( int dirfd, const char *path, mode_t mode )
|
||||
{
|
||||
@@ -3606,6 +3684,129 @@ cleanup:
|
||||
@@ -3598,6 +3676,132 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -153,21 +153,22 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ */
|
||||
+NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
+{
|
||||
+ char link_dir[PATH_MAX], original_dir[PATH_MAX], *d;
|
||||
+ char link_dir[PATH_MAX], link_path[PATH_MAX], *d;
|
||||
+ int link_path_len, buffer_len, encoded_len;
|
||||
+ char *unix_src, link_path[PATH_MAX];
|
||||
+ REPARSE_DATA_BUFFER header;
|
||||
+ ULONG out_size = *size;
|
||||
+ char *unix_name = NULL;
|
||||
+ char *encoded = NULL;
|
||||
+ int link_dir_fd = -1;
|
||||
+ NTSTATUS status;
|
||||
+ ssize_t ret;
|
||||
+ int depth;
|
||||
+ char *p;
|
||||
+
|
||||
+ if ((status = server_get_unix_name( handle, &unix_src )))
|
||||
+ if ((status = server_get_unix_name( handle, &unix_name )))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = readlink( unix_src, link_path, sizeof(link_path) );
|
||||
+ ret = readlink( unix_name, link_path, sizeof(link_path) );
|
||||
+ if (ret < 0)
|
||||
+ {
|
||||
+ status = errno_to_status( errno );
|
||||
@ -175,7 +176,7 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ }
|
||||
+ link_path_len = ret;
|
||||
+ link_path[link_path_len] = 0;
|
||||
+ if (strncmp( link_path, ".REPARSE_POINT/", 15) != 0)
|
||||
+ if (strncmp( link_path, ".REPARSE_POINT/", 15 ) != 0)
|
||||
+ {
|
||||
+ status = STATUS_NOT_IMPLEMENTED;
|
||||
+ goto cleanup;
|
||||
@ -214,8 +215,8 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ status = STATUS_BUFFER_TOO_SMALL;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ encoded_len = (int)ceil(buffer_len*4/3.0) + 1;
|
||||
+ encoded = realloc( encoded, encoded_len );
|
||||
+ encoded_len = (int)ceil(buffer_len*4/3.0);
|
||||
+ encoded = realloc( encoded, encoded_len + 3 ); /* 3 chars = slash, chunk ID, NUL character */
|
||||
+ if (!encoded)
|
||||
+ {
|
||||
+ status = STATUS_NO_MEMORY;
|
||||
@ -223,24 +224,25 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ }
|
||||
+
|
||||
+ /* change to the link folder so that we can build any necessary additional data */
|
||||
+ getcwd( original_dir, PATH_MAX );
|
||||
+ strcpy( link_dir, unix_src );
|
||||
+ strcpy( link_dir, unix_name );
|
||||
+ d = dirname( link_dir);
|
||||
+ if (d != link_dir) strcpy( link_dir, d );
|
||||
+ chdir( link_dir );
|
||||
+ link_dir_fd = open( link_dir, O_RDONLY|O_DIRECTORY );
|
||||
+
|
||||
+ /* Copy the encoded data from the follow on symlinks */
|
||||
+ while(strlen(encoded) < encoded_len-1)
|
||||
+ while(strlen(encoded) < encoded_len)
|
||||
+ {
|
||||
+ int fd;
|
||||
+
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ ret = readlink( link_dir, link_path, sizeof(link_path) );
|
||||
+ ret = readlinkat( link_dir_fd, link_dir, link_path, sizeof(link_path) );
|
||||
+ if (ret < 0)
|
||||
+ {
|
||||
+ status = errno_to_status( errno );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ link_path_len = ret;
|
||||
+ link_path[link_path_len] = 0;
|
||||
+ link_path[link_path_len] = 0; /* readlink does not NUL terminate */
|
||||
+
|
||||
+ p = &link_path[3*depth];
|
||||
+ for (depth=0; p < link_path + link_path_len; p += NAME_MAX+1, depth++)
|
||||
@ -249,12 +251,11 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ encoded[strlen(encoded)-1] = 0; /* final slash */
|
||||
+
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ chdir( link_dir );
|
||||
+ fd = openat( link_dir_fd, link_dir, O_RDONLY|O_DIRECTORY );
|
||||
+ close( link_dir_fd );
|
||||
+ link_dir_fd = fd;
|
||||
+ }
|
||||
+
|
||||
+ /* revert to the original directory */
|
||||
+ chdir( original_dir );
|
||||
+
|
||||
+ /* Decode the reparse buffer from the base64-encoded symlink data */
|
||||
+ *size = decode_base64url( encoded, strlen(encoded), (char*)buffer );
|
||||
+ status = STATUS_SUCCESS;
|
||||
@ -265,6 +266,8 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ if (link_dir_fd != -1) close( link_dir_fd );
|
||||
+ free( unix_name );
|
||||
+ free( encoded );
|
||||
+ return status;
|
||||
+}
|
||||
@ -273,7 +276,7 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
/******************************************************************************
|
||||
* lookup_unix_name
|
||||
*
|
||||
@@ -6353,6 +6554,14 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6347,6 +6551,14 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -289,5 +292,5 @@ index 3fb4ded846c..3a1489c35d0 100644
|
||||
{
|
||||
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)in_buffer;
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2a596f3d73eb9243960ed48c9b348c0e1461284e Mon Sep 17 00:00:00 2001
|
||||
From cef94f0a808ceccbb756a3fea6622927aff4e489 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 21:00:21 -0700
|
||||
Subject: [PATCH] ntdll: Add support for deleting reparse points.
|
||||
Subject: ntdll: Add support for deleting reparse points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -11,7 +11,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
3 files changed, 133 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 33e49793319..54f7c7fc860 100644
|
||||
index 805f5a6a940..a127a2f4f88 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5360,12 +5360,15 @@ static void test_reparse_points(void)
|
||||
@ -72,10 +72,10 @@ index 33e49793319..54f7c7fc860 100644
|
||||
ok(bret, "Failed to remove temporary target directory!\n");
|
||||
RemoveDirectoryW(path);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 3a1489c35d0..af390214624 100644
|
||||
index 8fe543ded08..4c221f53bfd 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3807,6 +3807,99 @@ cleanup:
|
||||
@@ -3802,6 +3802,99 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +175,7 @@ index 3a1489c35d0..af390214624 100644
|
||||
/******************************************************************************
|
||||
* lookup_unix_name
|
||||
*
|
||||
@@ -6554,6 +6647,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6551,6 +6644,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -210,5 +210,5 @@ index 21d42e17325..4539b89d583 100644
|
||||
+
|
||||
#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
From e64115c5421f37bbc426455d338d16ccb60ac9b2 Mon Sep 17 00:00:00 2001
|
||||
From a093cbbe7bd8ea6b1e5d48a552f2712dc2915f2c Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 21:01:25 -0700
|
||||
Subject: [PATCH] ntdll: Add support for testing for reparse points with
|
||||
Subject: ntdll: Add support for testing for reparse points with
|
||||
GetFileAttributes.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 5 +++++
|
||||
dlls/ntdll/unix/file.c | 26 +++++++++++++++++++++-----
|
||||
2 files changed, 26 insertions(+), 5 deletions(-)
|
||||
dlls/ntdll/unix/file.c | 23 +++++++++++++++++++----
|
||||
2 files changed, 24 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 2641197130b..4a18bd5c01a 100644
|
||||
index a127a2f4f88..ffc4ca44e32 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5469,6 +5469,11 @@ static void test_reparse_points(void)
|
||||
@ -27,18 +27,13 @@ index 2641197130b..4a18bd5c01a 100644
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
buffer_len = sizeof(*buffer) + 2*32767;
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 0b2987bf140..92dcd7775d6 100644
|
||||
index 4c221f53bfd..948074b35ec 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1755,11 +1755,22 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
@@ -1755,6 +1755,16 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
*attr = 0;
|
||||
ret = fstat( fd, st );
|
||||
if (ret == -1) return ret;
|
||||
- *attr |= get_file_attributes( st );
|
||||
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
|
||||
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
|
||||
+ if (S_ISLNK( st->st_mode ))
|
||||
+ {
|
||||
+ BOOL is_dir;
|
||||
@ -49,12 +44,10 @@ index 0b2987bf140..92dcd7775d6 100644
|
||||
+ if (is_reparse_dir( fd, "", &is_dir ) == 0)
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
+ }
|
||||
+ *attr |= get_file_attributes( st );
|
||||
+
|
||||
attr_len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 );
|
||||
if (attr_len != -1)
|
||||
*attr |= parse_samba_dos_attrib_data( attr_data, attr_len );
|
||||
@@ -1828,10 +1839,15 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
*attr |= get_file_attributes( st );
|
||||
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
|
||||
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
|
||||
@@ -1828,10 +1838,15 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
if (ret == -1) return ret;
|
||||
if (S_ISLNK( st->st_mode ))
|
||||
{
|
||||
@ -75,5 +68,5 @@ index 0b2987bf140..92dcd7775d6 100644
|
||||
else if (S_ISDIR( st->st_mode ) && (parent_path = malloc( strlen(path) + 4 )))
|
||||
{
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 4f3ab4bdb7daf7b38babb2ff4758c6633e703b7c Mon Sep 17 00:00:00 2001
|
||||
From da698613af1808ca0fe2599bc4b7898fad9dcf18 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 21:02:11 -0700
|
||||
Subject: [PATCH] server: Implement FILE_OPEN_REPARSE_POINT option.
|
||||
Subject: server: Implement FILE_OPEN_REPARSE_POINT option.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -10,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 137 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 8ae982294f6..2ab399ec8e2 100644
|
||||
index 5ba7e0be419..bfb291fa925 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -735,6 +735,8 @@ static UINT get_nt_file_options( DWORD attributes )
|
||||
@ -272,5 +272,5 @@ index eaebe044f37..1ed975673a6 100644
|
||||
if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
{
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e5d8dc8bdb7f22a5d1a91b8599ace874c5e2316f Mon Sep 17 00:00:00 2001
|
||||
From 0423cf43baf2938b4b1e7d705c20af11fb13f82c Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 12 Dec 2020 17:35:21 -0700
|
||||
Subject: [PATCH] kernelbase: Add support for deleting reparse points with
|
||||
Subject: kernelbase: Add support for deleting reparse points with
|
||||
RemoveDirectory.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
@ -11,7 +11,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 28 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 2ab399ec8e2..4f4040dd098 100644
|
||||
index bfb291fa925..6214f549406 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -3493,7 +3493,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryW( LPCWSTR path )
|
||||
@ -24,7 +24,7 @@ index 2ab399ec8e2..4f4040dd098 100644
|
||||
|
||||
if (!status)
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 7fa50ec59a6..fa8083b1c3b 100644
|
||||
index ffc4ca44e32..f3aad01ee93 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5363,11 +5363,11 @@ static void test_reparse_points(void)
|
||||
@ -81,5 +81,5 @@ index 7fa50ec59a6..fa8083b1c3b 100644
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
From 6ba3c723cbc8c5a2f3aea407ac62a005bab9b015 Mon Sep 17 00:00:00 2001
|
||||
From 03c96b5a2e215a7aa7d8c74ca3fbb5794fdcc95f Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 12:52:51 -0700
|
||||
Subject: [PATCH] kernelbase: Add support for deleting reparse points with
|
||||
DeleteFile.
|
||||
Subject: kernelbase: Add support for deleting reparse points with DeleteFile.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -11,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 4f4040dd098..5c9f0ebd485 100644
|
||||
index 6214f549406..17c25eb5858 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -993,7 +993,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW( LPCWSTR path )
|
||||
@ -25,7 +24,7 @@ index 4f4040dd098..5c9f0ebd485 100644
|
||||
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index fa8083b1c3b..4d4b861e9fb 100644
|
||||
index f3aad01ee93..4e3f0f04a3e 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5367,7 +5367,7 @@ static void test_reparse_points(void)
|
||||
@ -54,5 +53,5 @@ index fa8083b1c3b..4d4b861e9fb 100644
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
From c6e4a8f7377c21227044833bb6bf8a4fa4e8c8a5 Mon Sep 17 00:00:00 2001
|
||||
From d636805ef7d44cf78a08538f3c6c2e8f5a2f0d87 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 12:52:51 -0700
|
||||
Subject: [PATCH] ntdll: Add tests for NT symlink reparse points.
|
||||
Subject: ntdll: Add tests for NT symlink reparse points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 238 +++++++++++++++++++++++++++++++++++++---
|
||||
dlls/ntdll/tests/file.c | 239 +++++++++++++++++++++++++++++++++++++---
|
||||
include/ntifs.h | 12 ++
|
||||
2 files changed, 236 insertions(+), 14 deletions(-)
|
||||
2 files changed, 237 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 4d4b861e9fb..f9e179edc1d 100644
|
||||
index 4e3f0f04a3e..48abcd338bb 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5327,26 +5327,52 @@ static void test_mailslot_name(void)
|
||||
@ -75,7 +75,13 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
lstrcpyW(subst_dest, filename);
|
||||
lstrcpyW(print_dest, &filename[prefix_len]);
|
||||
*pbuffer = buffer;
|
||||
@@ -5368,9 +5394,12 @@ static void test_reparse_points(void)
|
||||
@@ -5363,14 +5389,18 @@ static void test_reparse_points(void)
|
||||
FILE_BASIC_INFORMATION old_attrib, new_attrib;
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
static WCHAR volW[] = {'c',':','\\',0};
|
||||
+ const WCHAR *rel_target = &targetW[1];
|
||||
WCHAR *dest, *long_path, *abs_target;
|
||||
REPARSE_GUID_DATA_BUFFER guid_buffer;
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
@ -89,7 +95,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
BOOL bret;
|
||||
|
||||
/* Create a temporary folder for the junction point tests */
|
||||
@@ -5435,7 +5464,7 @@ static void test_reparse_points(void)
|
||||
@@ -5435,7 +5465,7 @@ static void test_reparse_points(void)
|
||||
win_skip("Failed to open junction point directory handle (0x%lx).\n", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
@ -98,7 +104,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(!bret && GetLastError()==ERROR_INVALID_REPARSE_DATA, "Unexpected error (0x%lx)\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
@@ -5466,7 +5495,7 @@ static void test_reparse_points(void)
|
||||
@@ -5466,7 +5496,7 @@ static void test_reparse_points(void)
|
||||
}
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%lx).\n", dwret);
|
||||
@ -107,7 +113,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
|
||||
|
||||
@@ -5513,7 +5542,7 @@ static void test_reparse_points(void)
|
||||
@@ -5513,7 +5543,7 @@ static void test_reparse_points(void)
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
@ -116,7 +122,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5528,7 +5557,7 @@ static void test_reparse_points(void)
|
||||
@@ -5528,7 +5558,7 @@ static void test_reparse_points(void)
|
||||
ok(bret, "Failed to create junction point target directory.\n");
|
||||
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
@ -125,7 +131,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5541,6 +5570,187 @@ static void test_reparse_points(void)
|
||||
@@ -5541,6 +5571,187 @@ static void test_reparse_points(void)
|
||||
ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%lx)!\n", dwret);
|
||||
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: 0x%lx)\n", dwret);
|
||||
|
||||
@ -303,11 +309,11 @@ index 4d4b861e9fb..f9e179edc1d 100644
|
||||
+ bret = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer, buffer_len, &dwret, 0);
|
||||
+ ok(bret, "Failed to read relative symlink!\n");
|
||||
+ string_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
+ ok(string_len != lstrlenW(&targetW[1]), "Symlink destination length does not match ('%d' != '%d')!\n",
|
||||
+ string_len, lstrlenW(&targetW[1]));
|
||||
+ ok(string_len != lstrlenW(rel_target), "Symlink destination length does not match ('%d' != '%d')!\n",
|
||||
+ string_len, lstrlenW(rel_target));
|
||||
+ dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
+ ok((memcmp(dest, &targetW[1], string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
+ wine_dbgstr_w(dest), wine_dbgstr_w(&targetW[1]));
|
||||
+ ok((memcmp(dest, rel_target, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
+ wine_dbgstr_w(dest), wine_dbgstr_w(rel_target));
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
cleanup:
|
||||
@ -354,5 +360,5 @@ index 4539b89d583..0d02225bc4f 100644
|
||||
+
|
||||
#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
From edaf25f8037c96fe83885ab47a1195c7f28e2fd6 Mon Sep 17 00:00:00 2001
|
||||
From 70b8fd99f84708447779b45735e0553755f1b8bb Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 12:46:30 -0700
|
||||
Subject: [PATCH] kernelbase: Add support for moving reparse points with
|
||||
MoveFile*.
|
||||
Subject: kernelbase: Add support for moving reparse points with MoveFile*.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/kernelbase/file.c | 2 +-
|
||||
dlls/ntdll/tests/file.c | 13 ++++++++++++-
|
||||
dlls/ntdll/tests/file.c | 12 +++++++++++-
|
||||
dlls/ntdll/unix/file.c | 20 ++++++++++++++++++++
|
||||
server/fd.c | 6 ++++--
|
||||
4 files changed, 37 insertions(+), 4 deletions(-)
|
||||
4 files changed, 36 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 5c9f0ebd485..2cbe8f4ac03 100644
|
||||
index 17c25eb5858..53b9651a8fa 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -2471,7 +2471,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH MoveFileWithProgressW( const WCHAR *source, const
|
||||
@ -26,7 +25,7 @@ index 5c9f0ebd485..2cbe8f4ac03 100644
|
||||
if (!set_ntstatus( status )) goto error;
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index f9e179edc1d..6ccdb3c02dc 100644
|
||||
index 48abcd338bb..808d863ea55 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5381,7 +5381,8 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, ULONG flags,
|
||||
@ -39,16 +38,8 @@ index f9e179edc1d..6ccdb3c02dc 100644
|
||||
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
|
||||
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
|
||||
static const WCHAR parentW[] = {'\\','.','.','\\',0};
|
||||
@@ -5389,6 +5390,7 @@ static void test_reparse_points(void)
|
||||
FILE_BASIC_INFORMATION old_attrib, new_attrib;
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
static WCHAR volW[] = {'c',':','\\',0};
|
||||
+ const WCHAR *rel_target = &targetW[1];
|
||||
WCHAR *dest, *long_path, *abs_target;
|
||||
REPARSE_GUID_DATA_BUFFER guid_buffer;
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
@@ -5751,6 +5753,15 @@ static void test_reparse_points(void)
|
||||
wine_dbgstr_w(dest), wine_dbgstr_w(&targetW[1]));
|
||||
@@ -5752,6 +5753,15 @@ static void test_reparse_points(void)
|
||||
wine_dbgstr_w(dest), wine_dbgstr_w(rel_target));
|
||||
CloseHandle(handle);
|
||||
|
||||
+ /* Check moving a reparse point to another location */
|
||||
@ -64,10 +55,10 @@ index f9e179edc1d..6ccdb3c02dc 100644
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 201eeab7013..907d51f1fc3 100644
|
||||
index 948074b35ec..9ae5e194c6d 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5336,8 +5336,10 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -5328,8 +5328,10 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
if (len >= sizeof(FILE_RENAME_INFORMATION))
|
||||
{
|
||||
FILE_RENAME_INFORMATION *info = ptr;
|
||||
@ -78,7 +69,7 @@ index 201eeab7013..907d51f1fc3 100644
|
||||
char *unix_name;
|
||||
|
||||
name_str.Buffer = info->FileName;
|
||||
@@ -5346,6 +5348,19 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -5338,6 +5340,19 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
InitializeObjectAttributes( &attr, &name_str, OBJ_CASE_INSENSITIVE, info->RootDirectory, NULL );
|
||||
get_redirect( &attr, &redir );
|
||||
|
||||
@ -98,7 +89,7 @@ index 201eeab7013..907d51f1fc3 100644
|
||||
status = nt_to_unix_file_name( &attr, &unix_name, FILE_OPEN_IF );
|
||||
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
@@ -5362,9 +5377,14 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -5354,9 +5369,14 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
@ -145,5 +136,5 @@ index 1ed975673a6..60ba552f769 100644
|
||||
if (!fd->unix_name)
|
||||
set_error( STATUS_NO_MEMORY );
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 1af9d5003cb6d65be02fb68779e208488c242b82 Mon Sep 17 00:00:00 2001
|
||||
From 2cf08dad55bea4bbf5ca37ff0bf4a0553d1f6be3 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 3 Sep 2022 08:57:05 -0600
|
||||
Subject: [PATCH] kernelbase: Add test for reparse point copy behavior.
|
||||
Subject: kernelbase: Add test for reparse point copy behavior.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 6ccdb3c02dc..b1290f9ef7b 100644
|
||||
index 808d863ea55..390768f557d 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5762,6 +5762,12 @@ static void test_reparse_points(void)
|
||||
@ -26,5 +26,5 @@ index 6ccdb3c02dc..b1290f9ef7b 100644
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
From ff29165847ca6ea105053843f46cac727c7083c8 Mon Sep 17 00:00:00 2001
|
||||
From a3eedb8eb82f841ae48633d1e3c0416a362ccd34 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 3 Sep 2022 11:23:31 -0600
|
||||
Subject: [PATCH] ntdll: Follow reparse points during path resolution.
|
||||
Subject: ntdll: Follow reparse points during path resolution.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 11 +++-
|
||||
dlls/ntdll/unix/file.c | 122 +++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 124 insertions(+), 9 deletions(-)
|
||||
dlls/ntdll/tests/file.c | 11 ++-
|
||||
dlls/ntdll/unix/file.c | 189 +++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 177 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index b1290f9ef7b..799a8cebe50 100644
|
||||
index 390768f557d..a0b84849490 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5381,7 +5381,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, ULONG flags,
|
||||
@ -44,10 +44,46 @@ index b1290f9ef7b..799a8cebe50 100644
|
||||
ok(bret, "Failed to remove temporary reparse point directory!\n");
|
||||
bret = RemoveDirectoryW(target_path);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 907d51f1fc3..d520a73b253 100644
|
||||
index 9ae5e194c6d..ba844e90272 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3700,14 +3700,13 @@ cleanup:
|
||||
@@ -3516,6 +3516,35 @@ done:
|
||||
}
|
||||
|
||||
|
||||
+static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFFER *buffer,
|
||||
+ int *is_relative )
|
||||
+{
|
||||
+ int target_len, offset;
|
||||
+ WCHAR *target;
|
||||
+
|
||||
+ switch( buffer->ReparseTag )
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ offset = buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
+ *is_relative = FALSE;
|
||||
+ break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
+ *is_relative = (buffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) == SYMLINK_FLAG_RELATIVE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return STATUS_IO_REPARSE_TAG_NOT_HANDLED;
|
||||
+ }
|
||||
+ nt_target->Buffer = target;
|
||||
+ nt_target->Length = target_len;
|
||||
+ return STATUS_REPARSE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* 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.
|
||||
@@ -3692,16 +3721,14 @@ cleanup:
|
||||
|
||||
|
||||
/*
|
||||
@ -56,26 +92,33 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
+ * Obtain the reparse point buffer from the unix filename for the reparse point.
|
||||
*/
|
||||
-NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
+NTSTATUS get_reparse_point_unix(const char *unix_src, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
+NTSTATUS get_reparse_point_unix(const char *unix_name, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
{
|
||||
char link_dir[PATH_MAX], original_dir[PATH_MAX], *d;
|
||||
char link_dir[PATH_MAX], link_path[PATH_MAX], *d;
|
||||
int link_path_len, buffer_len, encoded_len;
|
||||
- char *unix_src, link_path[PATH_MAX];
|
||||
+ char link_path[PATH_MAX];
|
||||
REPARSE_DATA_BUFFER header;
|
||||
ULONG out_size = *size;
|
||||
- char *unix_name = NULL;
|
||||
char *encoded = NULL;
|
||||
@@ -3716,9 +3715,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
|
||||
int link_dir_fd = -1;
|
||||
NTSTATUS status;
|
||||
@@ -3709,9 +3736,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
|
||||
int depth;
|
||||
char *p;
|
||||
|
||||
- if ((status = server_get_unix_name( handle, &unix_src )))
|
||||
- if ((status = server_get_unix_name( handle, &unix_name )))
|
||||
- goto cleanup;
|
||||
-
|
||||
ret = readlink( unix_src, link_path, sizeof(link_path) );
|
||||
ret = readlink( unix_name, link_path, sizeof(link_path) );
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -3822,6 +3818,75 @@ cleanup:
|
||||
@@ -3811,12 +3835,76 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
|
||||
|
||||
cleanup:
|
||||
if (link_dir_fd != -1) close( link_dir_fd );
|
||||
- free( unix_name );
|
||||
free( encoded );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -97,13 +140,14 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
+
|
||||
+
|
||||
+/* find the NT target of a reparse point */
|
||||
+static NTSTATUS find_reparse_target( const char *unix_name, WCHAR **new_name, int *new_name_len)
|
||||
+static NTSTATUS find_reparse_target( const char *unix_name, const WCHAR *parent, int parent_len,
|
||||
+ WCHAR **new_name, int *new_name_len)
|
||||
+{
|
||||
+ REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
+ int offset, target_len;
|
||||
+ UNICODE_STRING nt_target;
|
||||
+ ULONG buffer_len = 0;
|
||||
+ int is_relative;
|
||||
+ NTSTATUS status;
|
||||
+ WCHAR *target;
|
||||
+
|
||||
+ status = get_reparse_point_unix( unix_name, NULL, &buffer_len );
|
||||
+ if (status != STATUS_BUFFER_TOO_SMALL)
|
||||
@ -117,32 +161,27 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
+ free( buffer );
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ switch( buffer->ReparseTag )
|
||||
+ if ((status = get_reparse_target( &nt_target, buffer, &is_relative )) == STATUS_REPARSE)
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ offset = buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
+ break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN( "Reparse point with unsupported tag: 0x%08x\n", buffer->ReparseTag );
|
||||
+ status = STATUS_NOT_IMPLEMENTED;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (status == STATUS_SUCCESS)
|
||||
+ {
|
||||
+ *new_name_len = target_len/sizeof(WCHAR);
|
||||
+ *new_name = malloc( target_len );
|
||||
+ if (*new_name) memcpy( *new_name, target, target_len );
|
||||
+ WCHAR *p;
|
||||
+
|
||||
+ p = *new_name = malloc( nt_target.Length + parent_len*sizeof(WCHAR) );
|
||||
+ if (!p)
|
||||
+ {
|
||||
+ status = STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (is_relative)
|
||||
+ {
|
||||
+ memcpy( p, parent, parent_len*sizeof(WCHAR) );
|
||||
+ p += parent_len;
|
||||
+ }
|
||||
+ memcpy( p, nt_target.Buffer, nt_target.Length );
|
||||
+ p += nt_target.Length/sizeof(WCHAR);
|
||||
+ *new_name_len = p - *new_name;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ free( buffer );
|
||||
+ return status;
|
||||
+}
|
||||
@ -151,26 +190,35 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
/*
|
||||
* Retrieve the unix name corresponding to a file handle, remove that symlink, and then recreate
|
||||
* a directory at the location of the old filename.
|
||||
@@ -3924,11 +3989,13 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
UINT disposition, BOOL is_unix )
|
||||
@@ -3910,15 +3998,25 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
+static NTSTATUS IoReplaceFileObjectName( FILE_OBJECT *fileobj, PWSTR name, USHORT name_len )
|
||||
+{
|
||||
+ fileobj->FileName.Buffer = name;
|
||||
+ fileobj->FileName.Length = name_len;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/******************************************************************************
|
||||
* lookup_unix_name
|
||||
*
|
||||
* Helper for nt_to_unix_file_name
|
||||
*/
|
||||
-static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer, int unix_len, int pos,
|
||||
- UINT disposition, BOOL is_unix )
|
||||
+static NTSTATUS lookup_unix_name( FILE_OBJECT *fileobj, const WCHAR *name, int name_len,
|
||||
+ char **buffer, int unix_len, int pos, UINT disposition,
|
||||
+ BOOL is_unix )
|
||||
{
|
||||
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, '/', 0 };
|
||||
+ WCHAR *name_buf = NULL;
|
||||
+ const WCHAR *fullname = fileobj->FileName.Buffer;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
struct stat st;
|
||||
char *unix_name = *buffer;
|
||||
const WCHAR *ptr, *end;
|
||||
+ int old_cwd;
|
||||
|
||||
/* check syntax of individual components */
|
||||
|
||||
@@ -3977,9 +4044,13 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
|
||||
/* now do it component by component */
|
||||
|
||||
+ old_cwd = open( ".", O_RDONLY );
|
||||
+
|
||||
@@ -3975,6 +4073,8 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
while (name_len)
|
||||
{
|
||||
const WCHAR *end, *next;
|
||||
@ -179,40 +227,32 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
|
||||
end = name;
|
||||
while (end < name + name_len && *end != '\\') end++;
|
||||
@@ -3999,8 +4070,39 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
@@ -3994,8 +4094,31 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
|
||||
status = find_file_in_dir( unix_name, pos, name, end - name, is_unix );
|
||||
|
||||
+ /* follow reparse point and restart from there (if applicable) */
|
||||
+ if (find_reparse_target( unix_name, &target, &target_len ) == STATUS_SUCCESS)
|
||||
+ if (name_len && find_reparse_target( unix_name, fullname, name - fullname, &target, &target_len ) == STATUS_REPARSE)
|
||||
+ {
|
||||
+ int new_name_len = target_len + name_len + 1;
|
||||
+ WCHAR *new_name, *p;
|
||||
+ WCHAR *p, *new_name;
|
||||
+
|
||||
+ if (!(p = new_name = malloc( new_name_len*sizeof(WCHAR) )))
|
||||
+ {
|
||||
+ free( target );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ status = STATUS_NO_MEMORY;
|
||||
+ break;
|
||||
+ }
|
||||
+ memcpy( p, target, target_len*sizeof(WCHAR) );
|
||||
+ p += target_len;
|
||||
+ (p++)[0] = '\\';
|
||||
+ memcpy( p, next, name_len*sizeof(WCHAR) );
|
||||
+ if (target[0] == '\\')
|
||||
+ {
|
||||
+ strcpy( unix_name, "/" );
|
||||
+ pos = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ unix_name = dirname( unix_name );
|
||||
+ TRACE( "Follow reparse point %s => %s, %s\n", debugstr_wn(name, end-name), unix_name,
|
||||
+ debugstr_wn(new_name, new_name_len) );
|
||||
+ next = new_name;
|
||||
+ name_len = new_name_len;
|
||||
+ TRACE( "Follow reparse point %s => %s\n", debugstr_wn(fullname, end-fullname),
|
||||
+ debugstr_wn(new_name, new_name_len) );
|
||||
+ free( target );
|
||||
+ free( name_buf );
|
||||
+ name_buf = new_name;
|
||||
+ status = STATUS_SUCCESS;
|
||||
+ if (IoReplaceFileObjectName( fileobj, new_name, new_name_len*sizeof(WCHAR) ))
|
||||
+ free( new_name );
|
||||
+ return STATUS_REPARSE;
|
||||
+ }
|
||||
/* if this is the last element, not finding it is not necessarily fatal */
|
||||
- if (!name_len)
|
||||
@ -220,21 +260,118 @@ index 907d51f1fc3..d520a73b253 100644
|
||||
{
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
@@ -4028,10 +4130,14 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
@@ -4034,12 +4157,12 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
/******************************************************************************
|
||||
* nt_to_unix_file_name_no_root
|
||||
*/
|
||||
-static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char **unix_name_ret,
|
||||
+static NTSTATUS nt_to_unix_file_name_no_root( FILE_OBJECT *fileobj, char **unix_name_ret,
|
||||
UINT disposition )
|
||||
{
|
||||
static const WCHAR unixW[] = {'u','n','i','x'};
|
||||
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
|
||||
-
|
||||
+ const UNICODE_STRING *nameW = &fileobj->FileName;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
const WCHAR *name;
|
||||
struct stat st;
|
||||
@@ -4129,7 +4252,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
|
||||
name += prefix_len;
|
||||
name_len -= prefix_len;
|
||||
|
||||
if (status != STATUS_SUCCESS) break;
|
||||
|
||||
+ chdir( unix_name );
|
||||
pos += strlen( unix_name + pos );
|
||||
name = next;
|
||||
- status = lookup_unix_name( name, name_len, &unix_name, unix_len, pos, disposition, is_unix );
|
||||
+ status = lookup_unix_name( fileobj, name, name_len, &unix_name, unix_len, pos, disposition, is_unix );
|
||||
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
TRACE( "%s -> %s\n", debugstr_us(nameW), debugstr_a(unix_name) );
|
||||
@@ -4137,7 +4260,8 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
|
||||
}
|
||||
else
|
||||
{
|
||||
- TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
|
||||
+ if (status != STATUS_REPARSE)
|
||||
+ TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
|
||||
free( unix_name );
|
||||
}
|
||||
return status;
|
||||
@@ -4155,18 +4279,30 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
|
||||
*/
|
||||
NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, UINT disposition )
|
||||
{
|
||||
+ HANDLE rootdir = attr->RootDirectory;
|
||||
enum server_fd_type type;
|
||||
int old_cwd, root_fd, needs_close;
|
||||
+ int reparse_count = 0;
|
||||
+ FILE_OBJECT fileobj;
|
||||
const WCHAR *name;
|
||||
char *unix_name;
|
||||
int name_len, unix_len;
|
||||
NTSTATUS status;
|
||||
|
||||
+ fchdir( old_cwd );
|
||||
+ free( name_buf );
|
||||
- if (!attr->RootDirectory) /* without root dir fall back to normal lookup */
|
||||
- return nt_to_unix_file_name_no_root( attr->ObjectName, name_ret, disposition );
|
||||
+ fileobj.FileName = *attr->ObjectName;
|
||||
+reparse:
|
||||
+ if (reparse_count++ == 31)
|
||||
+ return STATUS_REPARSE_POINT_NOT_RESOLVED;
|
||||
+ if (!rootdir) /* without root dir fall back to normal lookup */
|
||||
+ {
|
||||
+ status = nt_to_unix_file_name_no_root( &fileobj, name_ret, disposition );
|
||||
+ if (status == STATUS_REPARSE) goto reparse;
|
||||
+ if (fileobj.FileName.Buffer != attr->ObjectName->Buffer) free( fileobj.FileName.Buffer);
|
||||
+ return status;
|
||||
+ }
|
||||
|
||||
- name = attr->ObjectName->Buffer;
|
||||
- name_len = attr->ObjectName->Length / sizeof(WCHAR);
|
||||
+ name = fileobj.FileName.Buffer;
|
||||
+ name_len = fileobj.FileName.Length / sizeof(WCHAR);
|
||||
|
||||
if (name_len && name[0] == '\\') return STATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -4174,7 +4310,7 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
|
||||
if (!(unix_name = malloc( unix_len ))) return STATUS_NO_MEMORY;
|
||||
unix_name[0] = '.';
|
||||
|
||||
- if (!(status = server_get_unix_fd( attr->RootDirectory, 0, &root_fd, &needs_close, &type, NULL )))
|
||||
+ if (!(status = server_get_unix_fd( rootdir, 0, &root_fd, &needs_close, &type, NULL )))
|
||||
{
|
||||
if (type != FD_TYPE_DIR)
|
||||
{
|
||||
@@ -4186,7 +4322,8 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
|
||||
mutex_lock( &dir_mutex );
|
||||
if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1)
|
||||
{
|
||||
- status = lookup_unix_name( name, name_len, &unix_name, unix_len, 1, disposition, FALSE );
|
||||
+ status = lookup_unix_name( &fileobj, name, name_len, &unix_name, unix_len, 1,
|
||||
+ disposition, FALSE );
|
||||
if (fchdir( old_cwd ) == -1) chdir( "/" );
|
||||
}
|
||||
else status = errno_to_status( errno );
|
||||
@@ -4199,14 +4336,22 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
|
||||
|
||||
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
- TRACE( "%s -> %s\n", debugstr_us(attr->ObjectName), debugstr_a(unix_name) );
|
||||
+ TRACE( "%s -> %s\n", debugstr_us(&fileobj.FileName), debugstr_a(unix_name) );
|
||||
*name_ret = unix_name;
|
||||
}
|
||||
+ else if (status == STATUS_REPARSE)
|
||||
+ {
|
||||
+ if (fileobj.FileName.Buffer[0] == '\\') rootdir = 0;
|
||||
+ free( unix_name );
|
||||
+ goto reparse;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
|
||||
free( unix_name );
|
||||
}
|
||||
+
|
||||
+ if (fileobj.FileName.Buffer != attr->ObjectName->Buffer) free( fileobj.FileName.Buffer);
|
||||
return status;
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2863150ec05b9abf82d0c72bc33b4c64092dc4ee Mon Sep 17 00:00:00 2001
|
||||
From c232ecbb9cda964d9e279f16127b1e112f62ce55 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 12 Dec 2020 17:28:31 -0700
|
||||
Subject: [PATCH] kernel32: Advertise reparse point support.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 47d17451b657c657e63625b808ce6461169cd331 Mon Sep 17 00:00:00 2001
|
||||
From 7413100037edc5d6a0dbd5107cbe083b11a7ca55 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sun, 4 Sep 2022 13:19:16 -0600
|
||||
Subject: [PATCH] ntdll: Allow reparse points to target the applicable Unix
|
||||
Subject: ntdll: Allow reparse points to target the applicable Unix
|
||||
file/directory.
|
||||
|
||||
Allows lookup_unix_name 'shortcut' to succeed, as well as allowing
|
||||
@ -9,45 +9,20 @@ the user to follow the symlink outside of Wine.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 151 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 151 insertions(+)
|
||||
dlls/ntdll/unix/file.c | 129 +++++++++++++++++++++++++++++++++++++++++
|
||||
include/winnt.h | 2 +
|
||||
2 files changed, 131 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index d520a73b253..2a98d6baa28 100644
|
||||
index ba844e90272..980251b8bbf 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3526,6 +3526,150 @@ done:
|
||||
@@ -3545,6 +3545,125 @@ static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFF
|
||||
}
|
||||
|
||||
|
||||
+static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFFER *buffer )
|
||||
+{
|
||||
+ int target_len, offset;
|
||||
+ WCHAR *target;
|
||||
+
|
||||
+ switch( buffer->ReparseTag )
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ offset = buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
+ break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ target_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+ nt_target->Buffer = target;
|
||||
+ nt_target->Length = target_len;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* add a symlink to the unix target at the last point of the reparse point metadata */
|
||||
+NTSTATUS create_reparse_target( const char *unix_src, int depth, const char *link_path,
|
||||
+NTSTATUS create_reparse_target( int dirfd, const char *unix_src, int depth, const char *link_path,
|
||||
+ REPARSE_DATA_BUFFER *buffer )
|
||||
+{
|
||||
+ ULONG nt_path_len = PATH_MAX, unix_path_len = PATH_MAX;
|
||||
@ -56,16 +31,15 @@ index d520a73b253..2a98d6baa28 100644
|
||||
+ char *unix_path = NULL, *d;
|
||||
+ char target_path[PATH_MAX];
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ int nt_target_len;
|
||||
+ char *unix_target;
|
||||
+ int is_relative;
|
||||
+ NTSTATUS status;
|
||||
+ WCHAR *nt_path;
|
||||
+
|
||||
+ status = get_reparse_target( &nt_target, buffer );
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ if ((status = get_reparse_target( &nt_target, buffer, &is_relative )) != STATUS_REPARSE)
|
||||
+ return status;
|
||||
+ /* if the target path is relative then turn the source path into an NT path */
|
||||
+ is_relative = (nt_target.Buffer[0] != '\\');
|
||||
+ if (is_relative)
|
||||
+ {
|
||||
+ UNICODE_STRING nt_path_tmp;
|
||||
@ -112,8 +86,9 @@ index d520a73b253..2a98d6baa28 100644
|
||||
+ nt_path[0] = 0;
|
||||
+ }
|
||||
+ /* append the target path (if absolute, appends to empty string) */
|
||||
+ nt_full_target.MaximumLength = nt_target.Length + wcslen(nt_path) * sizeof(WCHAR);
|
||||
+ nt_full_target.Buffer = malloc( nt_full_target.MaximumLength );
|
||||
+ nt_target_len = nt_target.Length + sizeof(WCHAR);
|
||||
+ nt_full_target.MaximumLength = nt_target_len + wcslen(nt_path) * sizeof(WCHAR);
|
||||
+ nt_full_target.Buffer = malloc( nt_full_target.MaximumLength + 2 );
|
||||
+ if (!nt_full_target.Buffer)
|
||||
+ {
|
||||
+ status = STATUS_NO_MEMORY;
|
||||
@ -121,7 +96,7 @@ index d520a73b253..2a98d6baa28 100644
|
||||
+ }
|
||||
+ wcscpy( nt_full_target.Buffer, nt_path );
|
||||
+ free( nt_path );
|
||||
+ memcpy( &nt_full_target.Buffer[wcslen(nt_full_target.Buffer)], nt_target.Buffer, nt_target.Length + sizeof(WCHAR));
|
||||
+ memcpy( &nt_full_target.Buffer[wcslen(nt_full_target.Buffer)], nt_target.Buffer, nt_target_len );
|
||||
+ nt_full_target.Length = wcslen( nt_full_target.Buffer ) * sizeof(WCHAR);
|
||||
+ /* find the unix path for the target */
|
||||
+ InitializeObjectAttributes( &attr, &nt_full_target, 0, 0, NULL );
|
||||
@ -153,7 +128,7 @@ index d520a73b253..2a98d6baa28 100644
|
||||
+ strcat( target_path, "../" );
|
||||
+ strcat( target_path, &unix_target[relative_offset] );
|
||||
+ TRACE( "adding reparse point target: %s\n", target_path );
|
||||
+ symlink( target_path, link_path );
|
||||
+ symlinkat( target_path, dirfd, link_path );
|
||||
+ }
|
||||
+ free( unix_target );
|
||||
+ status = STATUS_SUCCESS;
|
||||
@ -163,24 +138,41 @@ index d520a73b253..2a98d6baa28 100644
|
||||
+ free( nt_full_target.Buffer );
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* 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.
|
||||
@@ -3655,6 +3799,13 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
chdir( link_dir );
|
||||
@@ -3678,6 +3797,16 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
link_dir_fd = fd;
|
||||
}
|
||||
|
||||
+ /* create the very last link directory */
|
||||
+ strcpy( link_path, target_path );
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ if (mkdir_p( link_dir, 0777) == 0)
|
||||
+ create_reparse_target( unix_src, depth + 2, link_path, buffer );
|
||||
+ if (IsReparseTagNameSurrogate( buffer->ReparseTag ))
|
||||
+ {
|
||||
+ strcpy( link_path, target_path );
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ if (mkdir_p( link_dir_fd, link_dir, 0777 ) == 0)
|
||||
+ create_reparse_target( link_dir_fd, unix_src, depth + 2, link_path, buffer );
|
||||
+ }
|
||||
+
|
||||
/* revert to the original directory */
|
||||
chdir( original_dir );
|
||||
/* Atomically move the initial link into position */
|
||||
if (!renameat2( -1, tmplink, -1, unix_src, RENAME_EXCHANGE ))
|
||||
{
|
||||
diff --git a/include/winnt.h b/include/winnt.h
|
||||
index 836bd7123e5..19bb5be83c4 100644
|
||||
--- a/include/winnt.h
|
||||
+++ b/include/winnt.h
|
||||
@@ -2330,6 +2330,8 @@ extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#define IO_REPARSE_TAG_ONEDRIVE __MSABI_LONG(0x80000021)
|
||||
#define IO_REPARSE_TAG_GVFS_TOMBSTONE __MSABI_LONG(0xA0000022)
|
||||
|
||||
+#define IsReparseTagNameSurrogate(x) (((x) & (1<<29)) == (1<<29))
|
||||
+
|
||||
/*
|
||||
* File formats definitions
|
||||
*/
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
From e21b5f472423dd2cd6d43421d8f3c94d30e8ff3f Mon Sep 17 00:00:00 2001
|
||||
From f3234130493d1d99545a46e262646c1486e9de86 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 16:16:17 -0700
|
||||
Subject: [PATCH] ntdll: Add an intermediary symlink in reparse point metadata
|
||||
pointing to prefix.
|
||||
Subject: ntdll: Add an intermediary prefix symlink in reparse point metadata.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
dlls/ntdll/unix/file.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 6310c4b414b..12df28a516e 100644
|
||||
index 980251b8bbf..f298b1f7a6c 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3556,6 +3556,18 @@ static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFF
|
||||
@@ -3545,6 +3545,18 @@ static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFF
|
||||
}
|
||||
|
||||
|
||||
@ -30,9 +29,9 @@ index 6310c4b414b..12df28a516e 100644
|
||||
+
|
||||
+
|
||||
/* add a symlink to the unix target at the last point of the reparse point metadata */
|
||||
NTSTATUS create_reparse_target( const char *unix_src, int depth, const char *link_path,
|
||||
NTSTATUS create_reparse_target( int dirfd, const char *unix_src, int depth, const char *link_path,
|
||||
REPARSE_DATA_BUFFER *buffer )
|
||||
@@ -3650,6 +3662,8 @@ NTSTATUS create_reparse_target( const char *unix_src, int depth, const char *lin
|
||||
@@ -3639,6 +3651,8 @@ NTSTATUS create_reparse_target( int dirfd, const char *unix_src, int depth, cons
|
||||
/* create the symlink to the target at the last metadata location */
|
||||
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
@ -41,7 +40,7 @@ index 6310c4b414b..12df28a516e 100644
|
||||
int relative_offset;
|
||||
|
||||
target_path[0] = 0;
|
||||
@@ -3659,8 +3673,21 @@ NTSTATUS create_reparse_target( const char *unix_src, int depth, const char *lin
|
||||
@@ -3648,8 +3662,21 @@ NTSTATUS create_reparse_target( int dirfd, const char *unix_src, int depth, cons
|
||||
relative_offset = 0;
|
||||
is_relative = FALSE;
|
||||
}
|
||||
@ -62,7 +61,33 @@ index 6310c4b414b..12df28a516e 100644
|
||||
+ strcat( target_path, prefix_string );
|
||||
strcat( target_path, &unix_target[relative_offset] );
|
||||
TRACE( "adding reparse point target: %s\n", target_path );
|
||||
symlink( target_path, link_path );
|
||||
symlinkat( target_path, dirfd, link_path );
|
||||
@@ -3855,6 +3882,7 @@ cleanup:
|
||||
NTSTATUS get_reparse_point_unix(const char *unix_name, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
{
|
||||
char link_dir[PATH_MAX], link_path[PATH_MAX], *d;
|
||||
+ const char prefix_string[] = "${WINEPREFIX}";
|
||||
int link_path_len, buffer_len, encoded_len;
|
||||
REPARSE_DATA_BUFFER header;
|
||||
ULONG out_size = *size;
|
||||
@@ -3953,6 +3981,17 @@ NTSTATUS get_reparse_point_unix(const char *unix_name, REPARSE_DATA_BUFFER *buff
|
||||
link_dir_fd = fd;
|
||||
}
|
||||
|
||||
+ /* if the prefix location has moved then update the Unix prefix passthrough link */
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ link_path_len = readlinkat( link_dir_fd, prefix_string, link_path, sizeof(link_path) );
|
||||
+ if (link_path_len > 0) link_path[link_path_len] = 0;
|
||||
+ if (link_path_len > 0 && strcmp( config_dir, link_path) != 0)
|
||||
+ {
|
||||
+ unlinkat( link_dir_fd, prefix_string, 0 );
|
||||
+ symlinkat( config_dir, link_dir_fd, prefix_string );
|
||||
+ }
|
||||
+
|
||||
/* Decode the reparse buffer from the base64-encoded symlink data */
|
||||
*size = decode_base64url( encoded, strlen(encoded), (char*)buffer );
|
||||
status = STATUS_SUCCESS;
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 18903b2921a76abaa12677c1c8d1b936d7e966d5 Mon Sep 17 00:00:00 2001
|
||||
From b0eff92e78691d5f864d14b96131d2a38a3aea1a Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 1 May 2019 12:06:20 -0600
|
||||
Subject: [PATCH] ntdll: Always report symbolic links as containing zero bytes.
|
||||
Subject: ntdll: Always report symbolic links as containing zero bytes.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -10,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 36 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 799a8cebe50..84797ba46b7 100644
|
||||
index a0b84849490..35ba5f03097 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5396,6 +5396,7 @@ static void test_reparse_points(void)
|
||||
@ -60,10 +60,10 @@ index 799a8cebe50..84797ba46b7 100644
|
||||
handle = CreateFileW(target_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 2a98d6baa28..ba3ea91b92f 100644
|
||||
index f298b1f7a6c..caa454c024f 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1797,6 +1797,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
@@ -1761,6 +1761,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
|
||||
/* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
@ -72,7 +72,7 @@ index 2a98d6baa28..ba3ea91b92f 100644
|
||||
/* whether a reparse point is a file or a directory is stored inside the link target */
|
||||
if (is_reparse_dir( fd, "", &is_dir ) == 0)
|
||||
st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
@@ -1857,6 +1859,8 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -1844,6 +1846,8 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
stat( path, st );
|
||||
/* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
@ -82,5 +82,5 @@ index 2a98d6baa28..ba3ea91b92f 100644
|
||||
if (is_reparse_dir( AT_FDCWD, path, &is_dir ) == 0)
|
||||
st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 4bd2d5bd482153546e644778dd7723dadf639d45 Mon Sep 17 00:00:00 2001
|
||||
From a6b3f7507ade04bcd9338a0936a2b1bfa8696fc1 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 1 May 2019 17:48:51 -0600
|
||||
Subject: [PATCH] ntdll: Find dangling symlinks quickly.
|
||||
Subject: ntdll: Find dangling symlinks quickly.
|
||||
|
||||
This is also necessary on systems (such as MacOS) that support
|
||||
case-insensitive lookups of files.
|
||||
@ -12,10 +12,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index ba3ea91b92f..db7c493a458 100644
|
||||
index caa454c024f..b26b239574b 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -2914,7 +2914,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
|
||||
@@ -2904,7 +2904,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
|
||||
if (ret >= 0 && ret <= MAX_DIR_ENTRY_LEN)
|
||||
{
|
||||
unix_name[pos + ret] = 0;
|
||||
@ -24,7 +24,7 @@ index ba3ea91b92f..db7c493a458 100644
|
||||
}
|
||||
if (check_case) goto not_found; /* we want an exact match */
|
||||
|
||||
@@ -4185,7 +4185,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
@@ -4228,7 +4228,7 @@ static NTSTATUS lookup_unix_name( FILE_OBJECT *fileobj, const WCHAR *name, int n
|
||||
char *p;
|
||||
unix_name[pos + 1 + ret] = 0;
|
||||
for (p = unix_name + pos ; *p; p++) if (*p == '\\') *p = '/';
|
||||
@ -34,5 +34,5 @@ index ba3ea91b92f..db7c493a458 100644
|
||||
if (disposition == FILE_CREATE) return STATUS_OBJECT_NAME_COLLISION;
|
||||
return STATUS_SUCCESS;
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From d3873d9acf5d2883a528d59a3c6f6a269694fa01 Mon Sep 17 00:00:00 2001
|
||||
From 6b1c261760080d470254b25b512625f4c1e3d935 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Mon, 23 Nov 2020 13:08:02 -0700
|
||||
Subject: [PATCH] ntdll: Succeed with no data for NtReadFile on reparse points.
|
||||
Subject: ntdll: Succeed with no data for NtReadFile on reparse points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -12,7 +12,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
4 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 84797ba46b7..f613a64b92b 100644
|
||||
index 35ba5f03097..8508161d269 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5636,7 +5636,7 @@ static void test_reparse_points(void)
|
||||
@ -25,10 +25,10 @@ index 84797ba46b7..f613a64b92b 100644
|
||||
CloseHandle(handle);
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index db7c493a458..8266478cd65 100644
|
||||
index b26b239574b..bf80708b41e 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6264,6 +6264,11 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
|
||||
@@ -6312,6 +6312,11 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
|
||||
if (needs_close) close( unix_handle );
|
||||
return status;
|
||||
}
|
||||
@ -65,5 +65,5 @@ index d828d41d1f7..aa7398369ad 100644
|
||||
FD_TYPE_SOCKET, /* socket */
|
||||
FD_TYPE_SERIAL, /* serial port */
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e5f483d10b2b90259061e115695beb9ae3e9aedf Mon Sep 17 00:00:00 2001
|
||||
From 76c4816f9015329c24968849f20063c07016a2da Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Wed, 25 Nov 2020 09:19:42 -0700
|
||||
Subject: [PATCH] ntdll: Add support for FileAttributeTagInformation.
|
||||
Subject: ntdll: Add support for FileAttributeTagInformation.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -10,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index f613a64b92b..a84abd66106 100644
|
||||
index 8508161d269..2450e9e5b4a 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5394,6 +5394,7 @@ static void test_reparse_points(void)
|
||||
@ -41,10 +41,10 @@ index f613a64b92b..a84abd66106 100644
|
||||
|
||||
/* Check the size/data of the symlink target */
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 8266478cd65..d5d62f3ba94 100644
|
||||
index bf80708b41e..51d6aed85f0 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5373,7 +5373,20 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -5421,7 +5421,20 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
{
|
||||
FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr;
|
||||
info->FileAttributes = attr;
|
||||
@ -67,5 +67,5 @@ index 8266478cd65..d5d62f3ba94 100644
|
||||
info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,8 +1,8 @@
|
||||
From f88d7e0e5ee70eaaa50c5fd448ad2cce1197c5cd Mon Sep 17 00:00:00 2001
|
||||
From 009a7b9e0b6be6fc559078b9544d4ca7b505a186 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 13 Mar 2019 16:02:05 -0600
|
||||
Subject: [PATCH] kernel32: Implement CreateSymbolicLink[A|W] with ntdll
|
||||
reparse points.
|
||||
Subject: kernel32: Implement CreateSymbolicLink[A|W] with ntdll reparse
|
||||
points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -161,7 +161,7 @@ index 3c57e81f4c6..fa143cb4e48 100644
|
||||
+ test_CreateSymbolicLink();
|
||||
}
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 2cbe8f4ac03..736589e9a5f 100644
|
||||
index 53b9651a8fa..bf6e9e17c9e 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -38,6 +38,7 @@
|
||||
@ -535,5 +535,5 @@ index 640e44e5b7c..6e9727f5854 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From fa2bfaa979927ffa57400dea9e5c86f72f680284 Mon Sep 17 00:00:00 2001
|
||||
From 4039b5b7bd3e8df9052006c5755a63aab93d52ef Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 15:11:42 -0600
|
||||
Subject: [PATCH] kernel32: Add reparse support to FindNextFile.
|
||||
Subject: kernel32: Add reparse support to FindNextFile.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 736589e9a5f..47b10d17acc 100644
|
||||
index bf6e9e17c9e..26d3dde5ad6 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -1508,6 +1508,30 @@ BOOL WINAPI DECLSPEC_HOTPATCH FindNextFileW( HANDLE handle, WIN32_FIND_DATAW *da
|
||||
@ -44,5 +44,5 @@ index 736589e9a5f..47b10d17acc 100644
|
||||
{
|
||||
memcpy( data->cAlternateFileName, dir_info->ShortName, dir_info->ShortNameLength );
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 5625bfea146c3845a6678dc3c4de49b1850e90b1 Mon Sep 17 00:00:00 2001
|
||||
From 8ceb056ccdf36bdf8a8692bd5882fc686aace5f6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 15:18:50 -0600
|
||||
Subject: [PATCH] wcmd: Display reparse point type in directory listings.
|
||||
Subject: wcmd: Display reparse point type in directory listings.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -46,5 +46,5 @@ index 8417687939a..a849807c76e 100644
|
||||
dir_count++;
|
||||
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From b488b1a3509afa3265d9c49bf7cc8dff4590c430 Mon Sep 17 00:00:00 2001
|
||||
From 563bc2fc3c48b2341a08a662e27e27a904702121 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 15:38:30 -0600
|
||||
Subject: [PATCH] wcmd: Show reparse point target in directory listing.
|
||||
Subject: wcmd: Show reparse point target in directory listing.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -62,5 +62,5 @@ index a849807c76e..5b0a19b442d 100644
|
||||
if (!((lstrcmpW(fd[i].cFileName, L".") == 0) ||
|
||||
(lstrcmpW(fd[i].cFileName, L"..") == 0))) {
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2dd44b98c47ecbff362b77ddacd7ff23a541fca7 Mon Sep 17 00:00:00 2001
|
||||
From 48cbd1c62bb0d2945334dfea222a7e19ea149c64 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 16:01:45 -0600
|
||||
Subject: [PATCH] wcmd: Add junction point support to mklink.
|
||||
Subject: wcmd: Add junction point support to mklink.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
@ -82,5 +82,5 @@ index dd3ae5b509b..53734b1e940 100644
|
||||
if(!ret)
|
||||
WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 489bbd44a182accd32dd26788ff19d0a439f49fd Mon Sep 17 00:00:00 2001
|
||||
From 57de4a076b99117d523349f168194c7334219303 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Mon, 3 May 2021 09:28:08 -0600
|
||||
Subject: [PATCH] ntdll: Add support for creating Unix/Linux symlinks.
|
||||
Subject: ntdll: Add support for creating Unix/Linux symlinks.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 35 ++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 48 +++++++++++++++++++++++++++--------------
|
||||
dlls/ntdll/tests/file.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 38 ++++++++++++++++++++++++++------------
|
||||
include/ntifs.h | 4 ++++
|
||||
include/winnt.h | 1 +
|
||||
4 files changed, 72 insertions(+), 16 deletions(-)
|
||||
4 files changed, 66 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index a84abd66106..f8f5e7f1ace 100644
|
||||
index 2450e9e5b4a..16a45636ebe 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5398,6 +5398,8 @@ static void test_reparse_points(void)
|
||||
@ -65,10 +65,10 @@ index a84abd66106..f8f5e7f1ace 100644
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index d5d62f3ba94..d495051a75a 100644
|
||||
index 51d6aed85f0..b17ee58d736 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3729,20 +3729,33 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -3751,20 +3751,33 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
* *) Append the base64-url encoded reparse point buffer
|
||||
* *) Append the filename of the first continuing symlink (0) in case we need it
|
||||
*/
|
||||
@ -86,10 +86,10 @@ index d5d62f3ba94..d495051a75a 100644
|
||||
- strncat( target_path, &encoded[i], chunk_len );
|
||||
+ strcpy( target_path, ".REPARSE_POINT/" );
|
||||
+ strcat( target_path, filename );
|
||||
strcat( target_path, "/" );
|
||||
+ strcat( target_path, "/" );
|
||||
+ if (is_dir)
|
||||
+ strcat( target_path, "." );
|
||||
+ strcat( target_path, "/" );
|
||||
strcat( target_path, "/" );
|
||||
+ for (depth=0; i<encoded_len && strlen(target_path)<SYM_MAX-2; i+=chunk_len, depth++)
|
||||
+ {
|
||||
+ chunk_len = min(NAME_MAX, SYM_MAX-2-strlen(target_path));
|
||||
@ -113,26 +113,16 @@ index d5d62f3ba94..d495051a75a 100644
|
||||
|
||||
/* Produce the link in a temporary location in the same folder */
|
||||
strcpy( tmpdir, unix_src );
|
||||
@@ -3804,11 +3817,14 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -3829,7 +3842,8 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
}
|
||||
|
||||
/* create the very last link directory */
|
||||
- strcpy( link_path, target_path );
|
||||
- strcpy( link_dir, link_path );
|
||||
- link_dir[strlen(link_dir)-1] = 0;
|
||||
- if (mkdir_p( link_dir, 0777) == 0)
|
||||
- create_reparse_target( unix_src, depth + 2, link_path, buffer );
|
||||
+ if (buffer->ReparseTag != IO_REPARSE_TAG_LX_SYMLINK)
|
||||
+ {
|
||||
+ strcpy( link_path, target_path );
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ if (mkdir_p( link_dir, 0777) == 0)
|
||||
+ create_reparse_target( unix_src, depth + 2, link_path, buffer );
|
||||
+ }
|
||||
|
||||
/* revert to the original directory */
|
||||
chdir( original_dir );
|
||||
- if (IsReparseTagNameSurrogate( buffer->ReparseTag ))
|
||||
+ if (IsReparseTagNameSurrogate( buffer->ReparseTag )
|
||||
+ && buffer->ReparseTag != IO_REPARSE_TAG_LX_SYMLINK)
|
||||
{
|
||||
strcpy( link_path, target_path );
|
||||
strcpy( link_dir, link_path );
|
||||
diff --git a/include/ntifs.h b/include/ntifs.h
|
||||
index 0d02225bc4f..25af12a413a 100644
|
||||
--- a/include/ntifs.h
|
||||
@ -149,7 +139,7 @@ index 0d02225bc4f..25af12a413a 100644
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
diff --git a/include/winnt.h b/include/winnt.h
|
||||
index 76aee026d84..96cab40201d 100644
|
||||
index 19bb5be83c4..ff4e502d65b 100644
|
||||
--- a/include/winnt.h
|
||||
+++ b/include/winnt.h
|
||||
@@ -2324,6 +2324,7 @@ extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
@ -161,5 +151,5 @@ index 76aee026d84..96cab40201d 100644
|
||||
#define IO_REPARSE_TAG_WCI_TOMBSTONE __MSABI_LONG(0xA000001F)
|
||||
#define IO_REPARSE_TAG_UNHANDLED __MSABI_LONG(0x80000020)
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,17 +1,16 @@
|
||||
From 3635077a0b682350123e9e2e9627dbdd973191e9 Mon Sep 17 00:00:00 2001
|
||||
From 867941be1803d23342470f8a464c066d52134031 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 16:32:44 -0700
|
||||
Subject: [PATCH] ntdll: Report regular Unix symlinks as WSL Linux/Unix
|
||||
symlinks.
|
||||
Subject: ntdll: Report regular Unix symlinks as WSL Linux/Unix symlinks.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 18 ++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 12 +++++++++++-
|
||||
2 files changed, 29 insertions(+), 1 deletion(-)
|
||||
dlls/ntdll/unix/file.c | 9 ++++++++-
|
||||
2 files changed, 26 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index f8f5e7f1ace..f0d80f4639b 100644
|
||||
index 16a45636ebe..979988e65fd 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5786,6 +5786,24 @@ static void test_reparse_points(void)
|
||||
@ -40,28 +39,25 @@ index f8f5e7f1ace..f0d80f4639b 100644
|
||||
memset(&guid_buffer, 0x00, sizeof(guid_buffer));
|
||||
guid_buffer.ReparseTag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index d495051a75a..6310c4b414b 100644
|
||||
index b17ee58d736..e6967a65a06 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3896,7 +3896,17 @@ NTSTATUS get_reparse_point_unix(const char *unix_src, REPARSE_DATA_BUFFER *buffe
|
||||
@@ -3921,7 +3921,14 @@ NTSTATUS get_reparse_point_unix(const char *unix_name, REPARSE_DATA_BUFFER *buff
|
||||
link_path[link_path_len] = 0;
|
||||
if (strncmp( link_path, ".REPARSE_POINT/", 15) != 0)
|
||||
if (strncmp( link_path, ".REPARSE_POINT/", 15 ) != 0)
|
||||
{
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
+ /* treat regular Unix symlinks as WSL Linux/Unix symlinks */
|
||||
+ int max_length, total_len;
|
||||
+
|
||||
+ max_length = out_size-FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[0]);
|
||||
+ if (link_path_len > max_length) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
|
||||
+ *size = FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[link_path_len]);
|
||||
+ if (*size > out_size) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
|
||||
+ buffer->ReparseTag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
+ buffer->LinuxSymbolicLinkReparseBuffer.Version = 2;
|
||||
+ memcpy( &buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer[0], link_path, link_path_len );
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[link_path_len]);
|
||||
+ buffer->ReparseDataLength = total_len - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ buffer->ReparseDataLength = *size - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ status = STATUS_SUCCESS;
|
||||
goto cleanup;
|
||||
}
|
||||
encoded_len = link_path_len;
|
||||
--
|
||||
2.35.1
|
||||
2.17.1
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 3abdca9dc957d524aa00ccd518aaa2a41a348582 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 16:15:03 -0700
|
||||
Subject: [PATCH] ntdll: Rewrite reparse point prefix symlink if the prefix
|
||||
location changes.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 12df28a516e..75153ae7620 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3903,6 +3903,7 @@ cleanup:
|
||||
NTSTATUS get_reparse_point_unix(const char *unix_src, REPARSE_DATA_BUFFER *buffer, ULONG *size)
|
||||
{
|
||||
char link_dir[PATH_MAX], original_dir[PATH_MAX], *d;
|
||||
+ const char prefix_string[] = "${WINEPREFIX}";
|
||||
int link_path_len, buffer_len, encoded_len;
|
||||
char link_path[PATH_MAX];
|
||||
REPARSE_DATA_BUFFER header;
|
||||
@@ -4008,6 +4009,18 @@ NTSTATUS get_reparse_point_unix(const char *unix_src, REPARSE_DATA_BUFFER *buffe
|
||||
chdir( link_dir );
|
||||
}
|
||||
|
||||
+ /* if the prefix location has moved then update the Unix prefix passthrough link */
|
||||
+ strcpy( link_dir, link_path );
|
||||
+ link_dir[strlen(link_dir)-1] = 0;
|
||||
+ chdir( link_dir );
|
||||
+ link_path_len = readlink( prefix_string, link_path, sizeof(link_path) );
|
||||
+ if (link_path_len > 0) link_path[link_path_len] = 0;
|
||||
+ if (link_path_len > 0 && strcmp( config_dir, link_path) != 0)
|
||||
+ {
|
||||
+ unlink( prefix_string );
|
||||
+ symlink( config_dir, prefix_string );
|
||||
+ }
|
||||
+
|
||||
/* revert to the original directory */
|
||||
chdir( original_dir );
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1697,19 +1697,18 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
|
||||
patch_apply ntdll-Junction_Points/0011-ntdll-Follow-reparse-points-during-path-resolution.patch
|
||||
patch_apply ntdll-Junction_Points/0012-kernel32-Advertise-reparse-point-support.patch
|
||||
patch_apply ntdll-Junction_Points/0013-ntdll-Allow-reparse-points-to-target-the-applicable-.patch
|
||||
patch_apply ntdll-Junction_Points/0014-ntdll-Always-report-symbolic-links-as-containing-zer.patch
|
||||
patch_apply ntdll-Junction_Points/0015-ntdll-Find-dangling-symlinks-quickly.patch
|
||||
patch_apply ntdll-Junction_Points/0016-ntdll-Succeed-with-no-data-for-NtReadFile-on-reparse.patch
|
||||
patch_apply ntdll-Junction_Points/0017-ntdll-Add-support-for-FileAttributeTagInformation.patch
|
||||
patch_apply ntdll-Junction_Points/0018-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch
|
||||
patch_apply ntdll-Junction_Points/0019-kernel32-Add-reparse-support-to-FindNextFile.patch
|
||||
patch_apply ntdll-Junction_Points/0020-wcmd-Display-reparse-point-type-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0021-wcmd-Show-reparse-point-target-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0022-wcmd-Add-junction-point-support-to-mklink.patch
|
||||
patch_apply ntdll-Junction_Points/0023-ntdll-Add-support-for-creating-Unix-Linux-symlinks.patch
|
||||
patch_apply ntdll-Junction_Points/0024-ntdll-Report-regular-Unix-symlinks-as-WSL-Linux-Unix.patch
|
||||
patch_apply ntdll-Junction_Points/0025-ntdll-Add-an-intermediary-symlink-in-reparse-point-m.patch
|
||||
patch_apply ntdll-Junction_Points/0026-ntdll-Rewrite-reparse-point-prefix-symlink-if-the-pr.patch
|
||||
patch_apply ntdll-Junction_Points/0014-ntdll-Add-an-intermediary-prefix-symlink-in-reparse-.patch
|
||||
patch_apply ntdll-Junction_Points/0015-ntdll-Always-report-symbolic-links-as-containing-zer.patch
|
||||
patch_apply ntdll-Junction_Points/0016-ntdll-Find-dangling-symlinks-quickly.patch
|
||||
patch_apply ntdll-Junction_Points/0017-ntdll-Succeed-with-no-data-for-NtReadFile-on-reparse.patch
|
||||
patch_apply ntdll-Junction_Points/0018-ntdll-Add-support-for-FileAttributeTagInformation.patch
|
||||
patch_apply ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch
|
||||
patch_apply ntdll-Junction_Points/0020-kernel32-Add-reparse-support-to-FindNextFile.patch
|
||||
patch_apply ntdll-Junction_Points/0021-wcmd-Display-reparse-point-type-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0022-wcmd-Show-reparse-point-target-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0023-wcmd-Add-junction-point-support-to-mklink.patch
|
||||
patch_apply ntdll-Junction_Points/0024-ntdll-Add-support-for-creating-Unix-Linux-symlinks.patch
|
||||
patch_apply ntdll-Junction_Points/0025-ntdll-Report-regular-Unix-symlinks-as-WSL-Linux-Unix.patch
|
||||
fi
|
||||
|
||||
# Patchset server-PeekMessage
|
||||
|
Loading…
Reference in New Issue
Block a user