diff --git a/patches/ntdll-Junction_Points/0011-ntdll-Follow-reparse-points-during-path-resolution.patch b/patches/ntdll-Junction_Points/0011-ntdll-Follow-reparse-points-during-path-resolution.patch index c1cf157a..9dbdc3cf 100644 --- a/patches/ntdll-Junction_Points/0011-ntdll-Follow-reparse-points-during-path-resolution.patch +++ b/patches/ntdll-Junction_Points/0011-ntdll-Follow-reparse-points-during-path-resolution.patch @@ -1,4 +1,4 @@ -From beaeb1935534ce99aa19b8009184b07bd602a24c Mon Sep 17 00:00:00 2001 +From 4f26d71abf2447b5e0c6d7b6e878cf6b6c578558 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 3 Sep 2022 11:23:31 -0600 Subject: [PATCH] ntdll: Follow reparse points during path resolution. @@ -6,14 +6,14 @@ Subject: [PATCH] ntdll: Follow reparse points during path resolution. Signed-off-by: Erich E. Hoover --- dlls/ntdll/tests/file.c | 11 ++- - dlls/ntdll/unix/file.c | 189 +++++++++++++++++++++++++++++++++++----- - 2 files changed, 177 insertions(+), 23 deletions(-) + dlls/ntdll/unix/file.c | 196 +++++++++++++++++++++++++++++++++++----- + 2 files changed, 184 insertions(+), 23 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 390768f557d..a0b84849490 100644 +index 39b98af7efa..80b967f5469 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, +@@ -6082,7 +6082,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, ULONG flags, static void test_reparse_points(void) { @@ -22,7 +22,7 @@ index 390768f557d..a0b84849490 100644 static const WCHAR new_reparseW[] = {'\\','n','e','w','_','r','e','p','a','r','s','e',0}; static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0}; static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0}; -@@ -5768,11 +5768,20 @@ static void test_reparse_points(void) +@@ -6469,11 +6469,20 @@ static void test_reparse_points(void) bret = CopyFileW(reparse_path, new_path, TRUE); ok(!bret, "Reparse points cannot be copied.\n"); @@ -44,10 +44,10 @@ index 390768f557d..a0b84849490 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 9211c6964a6..e90670ffc71 100644 +index 49afb57b2b6..26e412d28f1 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c -@@ -3548,6 +3548,35 @@ done: +@@ -3725,6 +3725,35 @@ done: } @@ -83,7 +83,7 @@ index 9211c6964a6..e90670ffc71 100644 /* * 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. -@@ -3724,16 +3753,14 @@ cleanup: +@@ -3901,16 +3930,14 @@ cleanup: /* @@ -102,7 +102,7 @@ index 9211c6964a6..e90670ffc71 100644 char *encoded = NULL; int link_dir_fd = -1; NTSTATUS status; -@@ -3741,9 +3768,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si +@@ -3918,9 +3945,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si int depth; char *p; @@ -112,7 +112,7 @@ index 9211c6964a6..e90670ffc71 100644 ret = readlink( unix_name, link_path, sizeof(link_path) ); if (ret < 0) { -@@ -3843,12 +3867,76 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si +@@ -4020,12 +4044,76 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si cleanup: if (link_dir_fd != -1) close( link_dir_fd ); @@ -190,7 +190,7 @@ index 9211c6964a6..e90670ffc71 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. -@@ -3942,15 +4030,25 @@ cleanup: +@@ -4119,15 +4207,24 @@ cleanup: } @@ -207,18 +207,16 @@ index 9211c6964a6..e90670ffc71 100644 * * 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 NTSTATUS lookup_unix_name( int root_fd, const WCHAR *name, int name_len, char **buffer, int unix_len, ++static NTSTATUS lookup_unix_name( FILE_OBJECT *fileobj, int root_fd, 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 }; + const WCHAR *fullname = fileobj->FileName.Buffer; NTSTATUS status; int ret; struct stat st; -@@ -4007,6 +4105,8 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer +@@ -4184,6 +4281,8 @@ static NTSTATUS lookup_unix_name( int root_fd, const WCHAR *name, int name_len, while (name_len) { const WCHAR *end, *next; @@ -227,9 +225,9 @@ index 9211c6964a6..e90670ffc71 100644 end = name; while (end < name + name_len && *end != '\\') end++; -@@ -4026,8 +4126,31 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer +@@ -4203,8 +4302,31 @@ static NTSTATUS lookup_unix_name( int root_fd, const WCHAR *name, int name_len, - status = find_file_in_dir( unix_name, pos, name, end - name, is_unix ); + status = find_file_in_dir( root_fd, unix_name, pos, name, end - name, is_unix ); + /* follow reparse point and restart from there (if applicable) */ + if (name_len && find_reparse_target( unix_name, fullname, name - fullname, &target, &target_len ) == STATUS_REPARSE) @@ -260,7 +258,7 @@ index 9211c6964a6..e90670ffc71 100644 { if (status == STATUS_OBJECT_NAME_NOT_FOUND) { -@@ -4066,12 +4189,12 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer +@@ -4243,12 +4365,12 @@ static NTSTATUS lookup_unix_name( int root_fd, const WCHAR *name, int name_len, /****************************************************************************** * nt_to_unix_file_name_no_root */ @@ -275,16 +273,16 @@ index 9211c6964a6..e90670ffc71 100644 NTSTATUS status = STATUS_SUCCESS; const WCHAR *name; struct stat st; -@@ -4161,7 +4284,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char +@@ -4338,7 +4460,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char name += prefix_len; name_len -= prefix_len; -- 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 ); +- status = lookup_unix_name( AT_FDCWD, name, name_len, &unix_name, unix_len, pos, disposition, is_unix ); ++ status = lookup_unix_name( fileobj, AT_FDCWD, 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) ); -@@ -4169,7 +4292,8 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char +@@ -4346,7 +4468,8 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char } else { @@ -294,13 +292,14 @@ index 9211c6964a6..e90670ffc71 100644 free( unix_name ); } return status; -@@ -4187,18 +4311,30 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char +@@ -4364,18 +4487,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 root_fd, needs_close; ++ int old_cwd, root_fd, needs_close; + int reparse_count = 0; + FILE_OBJECT fileobj; const WCHAR *name; @@ -329,7 +328,7 @@ index 9211c6964a6..e90670ffc71 100644 if (name_len && name[0] == '\\') return STATUS_INVALID_PARAMETER; -@@ -4206,7 +4342,7 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U +@@ -4383,7 +4518,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] = '.'; @@ -338,17 +337,25 @@ index 9211c6964a6..e90670ffc71 100644 { if (type != FD_TYPE_DIR) { -@@ -4218,7 +4354,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, +@@ -4392,7 +4527,16 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U + } + else + { +- status = lookup_unix_name( root_fd, name, name_len, &unix_name, unix_len, 1, disposition, FALSE ); ++ mutex_lock( &dir_mutex ); ++ if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1) ++ { ++ status = lookup_unix_name( &fileobj, root_fd, name, name_len, &unix_name, unix_len, 1, + disposition, FALSE ); - if (fchdir( old_cwd ) == -1) chdir( "/" ); - } - else status = errno_to_status( errno ); -@@ -4231,14 +4368,22 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U ++ if (fchdir( old_cwd ) == -1) chdir( "/" ); ++ } ++ else status = errno_to_status( errno ); ++ mutex_unlock( &dir_mutex ); ++ if (old_cwd != -1) close( old_cwd ); + if (needs_close) close( root_fd ); + } + } +@@ -4400,14 +4544,22 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE) { @@ -373,5 +380,5 @@ index 9211c6964a6..e90670ffc71 100644 } -- -2.35.1 +2.47.2 diff --git a/patches/ntdll-Junction_Points/0016-ntdll-Find-dangling-symlinks-quickly.patch b/patches/ntdll-Junction_Points/0016-ntdll-Find-dangling-symlinks-quickly.patch deleted file mode 100644 index 8b1f9e3e..00000000 --- a/patches/ntdll-Junction_Points/0016-ntdll-Find-dangling-symlinks-quickly.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a6b3f7507ade04bcd9338a0936a2b1bfa8696fc1 Mon Sep 17 00:00:00 2001 -From: "Erich E. Hoover" -Date: Wed, 1 May 2019 17:48:51 -0600 -Subject: ntdll: Find dangling symlinks quickly. - -This is also necessary on systems (such as MacOS) that support -case-insensitive lookups of files. - -Signed-off-by: Erich E. Hoover ---- - dlls/ntdll/unix/file.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index caa454c024f..b26b239574b 100644 ---- a/dlls/ntdll/unix/file.c -+++ b/dlls/ntdll/unix/file.c -@@ -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; -- if (!stat( unix_name, &st )) return STATUS_SUCCESS; -+ if (!lstat( unix_name, &st )) return STATUS_SUCCESS; - } - if (check_case) goto not_found; /* we want an exact match */ - -@@ -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 = '/'; -- if (!stat( unix_name, &st )) -+ if (!lstat( unix_name, &st )) - { - if (disposition == FILE_CREATE) return STATUS_OBJECT_NAME_COLLISION; - return STATUS_SUCCESS; --- -2.17.1 - diff --git a/staging/upstream-commit b/staging/upstream-commit index 3d488eb8..e1a8ad92 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -b201cd518f3448553c31e329d5504b94f21d84ce +6298b0cab2086ae61f46b284d22c420dfbb2b44e