You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Rebase against 6298b0cab2086ae61f46b284d22c420dfbb2b44e.
This commit is contained in:
@@ -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" <erich.e.hoover@gmail.com>
|
||||
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 <erich.e.hoover@gmail.com>
|
||||
---
|
||||
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
|
||||
|
||||
|
@@ -1,38 +0,0 @@
|
||||
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: 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 <erich.e.hoover@gmail.com>
|
||||
---
|
||||
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
|
||||
|
@@ -1 +1 @@
|
||||
b201cd518f3448553c31e329d5504b94f21d84ce
|
||||
6298b0cab2086ae61f46b284d22c420dfbb2b44e
|
||||
|
Reference in New Issue
Block a user