mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
ntdll-Junction_Points: Updates from Erich E. Hoover.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50770 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50804 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50878 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51059
This commit is contained in:
parent
7c888e7fee
commit
8e5c8cc63b
@ -1,4 +1,4 @@
|
||||
From 719f4d5ab7ba2b2e9f3797dfce0370fa5cba5a66 Mon Sep 17 00:00:00 2001
|
||||
From a83181801d5248f7e228810bfe0a829a81be345f 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 junction point creation.
|
||||
@ -14,10 +14,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
create mode 100644 include/ntifs.h
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ce6bad68f68..11f57d13274 100644
|
||||
index 71991bd3938..7553b22e76d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2218,6 +2218,8 @@ AC_CHECK_FUNCS(\
|
||||
@@ -2219,6 +2219,8 @@ AC_CHECK_FUNCS(\
|
||||
proc_pidinfo \
|
||||
pwrite \
|
||||
readlink \
|
||||
@ -27,7 +27,7 @@ index ce6bad68f68..11f57d13274 100644
|
||||
setproctitle \
|
||||
setprogname \
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 498da270a34..792c07b0d8e 100644
|
||||
index 2c1835e3ff0..54e06a3f126 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -38,6 +38,7 @@
|
||||
@ -38,7 +38,7 @@ index 498da270a34..792c07b0d8e 100644
|
||||
|
||||
#ifndef IO_COMPLETION_ALL_ACCESS
|
||||
#define IO_COMPLETION_ALL_ACCESS 0x001F0003
|
||||
@@ -5152,6 +5153,105 @@ static void test_mailslot_name(void)
|
||||
@@ -5233,6 +5234,105 @@ static void test_mailslot_name(void)
|
||||
CloseHandle( device );
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ index 498da270a34..792c07b0d8e 100644
|
||||
START_TEST(file)
|
||||
{
|
||||
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||
@@ -5224,5 +5324,6 @@ START_TEST(file)
|
||||
@@ -5305,5 +5405,6 @@ START_TEST(file)
|
||||
test_ioctl();
|
||||
test_query_ea();
|
||||
test_flush_buffers_file();
|
||||
@ -152,7 +152,7 @@ index 498da270a34..792c07b0d8e 100644
|
||||
test_mailslot_name();
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index a4728003cf8..ea9c0d811f5 100644
|
||||
index 700ee717294..492838d9031 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -36,6 +36,7 @@
|
||||
@ -182,7 +182,7 @@ index a4728003cf8..ea9c0d811f5 100644
|
||||
#ifdef linux
|
||||
|
||||
/* We want the real kernel dirent structure, not the libc one */
|
||||
@@ -479,6 +485,32 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si
|
||||
@@ -477,6 +483,32 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ index a4728003cf8..ea9c0d811f5 100644
|
||||
/* get space from the current directory data buffer, allocating a new one if necessary */
|
||||
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
|
||||
{
|
||||
@@ -5806,6 +5838,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
@@ -5950,6 +5982,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ index a4728003cf8..ea9c0d811f5 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.
|
||||
+ */
|
||||
+NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
+NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
+{
|
||||
+ BOOL src_allocated = FALSE, dest_allocated = FALSE, tempdir_created = FALSE;
|
||||
+ int dest_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
@ -332,7 +332,7 @@ index a4728003cf8..ea9c0d811f5 100644
|
||||
/******************************************************************************
|
||||
* NtFsControlFile (NTDLL.@)
|
||||
*/
|
||||
@@ -5888,6 +6030,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6032,6 +6174,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ index a4728003cf8..ea9c0d811f5 100644
|
||||
+ switch(buffer->ReparseTag)
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ status = FILE_CreateSymlink( handle, buffer );
|
||||
+ status = create_reparse_point( handle, buffer );
|
||||
+ break;
|
||||
+ default:
|
||||
+ FIXME("stub: FSCTL_SET_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
@ -357,10 +357,10 @@ index a4728003cf8..ea9c0d811f5 100644
|
||||
TRACE("FSCTL_SET_SPARSE: Ignoring request\n");
|
||||
io->Information = 0;
|
||||
diff --git a/include/Makefile.in b/include/Makefile.in
|
||||
index 6c16e01a271..bf938cae250 100644
|
||||
index 9822bce6bdd..00a1be0b74e 100644
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -533,6 +533,7 @@ SOURCES = \
|
||||
@@ -538,6 +538,7 @@ SOURCES = \
|
||||
ntddvdeo.h \
|
||||
ntdef.h \
|
||||
ntdsapi.h \
|
||||
@ -417,5 +417,5 @@ index 00000000000..21d42e17325
|
||||
+
|
||||
+#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,23 +1,28 @@
|
||||
From ba7660d29357412b0a12475dacd1d96da9d5679c Mon Sep 17 00:00:00 2001
|
||||
From 49ed938003d970383e684d7db56bf570d0d94b2a 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 junction points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 14 ++++-
|
||||
dlls/ntdll/unix/file.c | 120 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 133 insertions(+), 1 deletion(-)
|
||||
dlls/ntdll/tests/file.c | 20 ++++++-
|
||||
dlls/ntdll/unix/file.c | 125 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 144 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 792c07b0d8e..88e114ab7a2 100644
|
||||
index 54e06a3f126..a3f3485ce46 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5189,9 +5189,10 @@ static void test_reparse_points(void)
|
||||
@@ -5265,14 +5265,15 @@ static void test_reparse_points(void)
|
||||
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
|
||||
WCHAR path[MAX_PATH], reparse_path[MAX_PATH], target_path[MAX_PATH];
|
||||
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
|
||||
+ INT buffer_len, string_len, path_len, total_len;
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
static WCHAR volW[] = {'c',':','\\',0};
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags;
|
||||
+ INT buffer_len, string_len;
|
||||
UNICODE_STRING nameW;
|
||||
- INT buffer_len;
|
||||
HANDLE handle;
|
||||
@ -25,7 +30,7 @@ index 792c07b0d8e..88e114ab7a2 100644
|
||||
BOOL bret;
|
||||
|
||||
/* Create a temporary folder for the junction point tests */
|
||||
@@ -5239,6 +5240,17 @@ static void test_reparse_points(void)
|
||||
@@ -5320,6 +5321,23 @@ static void test_reparse_points(void)
|
||||
buffer_len = build_reparse_buffer(nameW.Buffer, &buffer);
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
@ -40,14 +45,20 @@ index 792c07b0d8e..88e114ab7a2 100644
|
||||
+ dest = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
+ ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
|
||||
+ wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));
|
||||
+ path_len = buffer->MountPointReparseBuffer.PrintNameOffset/sizeof(WCHAR);
|
||||
+ path_len += buffer->MountPointReparseBuffer.PrintNameLength/sizeof(WCHAR);
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len+1])
|
||||
+ - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
|
||||
+ buffer->ReparseDataLength, total_len);
|
||||
CloseHandle(handle);
|
||||
|
||||
cleanup:
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index ea9c0d811f5..6389e7c8f20 100644
|
||||
index 492838d9031..5289c0eec71 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5948,6 +5948,120 @@ cleanup:
|
||||
@@ -6092,6 +6092,125 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -55,9 +66,10 @@ index ea9c0d811f5..6389e7c8f20 100644
|
||||
+ * Retrieve the unix name corresponding to a file handle and use that to find the destination of the
|
||||
+ * symlink corresponding to that file handle.
|
||||
+ */
|
||||
+NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+{
|
||||
+ char *unix_src, unix_dest[PATH_MAX];
|
||||
+ INT prefix_len, path_len, total_len;
|
||||
+ VOID *subst_name, *print_name;
|
||||
+ SIZE_T nt_dest_len = PATH_MAX;
|
||||
+ BOOL dest_allocated = FALSE;
|
||||
@ -66,7 +78,6 @@ index ea9c0d811f5..6389e7c8f20 100644
|
||||
+ DWORD max_length;
|
||||
+ NTSTATUS status;
|
||||
+ WCHAR *nt_dest;
|
||||
+ INT prefix_len;
|
||||
+ ssize_t ret;
|
||||
+ char *p;
|
||||
+ int i;
|
||||
@ -135,12 +146,16 @@ index ea9c0d811f5..6389e7c8f20 100644
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ max_length = out_size-FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[1]);
|
||||
+ buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
|
||||
+ path_len = 0;
|
||||
+ buffer->MountPointReparseBuffer.SubstituteNameOffset = path_len;
|
||||
+ buffer->MountPointReparseBuffer.SubstituteNameLength = nt_dest_len;
|
||||
+ path_len += nt_dest_len + sizeof(WCHAR);
|
||||
+ subst_name = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
+ buffer->MountPointReparseBuffer.PrintNameOffset = nt_dest_len + sizeof(WCHAR);
|
||||
+ buffer->MountPointReparseBuffer.PrintNameOffset = path_len;
|
||||
+ buffer->MountPointReparseBuffer.PrintNameLength = nt_dest_len - prefix_len*sizeof(WCHAR);
|
||||
+ print_name = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
|
||||
+ path_len += (nt_dest_len - prefix_len*sizeof(WCHAR)) + sizeof(WCHAR);
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len/sizeof(WCHAR)]);
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* unrecognized (regular) files should probably be treated as symlinks */
|
||||
@ -156,6 +171,7 @@ index ea9c0d811f5..6389e7c8f20 100644
|
||||
+
|
||||
+ memcpy( subst_name, nt_dest, nt_dest_len );
|
||||
+ memcpy( print_name, &nt_dest[prefix_len], nt_dest_len - prefix_len*sizeof(WCHAR) );
|
||||
+ buffer->ReparseDataLength = total_len - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ status = STATUS_SUCCESS;
|
||||
+
|
||||
+cleanup:
|
||||
@ -168,19 +184,19 @@ index ea9c0d811f5..6389e7c8f20 100644
|
||||
/******************************************************************************
|
||||
* NtFsControlFile (NTDLL.@)
|
||||
*/
|
||||
@@ -6030,6 +6144,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6174,6 +6293,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
+ case FSCTL_GET_REPARSE_POINT:
|
||||
+ {
|
||||
+ REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)out_buffer;
|
||||
+ status = FILE_GetSymlink( handle, buffer, out_size );
|
||||
+ status = get_reparse_point( handle, buffer, out_size );
|
||||
+ break;
|
||||
+ }
|
||||
case FSCTL_SET_REPARSE_POINT:
|
||||
{
|
||||
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)in_buffer;
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 7554efacce44c930a981312bcf341b74e896fc17 Mon Sep 17 00:00:00 2001
|
||||
From cc1a2a1ade9c176a7c77a5673c26cee6ab85963c 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 junction points.
|
||||
@ -11,13 +11,13 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
3 files changed, 131 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 88e114ab7a2..0dcefdef97b 100644
|
||||
index a3f3485ce46..b844fe9e1d3 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5184,12 +5184,15 @@ static void test_reparse_points(void)
|
||||
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
|
||||
@@ -5266,11 +5266,14 @@ static void test_reparse_points(void)
|
||||
WCHAR path[MAX_PATH], reparse_path[MAX_PATH], target_path[MAX_PATH];
|
||||
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
|
||||
INT buffer_len, string_len, path_len, total_len;
|
||||
+ FILE_BASIC_INFORMATION old_attrib, new_attrib;
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
static WCHAR volW[] = {'c',':','\\',0};
|
||||
@ -25,12 +25,11 @@ index 88e114ab7a2..0dcefdef97b 100644
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags;
|
||||
INT buffer_len, string_len;
|
||||
+ IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
HANDLE handle;
|
||||
WCHAR *dest;
|
||||
@@ -5237,6 +5240,8 @@ static void test_reparse_points(void)
|
||||
@@ -5318,6 +5321,8 @@ static void test_reparse_points(void)
|
||||
win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
@ -39,10 +38,10 @@ index 88e114ab7a2..0dcefdef97b 100644
|
||||
buffer_len = build_reparse_buffer(nameW.Buffer, &buffer);
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
@@ -5251,6 +5256,22 @@ static void test_reparse_points(void)
|
||||
dest = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
|
||||
wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));
|
||||
@@ -5338,6 +5343,22 @@ static void test_reparse_points(void)
|
||||
- FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
|
||||
buffer->ReparseDataLength, total_len);
|
||||
+
|
||||
+ /* Delete the junction point */
|
||||
+ memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
@ -62,7 +61,7 @@ index 88e114ab7a2..0dcefdef97b 100644
|
||||
CloseHandle(handle);
|
||||
|
||||
cleanup:
|
||||
@@ -5258,7 +5279,7 @@ cleanup:
|
||||
@@ -5345,7 +5366,7 @@ cleanup:
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
@ -72,10 +71,10 @@ index 88e114ab7a2..0dcefdef97b 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 6389e7c8f20..982df84d029 100644
|
||||
index 5289c0eec71..118f81db3c1 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6062,6 +6062,87 @@ cleanup:
|
||||
@@ -6211,6 +6211,87 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +82,7 @@ index 6389e7c8f20..982df84d029 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.
|
||||
+ */
|
||||
+NTSTATUS FILE_RemoveSymlink(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
+NTSTATUS remove_reparse_point(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
+{
|
||||
+ char tmpdir[PATH_MAX], tmpfile[PATH_MAX], *d;
|
||||
+ BOOL tempdir_created = FALSE;
|
||||
@ -163,7 +162,7 @@ index 6389e7c8f20..982df84d029 100644
|
||||
/******************************************************************************
|
||||
* NtFsControlFile (NTDLL.@)
|
||||
*/
|
||||
@@ -6144,6 +6225,22 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6293,6 +6374,22 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -174,7 +173,7 @@ index 6389e7c8f20..982df84d029 100644
|
||||
+ switch(buffer->ReparseTag)
|
||||
+ {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ status = FILE_RemoveSymlink( handle, buffer );
|
||||
+ status = remove_reparse_point( handle, buffer );
|
||||
+ break;
|
||||
+ default:
|
||||
+ FIXME("stub: FSCTL_DELETE_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
@ -208,5 +207,5 @@ index 21d42e17325..4539b89d583 100644
|
||||
+
|
||||
#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From c0fe3802d5baca7d4048abfca0dcc261fb63ad2c Mon Sep 17 00:00:00 2001
|
||||
From 2b0a539941dcd1a292cda3f506abb6359f409527 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 a test for junction point advertisement.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 0dcefdef97b..7ad25ffd239 100644
|
||||
index b844fe9e1d3..504d67adde6 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5246,6 +5246,11 @@ static void test_reparse_points(void)
|
||||
@@ -5327,6 +5327,11 @@ static void test_reparse_points(void)
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
|
||||
@ -25,5 +25,5 @@ index 0dcefdef97b..7ad25ffd239 100644
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR);
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 55571cb23f81d2d5836c69793d5621f09f535009 Mon Sep 17 00:00:00 2001
|
||||
From d5a062699b1a599fc87ba757e65b3aeb2ead9834 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: Add support for deleting junction points with
|
||||
@ -11,19 +11,19 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 60 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 7ad25ffd239..5a2ac2114b0 100644
|
||||
index 504d67adde6..2ddabc865bf 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5190,7 +5190,7 @@ static void test_reparse_points(void)
|
||||
@@ -5272,7 +5272,7 @@ static void test_reparse_points(void)
|
||||
REPARSE_GUID_DATA_BUFFER guid_buffer;
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
- DWORD dwret, dwLen, dwFlags;
|
||||
+ DWORD dwret, dwLen, dwFlags, err;
|
||||
INT buffer_len, string_len;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
@@ -5279,6 +5279,38 @@ static void test_reparse_points(void)
|
||||
HANDLE handle;
|
||||
@@ -5366,6 +5366,38 @@ static void test_reparse_points(void)
|
||||
"Junction point folder's access time does not match.\n");
|
||||
CloseHandle(handle);
|
||||
|
||||
@ -63,7 +63,7 @@ index 7ad25ffd239..5a2ac2114b0 100644
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 65a6f876e5c..4f43f41fb31 100644
|
||||
index 481e9a88f0f..2605adf96ff 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -169,7 +169,8 @@ struct closed_fd
|
||||
@ -187,7 +187,7 @@ index 65a6f876e5c..4f43f41fb31 100644
|
||||
/* check directory options */
|
||||
if ((options & FILE_DIRECTORY_FILE) && !S_ISDIR(st.st_mode))
|
||||
{
|
||||
@@ -2611,10 +2629,10 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
@@ -2605,10 +2623,10 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
|
||||
free( fd->nt_name );
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
@ -201,5 +201,5 @@ index 65a6f876e5c..4f43f41fb31 100644
|
||||
return;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2086a18555c0c4111c48676af90c642828ce87f5 Mon Sep 17 00:00:00 2001
|
||||
From 58c9e69484d7c8da358e61de61827ec1d8399bbd 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 junction point support.
|
||||
@ -9,7 +9,7 @@ Subject: [PATCH] kernel32: Advertise junction point support.
|
||||
2 files changed, 86 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
|
||||
index dd2c7d70759..171dc6ea592 100644
|
||||
index 04e8fe3c0f5..c8e7d6bf088 100644
|
||||
--- a/dlls/mountmgr.sys/device.c
|
||||
+++ b/dlls/mountmgr.sys/device.c
|
||||
@@ -31,6 +31,21 @@
|
||||
@ -34,7 +34,7 @@ index dd2c7d70759..171dc6ea592 100644
|
||||
|
||||
#define NONAMELESSUNION
|
||||
|
||||
@@ -1828,6 +1843,68 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
|
||||
@@ -1902,6 +1917,68 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ index dd2c7d70759..171dc6ea592 100644
|
||||
static NTSTATUS WINAPI harddisk_query_volume( DEVICE_OBJECT *device, IRP *irp )
|
||||
{
|
||||
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
|
||||
@@ -1916,7 +1993,8 @@ static NTSTATUS WINAPI harddisk_query_volume( DEVICE_OBJECT *device, IRP *irp )
|
||||
@@ -1990,7 +2067,8 @@ static NTSTATUS WINAPI harddisk_query_volume( DEVICE_OBJECT *device, IRP *irp )
|
||||
memcpy(info->FileSystemName, fat32W, info->FileSystemNameLength);
|
||||
break;
|
||||
default:
|
||||
@ -114,10 +114,10 @@ index dd2c7d70759..171dc6ea592 100644
|
||||
info->FileSystemNameLength = min( sizeof(ntfsW), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
|
||||
memcpy(info->FileSystemName, ntfsW, info->FileSystemNameLength);
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 5a2ac2114b0..5882793c883 100644
|
||||
index 2ddabc865bf..699d5e67d88 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5181,8 +5181,8 @@ static INT build_reparse_buffer(const WCHAR *filename, REPARSE_DATA_BUFFER **pbu
|
||||
@@ -5262,8 +5262,8 @@ static INT build_reparse_buffer(const WCHAR *filename, REPARSE_DATA_BUFFER **pbu
|
||||
|
||||
static void test_reparse_points(void)
|
||||
{
|
||||
@ -125,9 +125,9 @@ index 5a2ac2114b0..5882793c883 100644
|
||||
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
|
||||
- WCHAR path[MAX_PATH], reparse_path[MAX_PATH], target_path[MAX_PATH];
|
||||
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
|
||||
INT buffer_len, string_len, path_len, total_len;
|
||||
FILE_BASIC_INFORMATION old_attrib, new_attrib;
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
@@ -5211,7 +5211,12 @@ static void test_reparse_points(void)
|
||||
@@ -5292,7 +5292,12 @@ static void test_reparse_points(void)
|
||||
pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL);
|
||||
volW[0] = nameW.Buffer[4];
|
||||
pRtlFreeUnicodeString( &nameW );
|
||||
@ -142,5 +142,5 @@ index 5a2ac2114b0..5882793c883 100644
|
||||
{
|
||||
skip("File system does not support reparse points.\n");
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 7fd3c661bce1c490fe9e2ad04b524777e897b896 Mon Sep 17 00:00:00 2001
|
||||
From fb7afe57f143a7777f54c1e936d60af5ace51865 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 21:06:24 -0700
|
||||
Subject: [PATCH] ntdll: Add support for absolute symlink creation.
|
||||
@ -6,15 +6,15 @@ Subject: [PATCH] ntdll: Add support for absolute symlink creation.
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 117 ++++++++++++++++++++++++++++++++++------
|
||||
dlls/ntdll/unix/file.c | 37 +++++++++++--
|
||||
dlls/ntdll/unix/file.c | 49 ++++++++++++-----
|
||||
include/ntifs.h | 10 ++++
|
||||
3 files changed, 145 insertions(+), 19 deletions(-)
|
||||
3 files changed, 146 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 5882793c883..53a24574eec 100644
|
||||
index 699d5e67d88..e0fa36ea64f 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5153,26 +5153,50 @@ static void test_mailslot_name(void)
|
||||
@@ -5234,26 +5234,50 @@ static void test_mailslot_name(void)
|
||||
CloseHandle( device );
|
||||
}
|
||||
|
||||
@ -73,10 +73,10 @@ index 5882793c883..53a24574eec 100644
|
||||
lstrcpyW(subst_dest, filename);
|
||||
lstrcpyW(print_dest, &filename[prefix_len]);
|
||||
*pbuffer = buffer;
|
||||
@@ -5192,10 +5216,12 @@ static void test_reparse_points(void)
|
||||
@@ -5273,10 +5297,12 @@ static void test_reparse_points(void)
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
INT buffer_len, string_len;
|
||||
+ HANDLE handle, token;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
@ -87,7 +87,7 @@ index 5882793c883..53a24574eec 100644
|
||||
BOOL bret;
|
||||
|
||||
/* Create a temporary folder for the junction point tests */
|
||||
@@ -5247,7 +5273,7 @@ static void test_reparse_points(void)
|
||||
@@ -5328,7 +5354,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%x).\n", dwret);
|
||||
@ -96,7 +96,7 @@ index 5882793c883..53a24574eec 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
|
||||
@@ -5288,7 +5314,7 @@ static void test_reparse_points(void)
|
||||
@@ -5375,7 +5401,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);
|
||||
@ -105,7 +105,7 @@ index 5882793c883..53a24574eec 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5303,7 +5329,7 @@ static void test_reparse_points(void)
|
||||
@@ -5390,7 +5416,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);
|
||||
@ -114,7 +114,7 @@ index 5882793c883..53a24574eec 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5316,14 +5342,73 @@ static void test_reparse_points(void)
|
||||
@@ -5403,14 +5429,73 @@ static void test_reparse_points(void)
|
||||
ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret);
|
||||
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: 0x%x)\n", dwret);
|
||||
|
||||
@ -193,11 +193,11 @@ index 5882793c883..53a24574eec 100644
|
||||
}
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 773223acd7c..9e4d00deb0e 100644
|
||||
index 118f81db3c1..da5136db68c 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5845,18 +5845,34 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -5989,18 +5989,35 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
{
|
||||
BOOL src_allocated = FALSE, dest_allocated = FALSE, tempdir_created = FALSE;
|
||||
- int dest_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
@ -228,13 +228,14 @@ index 773223acd7c..9e4d00deb0e 100644
|
||||
+ dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ break;
|
||||
+ default:
|
||||
+ FIXME("stub: FSCTL_SET_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
if ((status = server_get_unix_fd( handle, FILE_SPECIAL_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
|
||||
return status;
|
||||
|
||||
@@ -5891,6 +5907,20 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6035,6 +6052,20 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
strcat( magic_dest, "." );
|
||||
strcat( magic_dest, "/" );
|
||||
}
|
||||
@ -255,14 +256,25 @@ index 773223acd7c..9e4d00deb0e 100644
|
||||
strcat( magic_dest, unix_dest );
|
||||
|
||||
/* Produce the link in a temporary location in the same folder */
|
||||
@@ -6254,6 +6284,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
switch(buffer->ReparseTag)
|
||||
{
|
||||
case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
status = FILE_CreateSymlink( handle, buffer );
|
||||
break;
|
||||
default:
|
||||
@@ -6399,17 +6430,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
case FSCTL_SET_REPARSE_POINT:
|
||||
{
|
||||
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)in_buffer;
|
||||
-
|
||||
- switch(buffer->ReparseTag)
|
||||
- {
|
||||
- case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
- status = create_reparse_point( handle, buffer );
|
||||
- break;
|
||||
- default:
|
||||
- FIXME("stub: FSCTL_SET_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- break;
|
||||
- }
|
||||
+ status = create_reparse_point( handle, buffer );
|
||||
break;
|
||||
}
|
||||
|
||||
diff --git a/include/ntifs.h b/include/ntifs.h
|
||||
index 4539b89d583..ab3273d3f81 100644
|
||||
--- a/include/ntifs.h
|
||||
@ -297,5 +309,5 @@ index 4539b89d583..ab3273d3f81 100644
|
||||
typedef struct _REPARSE_GUID_DATA_BUFFER {
|
||||
DWORD ReparseTag;
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
From 59ba8b3a0f29945da7e1f082b197ce398bf442f2 Mon Sep 17 00:00:00 2001
|
||||
From 5859da2b48592d1a13f471a6932a2529aa1e0395 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 13 Mar 2019 12:55:20 -0600
|
||||
Subject: [PATCH] ntdll: Add support for reading absolute symlinks.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 13 ++++++++++++-
|
||||
dlls/ntdll/unix/file.c | 22 ++++++++++++++++++++++
|
||||
2 files changed, 34 insertions(+), 1 deletion(-)
|
||||
dlls/ntdll/tests/file.c | 19 ++++++++++++++++++-
|
||||
dlls/ntdll/unix/file.c | 26 ++++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 53a24574eec..9a6f72cb783 100644
|
||||
index e0fa36ea64f..cfc0d176b53 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5393,7 +5393,6 @@ static void test_reparse_points(void)
|
||||
@@ -5480,7 +5480,6 @@ static void test_reparse_points(void)
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
buffer_len = build_reparse_buffer(nameW.Buffer, IO_REPARSE_TAG_SYMLINK, &buffer);
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
@ -21,7 +21,7 @@ index 53a24574eec..9a6f72cb783 100644
|
||||
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
|
||||
/* Check the file attributes of the symlink */
|
||||
@@ -5401,6 +5400,18 @@ static void test_reparse_points(void)
|
||||
@@ -5488,6 +5487,24 @@ static void test_reparse_points(void)
|
||||
ok(dwret != (DWORD)~0, "Symlink doesn't exist (attributes: 0x%x)!\n", dwret);
|
||||
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a symlink! (attributes: %d)\n", dwret);
|
||||
|
||||
@ -35,24 +35,30 @@ index 53a24574eec..9a6f72cb783 100644
|
||||
+ ok(bret, "Failed to read symlink!\n");
|
||||
+ ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
+ wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));
|
||||
+ path_len = buffer->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
|
||||
+ path_len += buffer->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len+1])
|
||||
+ - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
|
||||
+ buffer->ReparseDataLength, total_len);
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 11a7269c09e..19a2d0ae471 100644
|
||||
index da5136db68c..668f4fe2c80 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5988,6 +5988,7 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6138,6 +6138,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
int unix_dest_len;
|
||||
DWORD max_length;
|
||||
NTSTATUS status;
|
||||
+ ULONG flags = 0;
|
||||
WCHAR *nt_dest;
|
||||
INT prefix_len;
|
||||
ssize_t ret;
|
||||
@@ -6032,6 +6033,17 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
char *p;
|
||||
@@ -6181,6 +6182,17 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
}
|
||||
buffer->ReparseTag |= (val << i);
|
||||
}
|
||||
@ -70,23 +76,27 @@ index 11a7269c09e..19a2d0ae471 100644
|
||||
unix_dest_len -= (p - unix_dest);
|
||||
memmove(unix_dest, p, unix_dest_len);
|
||||
unix_dest[unix_dest_len] = 0;
|
||||
@@ -6065,6 +6077,16 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
buffer->MountPointReparseBuffer.PrintNameLength = nt_dest_len - prefix_len*sizeof(WCHAR);
|
||||
print_name = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
|
||||
@@ -6218,6 +6230,20 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
path_len += (nt_dest_len - prefix_len*sizeof(WCHAR)) + sizeof(WCHAR);
|
||||
total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len/sizeof(WCHAR)]);
|
||||
break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ max_length = out_size-FIELD_OFFSET(typeof(*buffer), SymbolicLinkReparseBuffer.PathBuffer[1]);
|
||||
+ buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
|
||||
+ path_len = 0;
|
||||
+ buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = path_len;
|
||||
+ buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = nt_dest_len;
|
||||
+ path_len += nt_dest_len + sizeof(WCHAR);
|
||||
+ subst_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
+ buffer->SymbolicLinkReparseBuffer.PrintNameOffset = nt_dest_len + sizeof(WCHAR);
|
||||
+ buffer->SymbolicLinkReparseBuffer.PrintNameOffset = path_len;
|
||||
+ buffer->SymbolicLinkReparseBuffer.PrintNameLength = nt_dest_len - prefix_len*sizeof(WCHAR);
|
||||
+ print_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
|
||||
+ path_len += (nt_dest_len - prefix_len*sizeof(WCHAR)) + sizeof(WCHAR);
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len/sizeof(WCHAR)]);
|
||||
+ buffer->SymbolicLinkReparseBuffer.Flags = flags;
|
||||
+ break;
|
||||
default:
|
||||
/* unrecognized (regular) files should probably be treated as symlinks */
|
||||
WARN("unrecognized symbolic link\n");
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From a563404dcdc796241cb83da788c5ac62dfe1fc17 Mon Sep 17 00:00:00 2001
|
||||
From 1cd53753c747d30cb1acee7f93264747a58c338b Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 13 Mar 2019 13:02:22 -0600
|
||||
Subject: [PATCH] ntdll: Add support for deleting symlinks.
|
||||
@ -10,13 +10,13 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 9a6f72cb783..dd21083ebbb 100644
|
||||
index cfc0d176b53..1fe5fea47d5 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5410,6 +5410,22 @@ static void test_reparse_points(void)
|
||||
ok(bret, "Failed to read symlink!\n");
|
||||
ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));
|
||||
@@ -5503,6 +5503,22 @@ static void test_reparse_points(void)
|
||||
- FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
|
||||
buffer->ReparseDataLength, total_len);
|
||||
+
|
||||
+ /* Delete the symlink */
|
||||
+ memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
@ -37,17 +37,17 @@ index 9a6f72cb783..dd21083ebbb 100644
|
||||
|
||||
cleanup:
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 19a2d0ae471..4e16db830d2 100644
|
||||
index 668f4fe2c80..bddf55faad8 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6280,6 +6280,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -6438,6 +6438,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
switch(buffer->ReparseTag)
|
||||
{
|
||||
case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
status = FILE_RemoveSymlink( handle, buffer );
|
||||
status = remove_reparse_point( handle, buffer );
|
||||
break;
|
||||
default:
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b5698ce1750769a0b57372be14bf4efb5f1c872c Mon Sep 17 00:00:00 2001
|
||||
From a56456fcccb14d889925b8f82c2f4c8506143b0a Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 11 Apr 2019 12:16:49 -0600
|
||||
Subject: [PATCH] ntdll: Add support for relative symlink creation.
|
||||
@ -11,10 +11,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
3 files changed, 111 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index dd21083ebbb..8ed749cfe33 100644
|
||||
index 1fe5fea47d5..367eef539ce 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5153,7 +5153,8 @@ static void test_mailslot_name(void)
|
||||
@@ -5234,7 +5234,8 @@ static void test_mailslot_name(void)
|
||||
CloseHandle( device );
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
{
|
||||
static INT header_size = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer);
|
||||
INT buffer_size, struct_size, data_size, string_len, prefix_len;
|
||||
@@ -5171,7 +5172,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, REPARSE_DATA_B
|
||||
@@ -5252,7 +5253,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, REPARSE_DATA_B
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -33,7 +33,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
string_len = lstrlenW(&filename[prefix_len]);
|
||||
data_size = (prefix_len + 2 * string_len + 2) * sizeof(WCHAR);
|
||||
buffer_size = struct_size + data_size;
|
||||
@@ -5191,6 +5192,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, REPARSE_DATA_B
|
||||
@@ -5272,6 +5273,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, REPARSE_DATA_B
|
||||
buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = (prefix_len + string_len) * sizeof(WCHAR);
|
||||
buffer->SymbolicLinkReparseBuffer.PrintNameOffset = (prefix_len + string_len + 1) * sizeof(WCHAR);
|
||||
buffer->SymbolicLinkReparseBuffer.PrintNameLength = string_len * sizeof(WCHAR);
|
||||
@ -41,7 +41,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
subst_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[0];
|
||||
print_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[prefix_len + string_len + 1];
|
||||
break;
|
||||
@@ -5273,7 +5275,7 @@ static void test_reparse_points(void)
|
||||
@@ -5354,7 +5356,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%x).\n", dwret);
|
||||
@ -50,7 +50,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
|
||||
@@ -5314,7 +5316,7 @@ static void test_reparse_points(void)
|
||||
@@ -5401,7 +5403,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);
|
||||
@ -59,7 +59,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5329,7 +5331,7 @@ static void test_reparse_points(void)
|
||||
@@ -5416,7 +5418,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);
|
||||
@ -68,7 +68,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -5391,7 +5393,7 @@ static void test_reparse_points(void)
|
||||
@@ -5478,7 +5480,7 @@ static void test_reparse_points(void)
|
||||
}
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
@ -77,7 +77,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
|
||||
@@ -5428,6 +5430,22 @@ static void test_reparse_points(void)
|
||||
@@ -5521,6 +5523,22 @@ static void test_reparse_points(void)
|
||||
"Symlink folder's access time does not match.\n");
|
||||
CloseHandle(handle);
|
||||
|
||||
@ -92,7 +92,7 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
+ }
|
||||
+ dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
+ ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
+ buffer_len = build_reparse_buffer(targetW, IO_REPARSE_TAG_SYMLINK, SYMLINK_FLAG_RELATIVE, &buffer);
|
||||
+ buffer_len = build_reparse_buffer(&targetW[1], IO_REPARSE_TAG_SYMLINK, SYMLINK_FLAG_RELATIVE, &buffer);
|
||||
+ bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
+ CloseHandle(handle);
|
||||
+ ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
@ -101,12 +101,12 @@ index dd21083ebbb..8ed749cfe33 100644
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 4e16db830d2..45aab990fb5 100644
|
||||
index bddf55faad8..d907d455fc9 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5844,17 +5844,20 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
@@ -5988,17 +5988,20 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
*/
|
||||
NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
{
|
||||
- BOOL src_allocated = FALSE, dest_allocated = FALSE, tempdir_created = FALSE;
|
||||
+ BOOL src_allocated = FALSE, path_allocated = FALSE, dest_allocated = FALSE;
|
||||
@ -127,7 +127,7 @@ index 4e16db830d2..45aab990fb5 100644
|
||||
int i;
|
||||
|
||||
switch(buffer->ReparseTag)
|
||||
@@ -5863,11 +5866,13 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6007,11 +6010,13 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
dest_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
|
||||
offset = buffer->MountPointReparseBuffer.SubstituteNameOffset;
|
||||
dest = &buffer->MountPointReparseBuffer.PathBuffer[offset];
|
||||
@ -140,8 +140,8 @@ index 4e16db830d2..45aab990fb5 100644
|
||||
+ flags = buffer->SymbolicLinkReparseBuffer.Flags;
|
||||
break;
|
||||
default:
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
@@ -5879,8 +5884,66 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
FIXME("stub: FSCTL_SET_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
@@ -6024,8 +6029,66 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
if ((status = server_get_unix_name( handle, &unix_src )))
|
||||
goto cleanup;
|
||||
src_allocated = TRUE;
|
||||
@ -210,7 +210,7 @@ index 4e16db830d2..45aab990fb5 100644
|
||||
for (;;)
|
||||
{
|
||||
unix_dest = malloc( unix_dest_len );
|
||||
@@ -5896,11 +5959,24 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6041,11 +6104,24 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
if (status != STATUS_SUCCESS && status != STATUS_NO_SUCH_FILE)
|
||||
goto cleanup;
|
||||
dest_allocated = TRUE;
|
||||
@ -237,7 +237,7 @@ index 4e16db830d2..45aab990fb5 100644
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
if ((buffer->ReparseTag >> i) & 1)
|
||||
@@ -5917,7 +5993,7 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6066,7 +6142,7 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
strcat( magic_dest, "." );
|
||||
strcat( magic_dest, "/" );
|
||||
}
|
||||
@ -246,7 +246,7 @@ index 4e16db830d2..45aab990fb5 100644
|
||||
|
||||
/* Produce the link in a temporary location in the same folder */
|
||||
strcpy( tmpdir, unix_src );
|
||||
@@ -5967,7 +6043,9 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6116,7 +6192,9 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
|
||||
cleanup:
|
||||
if (tempdir_created) rmdir( tmpdir );
|
||||
@ -268,5 +268,5 @@ index ab3273d3f81..0d02225bc4f 100644
|
||||
+
|
||||
#endif /* __WINE_NTIFS_H */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 26b27a370a0fac1344dc6f480648d6698a10876e Mon Sep 17 00:00:00 2001
|
||||
From de6ef008eced847e63429f1a09fe1e7573110093 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 11 Apr 2019 12:31:16 -0600
|
||||
Subject: [PATCH] ntdll: Add support for reading relative symlinks.
|
||||
@ -10,12 +10,12 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 47 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 8ed749cfe33..bdc1a151b45 100644
|
||||
index 367eef539ce..46aadeb7e7d 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5443,9 +5443,22 @@ static void test_reparse_points(void)
|
||||
@@ -5536,9 +5536,22 @@ static void test_reparse_points(void)
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
buffer_len = build_reparse_buffer(targetW, IO_REPARSE_TAG_SYMLINK, SYMLINK_FLAG_RELATIVE, &buffer);
|
||||
buffer_len = build_reparse_buffer(&targetW[1], IO_REPARSE_TAG_SYMLINK, SYMLINK_FLAG_RELATIVE, &buffer);
|
||||
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
- CloseHandle(handle);
|
||||
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
@ -27,21 +27,21 @@ index 8ed749cfe33..bdc1a151b45 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), "Symlink destination length does not match ('%d' != '%d')!\n",
|
||||
+ string_len, lstrlenW(targetW));
|
||||
+ ok(string_len != lstrlenW(&targetW[1]), "Symlink destination length does not match ('%d' != '%d')!\n",
|
||||
+ string_len, lstrlenW(&targetW[1]));
|
||||
+ dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
|
||||
+ ok((memcmp(dest, targetW, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
+ wine_dbgstr_w(dest), wine_dbgstr_w(targetW));
|
||||
+ 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]));
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 45aab990fb5..522cc38f2fc 100644
|
||||
index d907d455fc9..3a25b803d6f 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6089,6 +6089,11 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6238,6 +6238,11 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
|
||||
/* Decode the reparse tag from the symlink */
|
||||
p = unix_dest;
|
||||
@ -53,7 +53,7 @@ index 45aab990fb5..522cc38f2fc 100644
|
||||
if (*p++ != '/')
|
||||
{
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
@@ -6126,24 +6131,47 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6275,24 +6280,47 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
memmove(unix_dest, p, unix_dest_len);
|
||||
unix_dest[unix_dest_len] = 0;
|
||||
|
||||
@ -107,5 +107,5 @@ index 45aab990fb5..522cc38f2fc 100644
|
||||
{
|
||||
case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 4a1aecb1e9b29fbe0f8d2f4e7d7410af0bbc060e Mon Sep 17 00:00:00 2001
|
||||
From 9129b44e1ef8458064d773a5605d1ff182d67c54 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 11 Apr 2019 17:57:53 -0600
|
||||
Subject: [PATCH] ntdll: Add support for file symlinks.
|
||||
@ -10,10 +10,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 49 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index bdc1a151b45..8938c5bf50c 100644
|
||||
index 46aadeb7e7d..e5cfbb68793 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5376,6 +5376,35 @@ static void test_reparse_points(void)
|
||||
@@ -5463,6 +5463,35 @@ static void test_reparse_points(void)
|
||||
/* Delete the junction point directory and create a blank slate for symlink tests */
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
ok(bret, "Failed to delete junction point!\n");
|
||||
@ -50,10 +50,10 @@ index bdc1a151b45..8938c5bf50c 100644
|
||||
ok(bret, "Failed to create junction point directory.\n");
|
||||
dwret = GetFileAttributesW(reparse_path);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 0d064d98743..9b8458b413c 100644
|
||||
index 3a25b803d6f..ead0c48d62e 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5854,6 +5854,7 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -5998,6 +5998,7 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
int relative_offset = 0;
|
||||
UNICODE_STRING nt_dest;
|
||||
int dest_len, offset;
|
||||
@ -61,7 +61,7 @@ index 0d064d98743..9b8458b413c 100644
|
||||
NTSTATUS status;
|
||||
struct stat st;
|
||||
WCHAR *dest;
|
||||
@@ -5986,7 +5987,6 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6131,7 +6132,6 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
/* Encode the type (file or directory) if NT symlink */
|
||||
if (buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
|
||||
{
|
||||
@ -69,7 +69,7 @@ index 0d064d98743..9b8458b413c 100644
|
||||
if (fstat( dest_fd, &st ) == -1)
|
||||
{
|
||||
status = errno_to_status( errno );
|
||||
@@ -6020,8 +6020,11 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6165,8 +6165,11 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
/* Atomically move the link into position */
|
||||
if (!renameat2( -1, tmplink, -1, unix_src, RENAME_EXCHANGE ))
|
||||
{
|
||||
@ -83,7 +83,7 @@ index 0d064d98743..9b8458b413c 100644
|
||||
}
|
||||
else if (errno == ENOSYS)
|
||||
{
|
||||
@@ -6229,6 +6232,7 @@ NTSTATUS FILE_RemoveSymlink(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
@@ -6383,6 +6386,7 @@ NTSTATUS remove_reparse_point(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
char tmpdir[PATH_MAX], tmpfile[PATH_MAX], *d;
|
||||
BOOL tempdir_created = FALSE;
|
||||
int dest_fd, needs_close;
|
||||
@ -91,7 +91,7 @@ index 0d064d98743..9b8458b413c 100644
|
||||
NTSTATUS status;
|
||||
char *unix_name;
|
||||
struct stat st;
|
||||
@@ -6241,12 +6245,13 @@ NTSTATUS FILE_RemoveSymlink(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
@@ -6395,12 +6399,13 @@ NTSTATUS remove_reparse_point(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
|
||||
TRACE( "Deleting symlink %s\n", unix_name );
|
||||
|
||||
@ -106,7 +106,7 @@ index 0d064d98743..9b8458b413c 100644
|
||||
strcpy( tmpdir, unix_name );
|
||||
d = dirname( tmpdir);
|
||||
if (d != tmpdir) strcpy( tmpdir, d );
|
||||
@@ -6259,11 +6264,21 @@ NTSTATUS FILE_RemoveSymlink(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
@@ -6413,11 +6418,21 @@ NTSTATUS remove_reparse_point(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
tempdir_created = TRUE;
|
||||
strcpy( tmpfile, tmpdir );
|
||||
strcat( tmpfile, "/tmpfile" );
|
||||
@ -130,5 +130,5 @@ index 0d064d98743..9b8458b413c 100644
|
||||
lchown( tmpfile, st.st_uid, st.st_gid );
|
||||
/* Atomically move the directory into position */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From ba365806d06a93493f1f91d6ca8ab3676a513136 Mon Sep 17 00:00:00 2001
|
||||
From 5c409a2387a0df100f0fe163d48ab86b66fefa20 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Tue, 30 Apr 2019 16:24:54 -0600
|
||||
Subject: [PATCH] ntdll: Allow creation of dangling reparse points to
|
||||
@ -6,15 +6,15 @@ Subject: [PATCH] ntdll: Allow creation of dangling reparse points to
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 18 ++++++++++++++++--
|
||||
dlls/ntdll/unix/file.c | 19 +++++++++++++++++--
|
||||
include/winternl.h | 1 +
|
||||
2 files changed, 17 insertions(+), 2 deletions(-)
|
||||
2 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 0655371dc66..a9fcf6cc444 100644
|
||||
index ead0c48d62e..be57865f6b3 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3378,7 +3378,8 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
@@ -3388,7 +3388,8 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
/* if this is the last element, not finding it is not necessarily fatal */
|
||||
if (!name_len)
|
||||
{
|
||||
@ -24,11 +24,12 @@ index 0655371dc66..a9fcf6cc444 100644
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
if (disposition != FILE_OPEN && disposition != FILE_OVERWRITE)
|
||||
@@ -3398,6 +3399,19 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
@@ -3408,6 +3409,20 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
status = STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
}
|
||||
+ else if (disposition == FILE_WINE_PATH && status == STATUS_OBJECT_PATH_NOT_FOUND)
|
||||
+ else if (disposition == FILE_WINE_PATH && (status == STATUS_OBJECT_PATH_NOT_FOUND
|
||||
+ || status == STATUS_OBJECT_NAME_NOT_FOUND))
|
||||
+ {
|
||||
+ ret = ntdll_wcstoumbs( name, end - name, unix_name + pos + 1, MAX_DIR_ENTRY_LEN + 1, TRUE );
|
||||
+ if (ret > 0 && ret <= MAX_DIR_ENTRY_LEN)
|
||||
@ -44,7 +45,7 @@ index 0655371dc66..a9fcf6cc444 100644
|
||||
|
||||
if (status != STATUS_SUCCESS) break;
|
||||
|
||||
@@ -5953,7 +5967,7 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6098,7 +6113,7 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -54,10 +55,10 @@ index 0655371dc66..a9fcf6cc444 100644
|
||||
free( unix_dest );
|
||||
}
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index d35d509eb41..561a83bd648 100644
|
||||
index 8bfc7de67d0..2daee57e50f 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -2513,6 +2513,7 @@ typedef struct _RTL_ATOM_TABLE
|
||||
@@ -2678,6 +2678,7 @@ typedef struct _RTL_ATOM_TABLE
|
||||
#define FILE_OVERWRITE 4
|
||||
#define FILE_OVERWRITE_IF 5
|
||||
#define FILE_MAXIMUM_DISPOSITION 5
|
||||
@ -66,5 +67,5 @@ index d35d509eb41..561a83bd648 100644
|
||||
/* Characteristics of a File System */
|
||||
#define FILE_REMOVABLE_MEDIA 0x00000001
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,28 +1,28 @@
|
||||
From 30353100c8647bd85bdf53fe95ccc039ca3ee867 Mon Sep 17 00:00:00 2001
|
||||
From 99f1cef882a3f8098c76cf0918b99882533d1bbd Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 30 Mar 2019 12:00:51 -0600
|
||||
Subject: [PATCH] ntdll: Correctly report file symbolic links as files.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 115 +++++++++++++++++++++++++++--------------
|
||||
1 file changed, 77 insertions(+), 38 deletions(-)
|
||||
dlls/ntdll/unix/file.c | 116 +++++++++++++++++++++++++++--------------
|
||||
1 file changed, 78 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index a9fcf6cc444..5d41919267e 100644
|
||||
index be57865f6b3..94be474a0ff 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1612,6 +1612,9 @@ static inline int get_file_xattr( char *hexattr, int attrlen )
|
||||
@@ -1606,6 +1606,9 @@ static inline int get_file_xattr( char *hexattr, int attrlen )
|
||||
return 0;
|
||||
}
|
||||
|
||||
+NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
+NTSTATUS get_symlink_properties(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
+
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
{
|
||||
@@ -1696,10 +1699,15 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -1690,10 +1693,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 ))
|
||||
{
|
||||
@ -37,12 +37,12 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
+ /* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
+ *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
+ /* whether a reparse point is a file or a directory is stored inside the link target */
|
||||
+ if (FILE_DecodeSymlink( path, NULL, NULL, NULL, NULL, &is_dir ) == STATUS_SUCCESS)
|
||||
+ if (get_symlink_properties( path, NULL, NULL, NULL, NULL, &is_dir ) == STATUS_SUCCESS)
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
}
|
||||
else if (S_ISDIR( st->st_mode ) && (parent_path = malloc( strlen(path) + 4 )))
|
||||
{
|
||||
@@ -6070,46 +6078,35 @@ cleanup:
|
||||
@@ -6219,46 +6227,35 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -50,11 +50,12 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
- * Retrieve the unix name corresponding to a file handle and use that to find the destination of the
|
||||
- * symlink corresponding to that file handle.
|
||||
- */
|
||||
-NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
-NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+NTSTATUS get_symlink_properties(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
{
|
||||
- char *unix_src, unix_dest[PATH_MAX];
|
||||
- INT prefix_len, path_len, total_len;
|
||||
- VOID *subst_name, *print_name;
|
||||
- SIZE_T nt_dest_len = PATH_MAX;
|
||||
- BOOL dest_allocated = FALSE;
|
||||
@ -66,7 +67,6 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
NTSTATUS status;
|
||||
- ULONG flags = 0;
|
||||
- WCHAR *nt_dest;
|
||||
- INT prefix_len;
|
||||
+ BOOL dir_flag;
|
||||
+ char *p, *tmp;
|
||||
ssize_t ret;
|
||||
@ -105,7 +105,7 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
p++;
|
||||
}
|
||||
if (*p++ != '/')
|
||||
@@ -6117,7 +6114,7 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6266,7 +6263,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -114,7 +114,7 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
char c = *p++;
|
||||
@@ -6132,22 +6129,64 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6281,22 +6278,65 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -160,8 +160,9 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
+ * Retrieve the unix name corresponding to a file handle and use that to find the destination of the
|
||||
+ * symlink corresponding to that file handle.
|
||||
+ */
|
||||
+NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
+{
|
||||
+ INT prefix_len, path_len, total_len;
|
||||
+ char *unix_src, unix_dest[PATH_MAX];
|
||||
+ VOID *subst_name, *print_name;
|
||||
+ SIZE_T nt_dest_len = PATH_MAX;
|
||||
@ -172,7 +173,6 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
+ NTSTATUS status;
|
||||
+ ULONG flags = 0;
|
||||
+ WCHAR *nt_dest;
|
||||
+ INT prefix_len;
|
||||
+
|
||||
+ if ((status = server_get_unix_fd( handle, FILE_ANY_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
|
||||
+ return status;
|
||||
@ -180,11 +180,12 @@ index a9fcf6cc444..5d41919267e 100644
|
||||
+ if ((status = server_get_unix_name( handle, &unix_src )))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if ((status = FILE_DecodeSymlink( unix_src, unix_dest, &unix_dest_len, &buffer->ReparseTag, &flags, NULL )))
|
||||
+ if ((status = get_symlink_properties( unix_src, unix_dest, &unix_dest_len, &buffer->ReparseTag,
|
||||
+ &flags, NULL )))
|
||||
+ goto cleanup;
|
||||
|
||||
/* convert the relative path into an absolute path */
|
||||
if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 17a86aec0579d7632eaa718800d51cdda191a4b4 Mon Sep 17 00:00:00 2001
|
||||
From 29337136ad7b6bdacd2910622ef3685ebacfe8fa Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sun, 22 Nov 2020 22:35:50 -0700
|
||||
Subject: [PATCH] kernelbase: Convert FILE_FLAG_OPEN_REPARSE_POINT for passing
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] kernelbase: Convert FILE_FLAG_OPEN_REPARSE_POINT for passing
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index abfdade04ed..ad3c002d8c6 100644
|
||||
index e0a75c2ad08..7eabf5aa211 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -723,6 +723,8 @@ static UINT get_nt_file_options( DWORD attributes )
|
||||
@@ -725,6 +725,8 @@ static UINT get_nt_file_options( DWORD attributes )
|
||||
options |= FILE_RANDOM_ACCESS;
|
||||
if (attributes & FILE_FLAG_WRITE_THROUGH)
|
||||
options |= FILE_WRITE_THROUGH;
|
||||
@ -22,5 +22,5 @@ index abfdade04ed..ad3c002d8c6 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,18 +1,26 @@
|
||||
From 663544d9d76dcd9d9338528a41a4e58343a8fc75 Mon Sep 17 00:00:00 2001
|
||||
From 05c1471fc29add8269c805692def9107de436bfa Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 12 Dec 2020 16:54:28 -0700
|
||||
Subject: [PATCH] server: Implement FILE_OPEN_REPARSE_POINT option.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 8 ++++----
|
||||
server/fd.c | 18 +++++++++++++++++-
|
||||
2 files changed, 21 insertions(+), 5 deletions(-)
|
||||
dlls/ntdll/tests/file.c | 27 +++++++++++++++++++++++----
|
||||
server/fd.c | 39 ++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 55 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 8938c5bf50c..59f10ea8cce 100644
|
||||
index e5cfbb68793..f3eecbbc708 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5299,7 +5299,7 @@ static void test_reparse_points(void)
|
||||
@@ -5299,6 +5299,7 @@ static void test_reparse_points(void)
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
+ WCHAR buf[] = {0,0,0,0};
|
||||
HANDLE handle, token;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
@@ -5386,7 +5387,7 @@ static void test_reparse_points(void)
|
||||
memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
old_attrib.LastAccessTime.QuadPart = 0x200deadcafebeef;
|
||||
dwret = NtSetInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
@ -21,7 +29,7 @@ index 8938c5bf50c..59f10ea8cce 100644
|
||||
memset(&guid_buffer, 0x00, sizeof(guid_buffer));
|
||||
guid_buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
bret = DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, (LPVOID)&guid_buffer,
|
||||
@@ -5308,7 +5308,7 @@ static void test_reparse_points(void)
|
||||
@@ -5395,7 +5396,7 @@ static void test_reparse_points(void)
|
||||
memset(&new_attrib, 0x00, sizeof(new_attrib));
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &new_attrib, sizeof(new_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%x).\n", dwret);
|
||||
@ -30,7 +38,32 @@ index 8938c5bf50c..59f10ea8cce 100644
|
||||
"Junction point folder's access time does not match.\n");
|
||||
CloseHandle(handle);
|
||||
|
||||
@@ -5446,7 +5446,7 @@ static void test_reparse_points(void)
|
||||
@@ -5476,6 +5477,24 @@ static void test_reparse_points(void)
|
||||
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
|
||||
+ /* Check the size/data of the symlink target when opened with FILE_FLAG_OPEN_REPARSE_POINT */
|
||||
+ handle = CreateFileW(target_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
+ if (handle == INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ win_skip("Failed to open symlink file handle (0x%x).\n", GetLastError());
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ ok(GetFileSize(handle, NULL) == sizeof(fooW), "symlink target size does not match (%d != %d)\n",
|
||||
+ GetFileSize(handle, NULL), sizeof(fooW));
|
||||
+ bret = ReadFile(handle, &buf, sizeof(buf), &dwLen, NULL);
|
||||
+ ok(bret, "Failed to read data from the symlink target.\n");
|
||||
+ ok(dwLen == sizeof(fooW), "Length of symlink target data does not match (%d != %d).\n",
|
||||
+ dwLen, sizeof(fooW));
|
||||
+ ok(!memcmp(fooW, &buf, sizeof(fooW)), "Symlink target data does not match (%s != %s).\n",
|
||||
+ wine_dbgstr_wn(buf, dwLen), wine_dbgstr_w(fooW));
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
/* Check deleting a file symlink as if it were a directory */
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
todo_wine ok(!bret, "Succeeded in deleting file symlink as a directory!\n");
|
||||
@@ -5539,7 +5558,7 @@ static void test_reparse_points(void)
|
||||
memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
old_attrib.LastAccessTime.QuadPart = 0x200deadcafebeef;
|
||||
dwret = NtSetInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
@ -39,7 +72,7 @@ index 8938c5bf50c..59f10ea8cce 100644
|
||||
memset(&guid_buffer, 0x00, sizeof(guid_buffer));
|
||||
guid_buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK;
|
||||
bret = DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, (LPVOID)&guid_buffer,
|
||||
@@ -5455,7 +5455,7 @@ static void test_reparse_points(void)
|
||||
@@ -5548,7 +5567,7 @@ static void test_reparse_points(void)
|
||||
memset(&new_attrib, 0x00, sizeof(new_attrib));
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &new_attrib, sizeof(new_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
@ -49,7 +82,7 @@ index 8938c5bf50c..59f10ea8cce 100644
|
||||
CloseHandle(handle);
|
||||
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 4f43f41fb31..a01d4c9c0f7 100644
|
||||
index 2605adf96ff..4fe7e6de53f 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -107,6 +107,10 @@
|
||||
@ -63,19 +96,54 @@ index 4f43f41fb31..a01d4c9c0f7 100644
|
||||
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL_CREATE)
|
||||
# include <sys/epoll.h>
|
||||
# define USE_EPOLL
|
||||
@@ -1958,6 +1962,11 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
@@ -1898,6 +1902,14 @@ void get_nt_name( struct fd *fd, struct unicode_str *name )
|
||||
name->len = fd->nt_namelen;
|
||||
}
|
||||
|
||||
+int check_symlink( char *name )
|
||||
+{
|
||||
+ struct stat st;
|
||||
+
|
||||
+ lstat( name, &st );
|
||||
+ return S_ISLNK( st.st_mode );
|
||||
+}
|
||||
+
|
||||
/* open() wrapper that returns a struct fd with no fd user set */
|
||||
struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name,
|
||||
int flags, mode_t *mode, unsigned int access,
|
||||
@@ -1958,6 +1970,18 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
}
|
||||
else rw_mode = O_RDONLY;
|
||||
|
||||
+ fd->unix_name = NULL;
|
||||
+ if ((path = dup_fd_name( root, name )))
|
||||
+ {
|
||||
+ int is_symlink = check_symlink( path );
|
||||
+#if defined(O_SYMLINK)
|
||||
+ if ((options & FILE_OPEN_REPARSE_POINT) && !(flags & O_CREAT))
|
||||
+ flags |= O_SYMLINK;
|
||||
+ if (is_symlink && (options & FILE_OPEN_REPARSE_POINT) && !(flags & O_CREAT))
|
||||
+ flags |= O_SYMLINK;
|
||||
+#endif
|
||||
+ fd->unlink_name = path;
|
||||
+ fd->unix_name = realpath( path, NULL );
|
||||
+ }
|
||||
+
|
||||
if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
|
||||
{
|
||||
/* if we tried to open a directory for write access, retry read-only */
|
||||
@@ -2431,6 +2440,7 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
|
||||
@@ -1975,12 +1999,6 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
}
|
||||
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
- fd->unix_name = NULL;
|
||||
- if ((path = dup_fd_name( root, name )))
|
||||
- {
|
||||
- fd->unlink_name = path;
|
||||
- fd->unix_name = realpath( path, NULL );
|
||||
- }
|
||||
|
||||
closed_fd->unix_fd = fd->unix_fd;
|
||||
closed_fd->unlink = 0;
|
||||
@@ -2425,6 +2443,7 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
|
||||
|
||||
static int is_dir_empty( int fd )
|
||||
{
|
||||
@ -83,7 +151,7 @@ index 4f43f41fb31..a01d4c9c0f7 100644
|
||||
DIR *dir;
|
||||
int empty;
|
||||
struct dirent *de;
|
||||
@@ -2438,8 +2448,13 @@ static int is_dir_empty( int fd )
|
||||
@@ -2432,8 +2451,13 @@ static int is_dir_empty( int fd )
|
||||
if ((fd = dup( fd )) == -1)
|
||||
return -1;
|
||||
|
||||
@ -98,7 +166,7 @@ index 4f43f41fb31..a01d4c9c0f7 100644
|
||||
close( fd );
|
||||
return -1;
|
||||
}
|
||||
@@ -2451,6 +2466,7 @@ static int is_dir_empty( int fd )
|
||||
@@ -2445,6 +2469,7 @@ static int is_dir_empty( int fd )
|
||||
empty = 0;
|
||||
}
|
||||
closedir( dir );
|
||||
@ -107,5 +175,5 @@ index 4f43f41fb31..a01d4c9c0f7 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 9303f780842e09a09c2e7d0a763cdd93f4289b8a Mon Sep 17 00:00:00 2001
|
||||
From 2b954893dcd3d0088f214c6a12846a3cf1149e24 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sun, 22 Nov 2020 22:37:33 -0700
|
||||
Subject: [PATCH] ntdll: Allow set_file_times_precise to work on reparse
|
||||
@ -11,10 +11,10 @@ Subject: [PATCH] ntdll: Allow set_file_times_precise to work on reparse
|
||||
3 files changed, 24 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 11f57d13274..eea5847c51f 100644
|
||||
index 7553b22e76d..7ed08b6336d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2226,7 +2226,8 @@ AC_CHECK_FUNCS(\
|
||||
@@ -2227,7 +2227,8 @@ AC_CHECK_FUNCS(\
|
||||
sigprocmask \
|
||||
symlink \
|
||||
tcdrain \
|
||||
@ -25,10 +25,10 @@ index 11f57d13274..eea5847c51f 100644
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 59f10ea8cce..8938c5bf50c 100644
|
||||
index f3eecbbc708..17ed907d628 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5299,7 +5299,7 @@ static void test_reparse_points(void)
|
||||
@@ -5387,7 +5387,7 @@ static void test_reparse_points(void)
|
||||
memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
old_attrib.LastAccessTime.QuadPart = 0x200deadcafebeef;
|
||||
dwret = NtSetInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
@ -37,7 +37,7 @@ index 59f10ea8cce..8938c5bf50c 100644
|
||||
memset(&guid_buffer, 0x00, sizeof(guid_buffer));
|
||||
guid_buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
bret = DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, (LPVOID)&guid_buffer,
|
||||
@@ -5308,7 +5308,7 @@ static void test_reparse_points(void)
|
||||
@@ -5396,7 +5396,7 @@ static void test_reparse_points(void)
|
||||
memset(&new_attrib, 0x00, sizeof(new_attrib));
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &new_attrib, sizeof(new_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%x).\n", dwret);
|
||||
@ -46,7 +46,7 @@ index 59f10ea8cce..8938c5bf50c 100644
|
||||
"Junction point folder's access time does not match.\n");
|
||||
CloseHandle(handle);
|
||||
|
||||
@@ -5446,7 +5446,7 @@ static void test_reparse_points(void)
|
||||
@@ -5558,7 +5558,7 @@ static void test_reparse_points(void)
|
||||
memset(&old_attrib, 0x00, sizeof(old_attrib));
|
||||
old_attrib.LastAccessTime.QuadPart = 0x200deadcafebeef;
|
||||
dwret = NtSetInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
@ -55,7 +55,7 @@ index 59f10ea8cce..8938c5bf50c 100644
|
||||
memset(&guid_buffer, 0x00, sizeof(guid_buffer));
|
||||
guid_buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK;
|
||||
bret = DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, (LPVOID)&guid_buffer,
|
||||
@@ -5455,7 +5455,7 @@ static void test_reparse_points(void)
|
||||
@@ -5567,7 +5567,7 @@ static void test_reparse_points(void)
|
||||
memset(&new_attrib, 0x00, sizeof(new_attrib));
|
||||
dwret = NtQueryInformationFile(handle, &iosb, &new_attrib, sizeof(new_attrib), FileBasicInformation);
|
||||
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
@ -65,10 +65,10 @@ index 59f10ea8cce..8938c5bf50c 100644
|
||||
CloseHandle(handle);
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 5d41919267e..4fb5afc2755 100644
|
||||
index 94be474a0ff..319f42e9e0c 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1737,6 +1737,14 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -1731,6 +1731,14 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ index 5d41919267e..4fb5afc2755 100644
|
||||
#if defined(__ANDROID__) && !defined(HAVE_FUTIMENS)
|
||||
static int futimens( int fd, const struct timespec spec[2] )
|
||||
{
|
||||
@@ -1752,7 +1760,7 @@ static int futimens( int fd, const struct timespec spec[2] )
|
||||
@@ -1746,7 +1754,7 @@ static int futimens( int fd, const struct timespec spec[2] )
|
||||
static BOOL set_file_times_precise( int fd, const LARGE_INTEGER *mtime,
|
||||
const LARGE_INTEGER *atime, NTSTATUS *status )
|
||||
{
|
||||
@ -92,26 +92,26 @@ index 5d41919267e..4fb5afc2755 100644
|
||||
struct timespec tv[2];
|
||||
|
||||
tv[0].tv_sec = tv[1].tv_sec = 0;
|
||||
@@ -1768,10 +1776,16 @@ static BOOL set_file_times_precise( int fd, const LARGE_INTEGER *mtime,
|
||||
@@ -1762,10 +1770,16 @@ static BOOL set_file_times_precise( int fd, const LARGE_INTEGER *mtime,
|
||||
tv[1].tv_nsec = (mtime->QuadPart % 10000000) * 100;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
- if (!&futimens) return FALSE;
|
||||
+ if (!&utimensat || !&futimens) return FALSE;
|
||||
+#endif
|
||||
#endif
|
||||
- if (futimens( fd, tv ) == -1) *status = errno_to_status( errno );
|
||||
- else *status = STATUS_SUCCESS;
|
||||
+#if defined(HAVE_UTIMENSAT)
|
||||
+ /* futimens does not work on O_PATH|O_NOFOLLOW (O_SYMLINK) file descriptors, so if fd is for a
|
||||
+ * symlink then use utimensat with an empty path (.) and do not follow the link. */
|
||||
+ if (utimensat(fd, ".", tv, AT_SYMLINK_NOFOLLOW) == 0) *status = STATUS_SUCCESS;
|
||||
+ else
|
||||
#endif
|
||||
- if (futimens( fd, tv ) == -1) *status = errno_to_status( errno );
|
||||
- else *status = STATUS_SUCCESS;
|
||||
+#endif
|
||||
+ if (futimens(fd, tv) == 0) *status = STATUS_SUCCESS;
|
||||
+ else *status = errno_to_status( errno );
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b17dd0d9dbfe6aff1654c1b8fe49019d5f97d139 Mon Sep 17 00:00:00 2001
|
||||
From 4ee6ccb3ca1639d81bd9e8ce572131905e6a8df1 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 30 Mar 2019 13:41:07 -0600
|
||||
Subject: [PATCH] server: Properly handle file symlink deletion.
|
||||
@ -10,10 +10,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
2 files changed, 62 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 8938c5bf50c..c5c186748b6 100644
|
||||
index 17ed907d628..a4648dd65e0 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5391,18 +5391,18 @@ static void test_reparse_points(void)
|
||||
@@ -5497,18 +5497,18 @@ static void test_reparse_points(void)
|
||||
|
||||
/* Check deleting a file symlink as if it were a directory */
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
@ -39,11 +39,11 @@ index 8938c5bf50c..c5c186748b6 100644
|
||||
/* Create a blank slate for directory symlink tests */
|
||||
bret = CreateDirectoryW(reparse_path, NULL);
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index a01d4c9c0f7..c4de093b40b 100644
|
||||
index 4fe7e6de53f..fcffe4a4afd 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -1902,6 +1902,55 @@ void get_nt_name( struct fd *fd, struct unicode_str *name )
|
||||
name->len = fd->nt_namelen;
|
||||
@@ -1910,6 +1910,55 @@ int check_symlink( char *name )
|
||||
return S_ISLNK( st.st_mode );
|
||||
}
|
||||
|
||||
+static void decode_symlink(char *name, int *is_dir)
|
||||
@ -98,7 +98,7 @@ index a01d4c9c0f7..c4de093b40b 100644
|
||||
/* open() wrapper that returns a struct fd with no fd user set */
|
||||
struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name,
|
||||
int flags, mode_t *mode, unsigned int access,
|
||||
@@ -2003,6 +2052,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
@@ -2012,6 +2061,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
{
|
||||
unsigned int err;
|
||||
struct inode *inode = get_inode( st.st_dev, st.st_ino, fd->unix_fd );
|
||||
@ -106,7 +106,7 @@ index a01d4c9c0f7..c4de093b40b 100644
|
||||
|
||||
if (!inode)
|
||||
{
|
||||
@@ -2017,16 +2067,20 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
@@ -2026,16 +2076,20 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
list_add_head( &inode->open, &fd->inode_entry );
|
||||
closed_fd = NULL;
|
||||
|
||||
@ -130,5 +130,5 @@ index a01d4c9c0f7..c4de093b40b 100644
|
||||
set_error( STATUS_FILE_IS_A_DIRECTORY );
|
||||
goto error;
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 879b893a5429ba4aa0ced3fdefd284dcca0b0a7d Mon Sep 17 00:00:00 2001
|
||||
From 4f38f2552b1d31e427ea0c45f2146485a4ade4ee Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 12 Dec 2020 17:40:27 -0700
|
||||
Subject: [PATCH] server: Properly handle deleting dangling symlinks.
|
||||
@ -8,18 +8,18 @@ Subject: [PATCH] server: Properly handle deleting dangling symlinks.
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index c4de093b40b..da5bee3e5ec 100644
|
||||
index fcffe4a4afd..4ef3c673268 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2038,6 +2038,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
{
|
||||
@@ -2029,6 +2029,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
#endif
|
||||
fd->unlink_name = path;
|
||||
fd->unix_name = realpath( path, NULL );
|
||||
+ if (!fd->unix_name) fd->unix_name = dup_fd_name( root, name ); /* dangling symlink */
|
||||
}
|
||||
|
||||
closed_fd->unix_fd = fd->unix_fd;
|
||||
@@ -2548,7 +2549,7 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
|
||||
@@ -2551,7 +2552,7 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
file_set_error();
|
||||
return;
|
||||
}
|
||||
@ -29,5 +29,5 @@ index c4de093b40b..da5bee3e5ec 100644
|
||||
if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
{
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b5c33b762b57ac73bc374e8aea6199730524ea59 Mon Sep 17 00:00:00 2001
|
||||
From 948fd2c1ec52cb7921d23b3fbaaf355075928611 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: Use FILE_OPEN_REPARSE_POINT in
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] kernelbase: Use FILE_OPEN_REPARSE_POINT in
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index ad3c002d8c6..375c00c7367 100644
|
||||
index 7eabf5aa211..80497c1ac97 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -3482,7 +3482,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryW( LPCWSTR path )
|
||||
@@ -3484,7 +3484,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryW( LPCWSTR path )
|
||||
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
|
||||
status = NtOpenFile( &handle, DELETE | SYNCHRONIZE, &attr, &io,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
@ -22,5 +22,5 @@ index ad3c002d8c6..375c00c7367 100644
|
||||
|
||||
if (!status)
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,29 +1,27 @@
|
||||
From 4bbc98949eb154de067f68188bb2c2702782c48c Mon Sep 17 00:00:00 2001
|
||||
From de51b2d861f5cd8c9cca5b0a6b30be6ef8f94d7a 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.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 46 +++++++++++++++++++++++++++++++++++++++--
|
||||
dlls/ntdll/tests/file.c | 45 +++++++++++++++++++++++++++++++++++++++--
|
||||
dlls/ntdll/unix/file.c | 2 ++
|
||||
2 files changed, 46 insertions(+), 2 deletions(-)
|
||||
2 files changed, 45 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index c5c186748b6..fb168549641 100644
|
||||
index a4648dd65e0..6e5082980bf 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5217,7 +5217,9 @@ static void test_reparse_points(void)
|
||||
@@ -5299,6 +5299,7 @@ static void test_reparse_points(void)
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
+ WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
INT buffer_len, string_len;
|
||||
+ WCHAR buf[] = {0,0,0,0};
|
||||
WCHAR buf[] = {0,0,0,0};
|
||||
HANDLE handle, token;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
@@ -5350,8 +5352,6 @@ static void test_reparse_points(void)
|
||||
@@ -5438,8 +5439,6 @@ static void test_reparse_points(void)
|
||||
"Unexpected junction point attributes (0x%x != 0x410)!\n", dwret);
|
||||
bret = RemoveDirectoryW(target_path);
|
||||
ok(bret, "Failed to delete junction point target!\n");
|
||||
@ -32,7 +30,7 @@ index c5c186748b6..fb168549641 100644
|
||||
|
||||
/* Establish permissions for symlink creation */
|
||||
bret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token);
|
||||
@@ -5376,6 +5376,13 @@ static void test_reparse_points(void)
|
||||
@@ -5464,6 +5463,13 @@ static void test_reparse_points(void)
|
||||
/* Delete the junction point directory and create a blank slate for symlink tests */
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
ok(bret, "Failed to delete junction point!\n");
|
||||
@ -46,7 +44,7 @@ index c5c186748b6..fb168549641 100644
|
||||
|
||||
/* Create the file symlink */
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
@@ -5389,6 +5396,37 @@ static void test_reparse_points(void)
|
||||
@@ -5477,6 +5483,37 @@ static void test_reparse_points(void)
|
||||
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
CloseHandle(handle);
|
||||
|
||||
@ -81,10 +79,10 @@ index c5c186748b6..fb168549641 100644
|
||||
+ wine_dbgstr_wn(buf, dwLen), wine_dbgstr_w(fooW));
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
/* Check deleting a file symlink as if it were a directory */
|
||||
bret = RemoveDirectoryW(reparse_path);
|
||||
ok(!bret, "Succeeded in deleting file symlink as a directory!\n");
|
||||
@@ -5410,6 +5448,10 @@ static void test_reparse_points(void)
|
||||
/* Check the size/data of the symlink target when opened with FILE_FLAG_OPEN_REPARSE_POINT */
|
||||
handle = CreateFileW(target_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
@@ -5516,6 +5553,10 @@ static void test_reparse_points(void)
|
||||
dwret = GetFileAttributesW(reparse_path);
|
||||
ok(dwret != (DWORD)~0, "Path doesn't exist (attributes: 0x%x)!\n", dwret);
|
||||
ok(!(dwret & FILE_ATTRIBUTE_REPARSE_POINT), "File is already a reparse point! (attributes: %d)\n", dwret);
|
||||
@ -96,10 +94,10 @@ index c5c186748b6..fb168549641 100644
|
||||
/* Create the directory symlink */
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 4fb5afc2755..f77e64ee6b4 100644
|
||||
index 319f42e9e0c..2561afd6d53 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1703,6 +1703,8 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -1697,6 +1697,8 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
|
||||
/* return information about the destination (unless this is a dangling symlink) */
|
||||
stat( path, st );
|
||||
@ -109,5 +107,5 @@ index 4fb5afc2755..f77e64ee6b4 100644
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
/* whether a reparse point is a file or a directory is stored inside the link target */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 42675b2cbb3460a5c9fe57f6804d1f144fe27529 Mon Sep 17 00:00:00 2001
|
||||
From 60436fb0d205508589a76cda2476013b90f5b601 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.
|
||||
@ -12,7 +12,7 @@ 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 9654f31cf30..f5e968c369e 100644
|
||||
index 2561afd6d53..e1b3b2692ee 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -2709,7 +2709,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 06e0409820f530dfe425693cba954d7defbfa722 Mon Sep 17 00:00:00 2001
|
||||
From 3bbfa5b27b5d1f5f0cbac1d3551b7da5731685c4 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 18 Jul 2020 09:13:29 -0600
|
||||
Subject: [PATCH] server: Fix obtaining information about a symlink.
|
||||
@ -11,10 +11,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
3 files changed, 15 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 0de80ebee7b..b52f0074175 100644
|
||||
index e1b3b2692ee..996e8d029d0 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1995,7 +1995,7 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
|
||||
@@ -1989,7 +1989,7 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
{
|
||||
data_size_t size = 1024;
|
||||
NTSTATUS ret;
|
||||
@@ -2008,6 +2008,7 @@ static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name )
|
||||
@@ -2002,6 +2002,7 @@ static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name )
|
||||
SERVER_START_REQ( get_handle_unix_name )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
@ -31,7 +31,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
wine_server_set_reply( req, name, size );
|
||||
ret = wine_server_call( req );
|
||||
size = reply->name_len;
|
||||
@@ -2182,7 +2183,7 @@ static NTSTATUS get_mountmgr_fs_info( HANDLE handle, int fd, struct mountmgr_uni
|
||||
@@ -2176,7 +2177,7 @@ static NTSTATUS get_mountmgr_fs_info( HANDLE handle, int fd, struct mountmgr_uni
|
||||
NTSTATUS status;
|
||||
int letter;
|
||||
|
||||
@ -40,7 +40,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
letter = find_dos_device( unix_name );
|
||||
free( unix_name );
|
||||
|
||||
@@ -4245,7 +4246,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4396,7 +4397,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno );
|
||||
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
@ -49,7 +49,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
{
|
||||
LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
|
||||
|
||||
@@ -4306,7 +4307,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4457,7 +4458,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
FILE_NAME_INFORMATION *info = ptr;
|
||||
char *unix_name;
|
||||
|
||||
@ -58,7 +58,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
{
|
||||
LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
|
||||
io->u.Status = fill_name_info( unix_name, info, &name_len );
|
||||
@@ -4320,7 +4321,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4471,7 +4472,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
FILE_NETWORK_OPEN_INFORMATION *info = ptr;
|
||||
char *unix_name;
|
||||
|
||||
@ -67,7 +67,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
{
|
||||
ULONG attributes;
|
||||
struct stat st;
|
||||
@@ -5920,7 +5921,7 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6066,7 +6067,7 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
if ((status = server_get_unix_fd( handle, FILE_SPECIAL_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
|
||||
return status;
|
||||
|
||||
@ -76,7 +76,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
goto cleanup;
|
||||
src_allocated = TRUE;
|
||||
if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
@@ -6198,7 +6199,7 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -6347,7 +6348,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
if ((status = server_get_unix_fd( handle, FILE_ANY_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
|
||||
return status;
|
||||
|
||||
@ -84,8 +84,8 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
+ if ((status = server_get_unix_name( handle, &unix_src, TRUE )))
|
||||
goto cleanup;
|
||||
|
||||
if ((status = FILE_DecodeSymlink( unix_src, unix_dest, &unix_dest_len, &buffer->ReparseTag, &flags, NULL )))
|
||||
@@ -6306,7 +6307,7 @@ NTSTATUS FILE_RemoveSymlink(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
if ((status = get_symlink_properties( unix_src, unix_dest, &unix_dest_len, &buffer->ReparseTag,
|
||||
@@ -6465,7 +6466,7 @@ NTSTATUS remove_reparse_point(HANDLE handle, REPARSE_GUID_DATA_BUFFER *buffer)
|
||||
if ((status = server_get_unix_fd( handle, FILE_SPECIAL_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
|
||||
return status;
|
||||
|
||||
@ -94,7 +94,7 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
goto cleanup;
|
||||
|
||||
TRACE( "Deleting symlink %s\n", unix_name );
|
||||
@@ -7411,7 +7412,7 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
|
||||
@@ -7559,7 +7560,7 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
|
||||
|
||||
/* first try as a file object */
|
||||
|
||||
@ -104,10 +104,10 @@ index 0de80ebee7b..b52f0074175 100644
|
||||
if (!(status = unix_to_nt_file_name( unix_name, &nt_name )))
|
||||
{
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index da5bee3e5ec..9a06492c3bb 100644
|
||||
index 4ef3c673268..dfab2e71f27 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2795,11 +2795,12 @@ DECL_HANDLER(get_handle_unix_name)
|
||||
@@ -2798,11 +2798,12 @@ DECL_HANDLER(get_handle_unix_name)
|
||||
|
||||
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
|
||||
{
|
||||
@ -124,10 +124,10 @@ index da5bee3e5ec..9a06492c3bb 100644
|
||||
}
|
||||
else set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 7f3b785df51..f37e03cbaea 100644
|
||||
index abfd6d70240..af6424590dc 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -1341,6 +1341,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
|
||||
@@ -1334,6 +1334,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
|
||||
/* Get the Unix name from a file handle */
|
||||
@REQ(get_handle_unix_name)
|
||||
obj_handle_t handle; /* file handle */
|
||||
@ -136,5 +136,5 @@ index 7f3b785df51..f37e03cbaea 100644
|
||||
data_size_t name_len; /* unix name length */
|
||||
VARARG(name,string); /* unix name */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b68b7725bf2bf7524bcd52c560b5fa61c98a8316 Mon Sep 17 00:00:00 2001
|
||||
From 231cc5f69845313256722c5e9736acad5ccef279 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.
|
||||
@ -11,10 +11,10 @@ Subject: [PATCH] ntdll: Succeed with no data for NtReadFile on reparse points.
|
||||
4 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index fb168549641..05f6f67c4d3 100644
|
||||
index 6e5082980bf..c94a112b23b 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5405,7 +5405,7 @@ static void test_reparse_points(void)
|
||||
@@ -5492,7 +5492,7 @@ static void test_reparse_points(void)
|
||||
ok(handle != INVALID_HANDLE_VALUE, "Failed to open symlink file.\n");
|
||||
todo_wine ok(GetFileSize(handle, NULL) == 0, "symlink size is not zero\n");
|
||||
bret = ReadFile(handle, &buf, sizeof(buf), &dwLen, NULL);
|
||||
@ -24,10 +24,10 @@ index fb168549641..05f6f67c4d3 100644
|
||||
CloseHandle(handle);
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index b52f0074175..06a010f02ce 100644
|
||||
index 996e8d029d0..8a4dfe9a34b 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5291,6 +5291,11 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
|
||||
@@ -5436,6 +5436,11 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,7 @@ index b52f0074175..06a010f02ce 100644
|
||||
if (type == FD_TYPE_SERIAL && async_read && length)
|
||||
{
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index f9ce0106c3b..ccac535e50f 100644
|
||||
index aff4d9e09e1..53c694177df 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -296,6 +296,7 @@ static enum server_fd_type file_get_fd_type( struct fd *fd )
|
||||
@ -52,10 +52,10 @@ index f9ce0106c3b..ccac535e50f 100644
|
||||
if (S_ISDIR(file->mode)) return FD_TYPE_DIR;
|
||||
return FD_TYPE_CHAR;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index f37e03cbaea..8b376c613ca 100644
|
||||
index af6424590dc..edfd4cf88d5 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -1361,6 +1361,7 @@ enum server_fd_type
|
||||
@@ -1354,6 +1354,7 @@ enum server_fd_type
|
||||
{
|
||||
FD_TYPE_INVALID, /* invalid file (no associated fd) */
|
||||
FD_TYPE_FILE, /* regular file */
|
||||
@ -64,5 +64,5 @@ index f37e03cbaea..8b376c613ca 100644
|
||||
FD_TYPE_SOCKET, /* socket */
|
||||
FD_TYPE_SERIAL, /* serial port */
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -0,0 +1,101 @@
|
||||
From c2da4e7418c498619f5e8432bccd2c32a8c97f5c Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Wed, 25 Nov 2020 09:05:51 -0700
|
||||
Subject: [PATCH] ntdll: Support reparse point properties in fd_get_file_info.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 2 +-
|
||||
dlls/ntdll/unix/file.c | 26 +++++++++++++++++++-------
|
||||
2 files changed, 20 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index c94a112b23b..b407d0ed18d 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5490,7 +5490,7 @@ static void test_reparse_points(void)
|
||||
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
ok(handle != INVALID_HANDLE_VALUE, "Failed to open symlink file.\n");
|
||||
- todo_wine ok(GetFileSize(handle, NULL) == 0, "symlink size is not zero\n");
|
||||
+ ok(GetFileSize(handle, NULL) == 0, "symlink size is not zero\n");
|
||||
bret = ReadFile(handle, &buf, sizeof(buf), &dwLen, NULL);
|
||||
ok(bret, "Failed to read data from the symlink.\n");
|
||||
ok(dwLen == 0, "Length of symlink data is not zero.\n");
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 8a4dfe9a34b..0a35044f739 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1606,7 +1606,7 @@ static inline int get_file_xattr( char *hexattr, int attrlen )
|
||||
return 0;
|
||||
}
|
||||
|
||||
-NTSTATUS get_symlink_properties(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
|
||||
/* fetch the attributes of a file */
|
||||
@@ -1640,10 +1640,22 @@ 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;
|
||||
+
|
||||
+ /* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
+ *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
+ /* symbolic links always report size 0 */
|
||||
+ st->st_size = 0;
|
||||
+ if (get_symlink_properties( fd, "", NULL, NULL, NULL, NULL, &is_dir ) == STATUS_SUCCESS)
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
+ }
|
||||
+ *attr |= get_file_attributes( st );
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1702,7 +1714,7 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
/* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
/* whether a reparse point is a file or a directory is stored inside the link target */
|
||||
- if (get_symlink_properties( path, NULL, NULL, NULL, NULL, &is_dir ) == STATUS_SUCCESS)
|
||||
+ if (get_symlink_properties( AT_FDCWD, path, NULL, NULL, NULL, NULL, &is_dir ) == STATUS_SUCCESS)
|
||||
st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
}
|
||||
else if (S_ISDIR( st->st_mode ) && (parent_path = malloc( strlen(path) + 4 )))
|
||||
@@ -6249,7 +6261,7 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
-NTSTATUS get_symlink_properties(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
{
|
||||
int len = MAX_PATH;
|
||||
@@ -6265,7 +6277,7 @@ NTSTATUS get_symlink_properties(const char *unix_src, char *unix_dest, int *unix
|
||||
tmp = malloc( len );
|
||||
else
|
||||
tmp = unix_dest;
|
||||
- if ((ret = readlink( unix_src, tmp, len )) < 0)
|
||||
+ if ((ret = readlinkat( fd, unix_src, tmp, len )) < 0)
|
||||
{
|
||||
status = errno_to_status( errno );
|
||||
goto cleanup;
|
||||
@@ -6356,8 +6368,8 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
if ((status = server_get_unix_name( handle, &unix_src, TRUE )))
|
||||
goto cleanup;
|
||||
|
||||
- if ((status = get_symlink_properties( unix_src, unix_dest, &unix_dest_len, &buffer->ReparseTag,
|
||||
- &flags, NULL )))
|
||||
+ if ((status = get_symlink_properties( AT_FDCWD, unix_src, unix_dest, &unix_dest_len,
|
||||
+ &buffer->ReparseTag, &flags, NULL )))
|
||||
goto cleanup;
|
||||
|
||||
/* convert the relative path into an absolute path */
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 69a49f474062017e89448228923e9d3736409d80 Mon Sep 17 00:00:00 2001
|
||||
From 906233fe177919711b247c7e8e6be7b4a70370d6 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.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 6 ++++++
|
||||
dlls/ntdll/unix/file.c | 14 +++++++++++++-
|
||||
2 files changed, 19 insertions(+), 1 deletion(-)
|
||||
dlls/ntdll/tests/file.c | 6 ++++++
|
||||
dlls/ntdll/unix/file.c | 4 +++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 20c569c0962..3f4017d2aeb 100644
|
||||
index b407d0ed18d..47df69541c3 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5215,6 +5215,7 @@ static void test_reparse_points(void)
|
||||
@@ -5297,6 +5297,7 @@ static void test_reparse_points(void)
|
||||
static WCHAR volW[] = {'c',':','\\',0};
|
||||
REPARSE_GUID_DATA_BUFFER guid_buffer;
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
@ -20,7 +20,7 @@ index 20c569c0962..3f4017d2aeb 100644
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
@@ -5224,6 +5225,7 @@ static void test_reparse_points(void)
|
||||
@@ -5305,6 +5306,7 @@ static void test_reparse_points(void)
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
TOKEN_PRIVILEGES tp;
|
||||
@ -28,7 +28,7 @@ index 20c569c0962..3f4017d2aeb 100644
|
||||
WCHAR *dest;
|
||||
LUID luid;
|
||||
BOOL bret;
|
||||
@@ -5407,6 +5409,10 @@ static void test_reparse_points(void)
|
||||
@@ -5494,6 +5496,10 @@ static void test_reparse_points(void)
|
||||
bret = ReadFile(handle, &buf, sizeof(buf), &dwLen, NULL);
|
||||
ok(bret, "Failed to read data from the symlink.\n");
|
||||
ok(dwLen == 0, "Length of symlink data is not zero.\n");
|
||||
@ -40,30 +40,20 @@ index 20c569c0962..3f4017d2aeb 100644
|
||||
|
||||
/* Check the size/data of the symlink target */
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 61fc8e821d9..1c19a05a1c8 100644
|
||||
index 0a35044f739..66c8b98a20a 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -4389,7 +4389,19 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4533,7 +4533,9 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
{
|
||||
FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr;
|
||||
info->FileAttributes = attr;
|
||||
- info->ReparseTag = 0; /* FIXME */
|
||||
+ info->ReparseTag = 0;
|
||||
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
+ {
|
||||
+ char path[MAX_PATH];
|
||||
+ ssize_t len;
|
||||
+ BOOL is_dir;
|
||||
+
|
||||
+ if ((len = readlinkat( fd, "", path, sizeof(path))) != -1)
|
||||
+ {
|
||||
+ path[len] = 0;
|
||||
+ get_symlink_properties(path, len, NULL, NULL, &info->ReparseTag, NULL, &is_dir);
|
||||
+ }
|
||||
+ }
|
||||
+ get_symlink_properties( fd, "", NULL, NULL, &info->ReparseTag, NULL, NULL );
|
||||
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st ))
|
||||
info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 36d6dca595e1db08be515989d741ccd512a662a3 Mon Sep 17 00:00:00 2001
|
||||
From 2bd2870ade6cd8b048ca93a90670c744142ff3f5 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
|
||||
@ -161,7 +161,7 @@ index f49af6d5bfe..bc2cd84a65d 100644
|
||||
+ test_CreateSymbolicLink();
|
||||
}
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 375c00c7367..6040fa18059 100644
|
||||
index 80497c1ac97..68de99a2516 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -38,6 +38,7 @@
|
||||
@ -172,7 +172,7 @@ index 375c00c7367..6040fa18059 100644
|
||||
|
||||
#include "kernelbase.h"
|
||||
#include "wine/exception.h"
|
||||
@@ -936,8 +937,106 @@ done:
|
||||
@@ -938,8 +939,106 @@ done:
|
||||
*/
|
||||
BOOLEAN WINAPI /* DECLSPEC_HOTPATCH */ CreateSymbolicLinkW( LPCWSTR link, LPCWSTR target, DWORD flags )
|
||||
{
|
||||
@ -535,5 +535,5 @@ index 8a3771842a0..a55998e0d79 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,53 +1,42 @@
|
||||
From 2d3399e1071d0754dd3cd7f7ddb2906e561428fb Mon Sep 17 00:00:00 2001
|
||||
From 67ee6190599a8d820f333910b7a365d3fc255e29 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.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/kernelbase/file.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
dlls/kernelbase/file.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 6040fa18059..2f89f78ffd4 100644
|
||||
index 68de99a2516..820f73a38cc 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -1495,6 +1495,41 @@ BOOL WINAPI DECLSPEC_HOTPATCH FindNextFileW( HANDLE handle, WIN32_FIND_DATAW *da
|
||||
@@ -1497,6 +1497,30 @@ BOOL WINAPI DECLSPEC_HOTPATCH FindNextFileW( HANDLE handle, WIN32_FIND_DATAW *da
|
||||
memcpy( data->cFileName, dir_info->FileName, dir_info->FileNameLength );
|
||||
data->cFileName[dir_info->FileNameLength/sizeof(WCHAR)] = 0;
|
||||
|
||||
+ /* get reparse tag */
|
||||
+ if (dir_info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
+ {
|
||||
+ REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
+ INT buffer_len;
|
||||
+ HANDLE hlink;
|
||||
+ DWORD dwret;
|
||||
+ BOOL bret;
|
||||
+ INT path_len = info->path.Length + dir_info->FileNameLength +
|
||||
+ sizeof(WCHAR);
|
||||
+ INT path_len = info->path.Length + dir_info->FileNameLength + sizeof(WCHAR);
|
||||
+ WCHAR *path = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, path_len );
|
||||
+ FILE_ATTRIBUTE_TAG_INFORMATION taginfo;
|
||||
+ IO_STATUS_BLOCK iosb;
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE hlink;
|
||||
+
|
||||
+ if (!path) break;
|
||||
+
|
||||
+ lstrcpynW( path, info->path.Buffer, info->path.Length/sizeof(WCHAR) + 1 );
|
||||
+ lstrcatW( path, data->cFileName );
|
||||
+
|
||||
+ hlink = CreateFileW( path, GENERIC_READ | GENERIC_WRITE, 0, 0,
|
||||
+ OPEN_EXISTING,
|
||||
+ hlink = CreateFileW( path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0 );
|
||||
+ HeapFree( GetProcessHeap(), 0, path );
|
||||
+ buffer_len = sizeof(*buffer) + 2*MAX_PATH*sizeof(WCHAR);
|
||||
+ buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len );
|
||||
+ if (!buffer)
|
||||
+ {
|
||||
+ CloseHandle( hlink );
|
||||
+ break;
|
||||
+ }
|
||||
+ bret = DeviceIoControl( hlink, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer,
|
||||
+ buffer_len, &dwret, 0 );
|
||||
+ if (bret) data->dwReserved0 = buffer->ReparseTag;
|
||||
+ HeapFree( GetProcessHeap(), 0, buffer );
|
||||
+ status = NtQueryInformationFile( hlink, &iosb, &taginfo, sizeof(taginfo),
|
||||
+ FileAttributeTagInformation );
|
||||
+ if (status == STATUS_SUCCESS) data->dwReserved0 = taginfo.ReparseTag;
|
||||
+ CloseHandle( hlink );
|
||||
+ }
|
||||
+
|
||||
@ -55,5 +44,5 @@ index 6040fa18059..2f89f78ffd4 100644
|
||||
{
|
||||
memcpy( data->cAlternateFileName, dir_info->ShortName, dir_info->ShortNameLength );
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From c32b14dc99d3518a015ff8acc29d710304a45fc8 Mon Sep 17 00:00:00 2001
|
||||
From babea30f268f9c25429cd441499aa6c27e9313c1 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.
|
||||
@ -46,5 +46,5 @@ index 24b18bfa81b..40554aed368 100644
|
||||
dir_count++;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,169 +0,0 @@
|
||||
From 3a617a56abd9277e83a0c23d60cb8cba09c4082f Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Wed, 25 Nov 2020 09:05:51 -0700
|
||||
Subject: [PATCH] ntdll: Support reparse point properties in fd_get_file_info.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 2 +-
|
||||
dlls/ntdll/unix/file.c | 85 ++++++++++++++++++++++++-----------------
|
||||
2 files changed, 52 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 05f6f67c4d3..20c569c0962 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5403,7 +5403,7 @@ static void test_reparse_points(void)
|
||||
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
ok(handle != INVALID_HANDLE_VALUE, "Failed to open symlink file.\n");
|
||||
- todo_wine ok(GetFileSize(handle, NULL) == 0, "symlink size is not zero\n");
|
||||
+ ok(GetFileSize(handle, NULL) == 0, "symlink size is not zero\n");
|
||||
bret = ReadFile(handle, &buf, sizeof(buf), &dwLen, NULL);
|
||||
ok(bret, "Failed to read data from the symlink.\n");
|
||||
ok(dwLen == 0, "Length of symlink data is not zero.\n");
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 06a010f02ce..61fc8e821d9 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1614,6 +1614,8 @@ static inline int get_file_xattr( char *hexattr, int attrlen )
|
||||
|
||||
NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
+NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
@@ -1650,6 +1652,23 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
/* 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 ))
|
||||
+ {
|
||||
+ char path[MAX_PATH];
|
||||
+ ssize_t len;
|
||||
+ BOOL is_dir;
|
||||
+
|
||||
+ if ((len = readlinkat( fd, "", path, sizeof(path))) == -1) goto done;
|
||||
+ path[len] = 0;
|
||||
+ /* symbolic links (either junction points or NT symlinks) are "reparse points" */
|
||||
+ *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
+ /* symbolic links always report size 0 */
|
||||
+ st->st_size = 0;
|
||||
+ if (get_symlink_properties(path, len, NULL, NULL, NULL, NULL, &is_dir) == STATUS_SUCCESS)
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6100,42 +6119,22 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
-NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
- DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
+NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
{
|
||||
- int len = MAX_PATH;
|
||||
+ const char *p = target;
|
||||
DWORD reparse_tag;
|
||||
- NTSTATUS status;
|
||||
BOOL dir_flag;
|
||||
- char *p, *tmp;
|
||||
- ssize_t ret;
|
||||
int i;
|
||||
|
||||
- if (unix_dest_len) len = *unix_dest_len;
|
||||
- if (!unix_dest)
|
||||
- tmp = malloc( len );
|
||||
- else
|
||||
- tmp = unix_dest;
|
||||
- if ((ret = readlink( unix_src, tmp, len )) < 0)
|
||||
- {
|
||||
- status = errno_to_status( errno );
|
||||
- goto cleanup;
|
||||
- }
|
||||
- len = ret;
|
||||
- tmp[len] = 0;
|
||||
-
|
||||
/* Decode the reparse tag from the symlink */
|
||||
- p = tmp;
|
||||
if (*p == '.')
|
||||
{
|
||||
if (flags) *flags = SYMLINK_FLAG_RELATIVE;
|
||||
p++;
|
||||
}
|
||||
if (*p++ != '/')
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
reparse_tag = 0;
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
@@ -6147,10 +6146,7 @@ NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_des
|
||||
else if (c == '.' && *p++ == '/')
|
||||
val = 1;
|
||||
else
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
reparse_tag |= (val << i);
|
||||
}
|
||||
/* skip past the directory/file flag */
|
||||
@@ -6163,19 +6159,40 @@ NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_des
|
||||
else if (c == '.' && *p++ == '/')
|
||||
dir_flag = TRUE;
|
||||
else
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else
|
||||
dir_flag = TRUE;
|
||||
- len -= (p - tmp);
|
||||
+ len -= (p - target);
|
||||
if (tag) *tag = reparse_tag;
|
||||
if (is_dir) *is_dir = dir_flag;
|
||||
if (unix_dest) memmove(unix_dest, p, len + 1);
|
||||
if (unix_dest_len) *unix_dest_len = len;
|
||||
- status = STATUS_SUCCESS;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
+{
|
||||
+ int len = MAX_PATH;
|
||||
+ NTSTATUS status;
|
||||
+ ssize_t ret;
|
||||
+ char *tmp;
|
||||
+
|
||||
+ if (unix_dest_len) len = *unix_dest_len;
|
||||
+ if (!unix_dest)
|
||||
+ tmp = malloc( len );
|
||||
+ else
|
||||
+ tmp = unix_dest;
|
||||
+ if ((ret = readlink( unix_src, tmp, len )) < 0)
|
||||
+ {
|
||||
+ status = errno_to_status( errno );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ len = ret;
|
||||
+ tmp[len] = 0;
|
||||
+ status = get_symlink_properties(tmp, len, unix_dest, unix_dest_len, tag, flags, is_dir);
|
||||
|
||||
cleanup:
|
||||
if (!unix_dest) free( tmp );
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 652ceaf374295989dec1d32157f3f81707af08ea Mon Sep 17 00:00:00 2001
|
||||
From c36ba7d9de06abcbacdca63cdabdb2b91a17a0fb 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.
|
||||
@ -62,5 +62,5 @@ index 40554aed368..0618ffec8d1 100644
|
||||
if (!((lstrcmpW(fd[i].cFileName, L".") == 0) ||
|
||||
(lstrcmpW(fd[i].cFileName, L"..") == 0))) {
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 4d2c17cf2ccd327c57be77429f86221c9d984b72 Mon Sep 17 00:00:00 2001
|
||||
From c54be21fe819e7bb157a0a0edc3f9a3d3636d765 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.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 47 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
|
||||
index 0fb40d94e49..07d34c10706 100644
|
||||
index 502694ffc46..bb1a5578911 100644
|
||||
--- a/programs/cmd/builtins.c
|
||||
+++ b/programs/cmd/builtins.c
|
||||
@@ -31,6 +31,9 @@
|
||||
@ -22,7 +22,7 @@ index 0fb40d94e49..07d34c10706 100644
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cmd);
|
||||
|
||||
@@ -4973,6 +4976,49 @@ void WCMD_color (void) {
|
||||
@@ -4969,6 +4972,49 @@ void WCMD_color (void) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ index 0fb40d94e49..07d34c10706 100644
|
||||
/****************************************************************************
|
||||
* WCMD_mklink
|
||||
*/
|
||||
@@ -5021,7 +5067,7 @@ void WCMD_mklink(WCHAR *args)
|
||||
@@ -5017,7 +5063,7 @@ void WCMD_mklink(WCHAR *args)
|
||||
else if(!junction)
|
||||
ret = CreateSymbolicLinkW(file1, file2, isdir);
|
||||
else
|
||||
@ -82,5 +82,5 @@ index 0fb40d94e49..07d34c10706 100644
|
||||
if(!ret)
|
||||
WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From e509d8607a0c85846b8d060041f8d16704f2f749 Mon Sep 17 00:00:00 2001
|
||||
From 68254807f957ad327c12c8bfaf6b5dcfad9a4efd Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 12:17:23 -0700
|
||||
Subject: [PATCH] server: Properly handle renames involving symlinks.
|
||||
@ -8,10 +8,10 @@ Subject: [PATCH] server: Properly handle renames involving symlinks.
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 9a06492c3bb..ee58aa3c8ae 100644
|
||||
index dfab2e71f27..c7c4ad280ef 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2628,7 +2628,7 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
@@ -2631,7 +2631,7 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ index 9a06492c3bb..ee58aa3c8ae 100644
|
||||
{
|
||||
if (!fstat( fd->unix_fd, &st2 ) && st.st_ino == st2.st_ino && st.st_dev == st2.st_dev)
|
||||
{
|
||||
@@ -2644,7 +2644,7 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
@@ -2647,7 +2647,7 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
}
|
||||
|
||||
/* can't replace directories or special files */
|
||||
@ -29,7 +29,7 @@ index 9a06492c3bb..ee58aa3c8ae 100644
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
goto failed;
|
||||
@@ -2703,6 +2703,8 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
@@ -2706,6 +2706,8 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
free( fd->unlink_name );
|
||||
free( fd->unix_name );
|
||||
fd->closed->unix_name = fd->unix_name = realpath( name, NULL );
|
||||
@ -39,5 +39,5 @@ index 9a06492c3bb..ee58aa3c8ae 100644
|
||||
set_error( STATUS_NO_MEMORY );
|
||||
return;
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 8d31be068c4e5fbf31c66b8a28a9a7a666a2e2ab Mon Sep 17 00:00:00 2001
|
||||
From 697dae8422849f3adadf523b9fa20f7db21739f8 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: Use FILE_OPEN_REPARSE_POINT in
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] kernelbase: Use FILE_OPEN_REPARSE_POINT in
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 2f89f78ffd4..795cdcbfaf5 100644
|
||||
index 820f73a38cc..7ad352d3451 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -2592,7 +2592,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH MoveFileWithProgressW( const WCHAR *source, const
|
||||
@@ -2583,7 +2583,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH MoveFileWithProgressW( const WCHAR *source, const
|
||||
|
||||
status = NtOpenFile( &source_handle, DELETE | SYNCHRONIZE, &attr, &io,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
@ -22,5 +22,5 @@ index 2f89f78ffd4..795cdcbfaf5 100644
|
||||
if (!set_ntstatus( status )) goto error;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 0646ca34d0052611e66af79cfb1196177260e1c9 Mon Sep 17 00:00:00 2001
|
||||
From 7150cb17fa6b349530dea3a808c8cfbd55acc16c 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: Use FILE_OPEN_REPARSE_POINT in DeleteFile.
|
||||
@ -8,10 +8,10 @@ Subject: [PATCH] kernelbase: Use FILE_OPEN_REPARSE_POINT in DeleteFile.
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
|
||||
index 795cdcbfaf5..73655ca6ffa 100644
|
||||
index 7ad352d3451..b96de9948b8 100644
|
||||
--- a/dlls/kernelbase/file.c
|
||||
+++ b/dlls/kernelbase/file.c
|
||||
@@ -1080,7 +1080,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW( LPCWSTR path )
|
||||
@@ -1082,7 +1082,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW( LPCWSTR path )
|
||||
|
||||
status = NtCreateFile(&hFile, SYNCHRONIZE | DELETE, &attr, &io, NULL, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
@ -22,5 +22,5 @@ index 795cdcbfaf5..73655ca6ffa 100644
|
||||
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
From 2851b3072e7776cd87a3b79aa7edc99813fbcf2e 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: Treat undecoded unix symlinks as NT symlinks.
|
||||
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 28 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 1c19a05a1c8..b6e49590f62 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1614,8 +1614,8 @@ static inline int get_file_xattr( char *hexattr, int attrlen )
|
||||
|
||||
NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
-NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
- DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
+void get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir);
|
||||
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
@@ -1664,8 +1664,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
/* symbolic links always report size 0 */
|
||||
st->st_size = 0;
|
||||
- if (get_symlink_properties(path, len, NULL, NULL, NULL, NULL, &is_dir) == STATUS_SUCCESS)
|
||||
- st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
+ get_symlink_properties(path, len, NULL, NULL, NULL, NULL, &is_dir);
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -6131,10 +6131,11 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
-NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
- DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
+void get_symlink_properties(const char *target, int len, char *unix_dest, int *unix_dest_len,
|
||||
+ DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
{
|
||||
const char *p = target;
|
||||
+ int decoded = FALSE;
|
||||
DWORD reparse_tag;
|
||||
BOOL dir_flag;
|
||||
int i;
|
||||
@@ -6146,7 +6147,7 @@ NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, in
|
||||
p++;
|
||||
}
|
||||
if (*p++ != '/')
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ goto done;
|
||||
reparse_tag = 0;
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
@@ -6158,7 +6159,7 @@ NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, in
|
||||
else if (c == '.' && *p++ == '/')
|
||||
val = 1;
|
||||
else
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ goto done;
|
||||
reparse_tag |= (val << i);
|
||||
}
|
||||
/* skip past the directory/file flag */
|
||||
@@ -6171,16 +6172,31 @@ NTSTATUS get_symlink_properties(const char *target, int len, char *unix_dest, in
|
||||
else if (c == '.' && *p++ == '/')
|
||||
dir_flag = TRUE;
|
||||
else
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ goto done;
|
||||
}
|
||||
else
|
||||
dir_flag = TRUE;
|
||||
+ decoded = TRUE;
|
||||
+
|
||||
+done:
|
||||
+ if (!decoded)
|
||||
+ {
|
||||
+ /* treat undecoded unix symlinks as NT symlinks */
|
||||
+ struct stat st;
|
||||
+
|
||||
+ p = target;
|
||||
+ if (flags && *p != '/') *flags = SYMLINK_FLAG_RELATIVE;
|
||||
+ reparse_tag = IO_REPARSE_TAG_SYMLINK;
|
||||
+ if (!stat( target, &st ))
|
||||
+ dir_flag = S_ISDIR(st.st_mode);
|
||||
+ else
|
||||
+ dir_flag = FALSE; /* treat dangling symlinks as files */
|
||||
+ }
|
||||
len -= (p - target);
|
||||
if (tag) *tag = reparse_tag;
|
||||
if (is_dir) *is_dir = dir_flag;
|
||||
if (unix_dest) memmove(unix_dest, p, len + 1);
|
||||
if (unix_dest_len) *unix_dest_len = len;
|
||||
- return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -6204,7 +6220,8 @@ NTSTATUS FILE_DecodeSymlink(const char *unix_src, char *unix_dest, int *unix_des
|
||||
}
|
||||
len = ret;
|
||||
tmp[len] = 0;
|
||||
- status = get_symlink_properties(tmp, len, unix_dest, unix_dest_len, tag, flags, is_dir);
|
||||
+ get_symlink_properties(tmp, len, unix_dest, unix_dest_len, tag, flags, is_dir);
|
||||
+ status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (!unix_dest) free( tmp );
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,178 @@
|
||||
From ebba56121b254c640ef9fb9b2888bc9b08062080 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: Treat undecoded unix symlinks as WSL Linux/Unix
|
||||
symlinks.
|
||||
|
||||
---
|
||||
dlls/ntdll/unix/file.c | 62 ++++++++++++++++++++++++------------------
|
||||
include/ntifs.h | 4 +++
|
||||
include/winnt.h | 1 +
|
||||
3 files changed, 41 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 66c8b98a20a..62593fa8526 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6266,9 +6266,10 @@ cleanup:
|
||||
NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, int *unix_dest_len,
|
||||
DWORD *tag, ULONG *flags, BOOL *is_dir)
|
||||
{
|
||||
+ NTSTATUS status = STATUS_SUCCESS;
|
||||
int len = MAX_PATH;
|
||||
+ int decoded = FALSE;
|
||||
DWORD reparse_tag;
|
||||
- NTSTATUS status;
|
||||
BOOL dir_flag;
|
||||
char *p, *tmp;
|
||||
ssize_t ret;
|
||||
@@ -6295,10 +6296,7 @@ NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, i
|
||||
p++;
|
||||
}
|
||||
if (*p++ != '/')
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ goto done;
|
||||
reparse_tag = 0;
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
@@ -6310,10 +6308,7 @@ NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, i
|
||||
else if (c == '.' && *p++ == '/')
|
||||
val = 1;
|
||||
else
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ goto done;
|
||||
reparse_tag |= (val << i);
|
||||
}
|
||||
/* skip past the directory/file flag */
|
||||
@@ -6326,19 +6321,31 @@ NTSTATUS get_symlink_properties(int fd, const char *unix_src, char *unix_dest, i
|
||||
else if (c == '.' && *p++ == '/')
|
||||
dir_flag = TRUE;
|
||||
else
|
||||
- {
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ goto done;
|
||||
}
|
||||
else
|
||||
dir_flag = TRUE;
|
||||
+ decoded = TRUE;
|
||||
+
|
||||
+done:
|
||||
+ if (!decoded)
|
||||
+ {
|
||||
+ /* treat undecoded unix symlinks as NT symlinks */
|
||||
+ struct stat st;
|
||||
+
|
||||
+ p = tmp;
|
||||
+ reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
+ if (flags && *p != '/') *flags = SYMLINK_FLAG_RELATIVE;
|
||||
+ if (!stat( tmp, &st ))
|
||||
+ dir_flag = S_ISDIR(st.st_mode);
|
||||
+ else
|
||||
+ dir_flag = FALSE; /* treat dangling symlinks as files */
|
||||
+ }
|
||||
len -= (p - tmp);
|
||||
if (tag) *tag = reparse_tag;
|
||||
if (is_dir) *is_dir = dir_flag;
|
||||
if (unix_dest) memmove(unix_dest, p, len + 1);
|
||||
if (unix_dest_len) *unix_dest_len = len;
|
||||
- status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (!unix_dest) free( tmp );
|
||||
@@ -6352,9 +6359,9 @@ cleanup:
|
||||
*/
|
||||
NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_size)
|
||||
{
|
||||
+ VOID *subst_name = NULL, *print_name = NULL, *unix_name = NULL;
|
||||
INT prefix_len, path_len, total_len;
|
||||
char *unix_src, unix_dest[PATH_MAX];
|
||||
- VOID *subst_name, *print_name;
|
||||
SIZE_T nt_dest_len = PATH_MAX;
|
||||
int unix_dest_len = PATH_MAX;
|
||||
BOOL dest_allocated = FALSE;
|
||||
@@ -6419,6 +6426,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
{
|
||||
case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
max_length = out_size-FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[1]);
|
||||
+ if (nt_dest_len > max_length) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
|
||||
path_len = 0;
|
||||
buffer->MountPointReparseBuffer.SubstituteNameOffset = path_len;
|
||||
buffer->MountPointReparseBuffer.SubstituteNameLength = nt_dest_len;
|
||||
@@ -6432,6 +6440,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
break;
|
||||
case IO_REPARSE_TAG_SYMLINK:
|
||||
max_length = out_size-FIELD_OFFSET(typeof(*buffer), SymbolicLinkReparseBuffer.PathBuffer[1]);
|
||||
+ if (nt_dest_len > max_length) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
|
||||
path_len = 0;
|
||||
buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = path_len;
|
||||
buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = nt_dest_len;
|
||||
@@ -6445,19 +6454,20 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out
|
||||
buffer->SymbolicLinkReparseBuffer.Flags = flags;
|
||||
break;
|
||||
default:
|
||||
- /* unrecognized (regular) files should probably be treated as symlinks */
|
||||
- WARN("unrecognized symbolic link\n");
|
||||
- status = STATUS_NOT_IMPLEMENTED;
|
||||
- goto cleanup;
|
||||
- }
|
||||
- if (nt_dest_len > max_length)
|
||||
- {
|
||||
- status = STATUS_BUFFER_TOO_SMALL;
|
||||
- goto cleanup;
|
||||
+ WARN("unrecognized symbolic link reparse tag: 0x%08x\n", buffer->ReparseTag);
|
||||
+ case IO_REPARSE_TAG_LX_SYMLINK:
|
||||
+ /* report links without a reparse tag as a WSL linux/unix symlink */
|
||||
+ max_length = out_size-FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[0]);
|
||||
+ if (unix_dest_len > max_length) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
|
||||
+ buffer->LinuxSymbolicLinkReparseBuffer.Version = 2;
|
||||
+ unix_name = &buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer[0];
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[unix_dest_len]);
|
||||
+ break;
|
||||
}
|
||||
|
||||
- memcpy( subst_name, nt_dest, nt_dest_len );
|
||||
- memcpy( print_name, &nt_dest[prefix_len], nt_dest_len - prefix_len*sizeof(WCHAR) );
|
||||
+ if (subst_name) memcpy( subst_name, nt_dest, nt_dest_len );
|
||||
+ if (print_name) memcpy( print_name, &nt_dest[prefix_len], nt_dest_len - prefix_len*sizeof(WCHAR) );
|
||||
+ if (unix_name) memcpy( unix_name, unix_dest, unix_dest_len );
|
||||
buffer->ReparseDataLength = total_len - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
diff --git a/include/ntifs.h b/include/ntifs.h
|
||||
index 0d02225bc4f..25af12a413a 100644
|
||||
--- a/include/ntifs.h
|
||||
+++ b/include/ntifs.h
|
||||
@@ -42,6 +42,10 @@ typedef struct _REPARSE_DATA_BUFFER {
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
+ struct {
|
||||
+ ULONG Version;
|
||||
+ UCHAR PathBuffer[1];
|
||||
+ } LinuxSymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
diff --git a/include/winnt.h b/include/winnt.h
|
||||
index 0843ee3f739..52a4825781c 100644
|
||||
--- a/include/winnt.h
|
||||
+++ b/include/winnt.h
|
||||
@@ -2877,6 +2877,7 @@ extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#define IO_REPARSE_TAG_CLOUD_MASK __MSABI_LONG(0x0000F000)
|
||||
#define IO_REPARSE_TAG_APPEXECLINK __MSABI_LONG(0x8000001B)
|
||||
#define IO_REPARSE_TAG_GVFS __MSABI_LONG(0x9000001C)
|
||||
+#define IO_REPARSE_TAG_LX_SYMLINK __MSABI_LONG(0xA000001D)
|
||||
#define IO_REPARSE_TAG_STORAGE_SYNC __MSABI_LONG(0x8000001E)
|
||||
#define IO_REPARSE_TAG_WCI_TOMBSTONE __MSABI_LONG(0xA000001F)
|
||||
#define IO_REPARSE_TAG_UNHANDLED __MSABI_LONG(0x80000020)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,156 @@
|
||||
From 54b8792b895c7aaa3c2795fb9293187493b8766e 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.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 43 +++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 30 ++++++++++++++++++++--------
|
||||
2 files changed, 65 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 47df69541c3..eadd5922f32 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5301,7 +5301,9 @@ static void test_reparse_points(void)
|
||||
REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
DWORD dwret, dwLen, dwFlags, err;
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
+ UCHAR *unix_dest;
|
||||
WCHAR buf[] = {0,0,0,0};
|
||||
+ char name[] = "target";
|
||||
HANDLE handle, token;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
UNICODE_STRING nameW;
|
||||
@@ -5647,6 +5649,47 @@ static void test_reparse_points(void)
|
||||
wine_dbgstr_w(dest), wine_dbgstr_w(&targetW[1]));
|
||||
CloseHandle(handle);
|
||||
|
||||
+ /* Create a Unix/Linux symlink */
|
||||
+ HeapFree(GetProcessHeap(), 0, buffer);
|
||||
+ RemoveDirectoryW(reparse_path);
|
||||
+ bret = CreateDirectoryW(reparse_path, NULL);
|
||||
+ handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
+ if (handle == INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ win_skip("Failed to open symlink directory handle (0x%x).\n", GetLastError());
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
+ ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
|
||||
+ path_len = strlen(name);
|
||||
+ buffer_len = offsetof(REPARSE_DATA_BUFFER, LinuxSymbolicLinkReparseBuffer.PathBuffer[path_len]);
|
||||
+ buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len);
|
||||
+ buffer->ReparseTag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
+ buffer->ReparseDataLength = sizeof(ULONG) + path_len;
|
||||
+ memcpy(buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer, name, path_len);
|
||||
+ bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
|
||||
+ ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
|
||||
+
|
||||
+ /* Read back the Unix/Linux symlink */
|
||||
+ 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);
|
||||
+ if (handle == INVALID_HANDLE_VALUE)
|
||||
+ buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR);
|
||||
+ buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len);
|
||||
+ bret = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer, buffer_len, &dwret, 0);
|
||||
+ ok(bret, "Failed to read symlink!\n");
|
||||
+ string_len = buffer->ReparseDataLength - sizeof(ULONG);
|
||||
+ unix_dest = &buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer[0];
|
||||
+ ok((memcmp(unix_dest, name, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
|
||||
+ unix_dest, name);
|
||||
+ total_len = FIELD_OFFSET(typeof(*buffer), LinuxSymbolicLinkReparseBuffer.PathBuffer[path_len])
|
||||
+ - FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
|
||||
+ ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
|
||||
+ buffer->ReparseDataLength, total_len);
|
||||
+ CloseHandle(handle);
|
||||
+
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
pRtlFreeUnicodeString(&nameW);
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 62593fa8526..e3c21bcbc66 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6049,18 +6049,18 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
{
|
||||
BOOL src_allocated = FALSE, path_allocated = FALSE, dest_allocated = FALSE;
|
||||
BOOL nt_dest_allocated = FALSE, tempdir_created = FALSE;
|
||||
- char *unix_src, *unix_dest, *unix_path = NULL;
|
||||
+ char *unix_src, *unix_dest = NULL, *unix_path = NULL;
|
||||
char tmpdir[PATH_MAX], tmplink[PATH_MAX], *d;
|
||||
SIZE_T unix_dest_len = PATH_MAX;
|
||||
char magic_dest[PATH_MAX];
|
||||
int dest_fd, needs_close;
|
||||
+ int dest_len = 0, offset;
|
||||
int relative_offset = 0;
|
||||
UNICODE_STRING nt_dest;
|
||||
- int dest_len, offset;
|
||||
BOOL is_dir = TRUE;
|
||||
+ WCHAR *dest = NULL;
|
||||
NTSTATUS status;
|
||||
struct stat st;
|
||||
- WCHAR *dest;
|
||||
ULONG flags;
|
||||
int i;
|
||||
|
||||
@@ -6078,6 +6078,12 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
flags = buffer->SymbolicLinkReparseBuffer.Flags;
|
||||
break;
|
||||
+ case IO_REPARSE_TAG_LX_SYMLINK:
|
||||
+ offset = 0;
|
||||
+ flags = 0;
|
||||
+ unix_dest_len = buffer->ReparseDataLength - sizeof(ULONG);
|
||||
+ unix_dest = (char *) &buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ break;
|
||||
default:
|
||||
FIXME("stub: FSCTL_SET_REPARSE_POINT(%x)\n", buffer->ReparseTag);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
@@ -6089,6 +6095,9 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
if ((status = server_get_unix_name( handle, &unix_src, FALSE )))
|
||||
goto cleanup;
|
||||
src_allocated = TRUE;
|
||||
+
|
||||
+ if (unix_dest) goto have_dest;
|
||||
+
|
||||
if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
{
|
||||
SIZE_T nt_path_len = PATH_MAX, unix_path_len = PATH_MAX;
|
||||
@@ -6164,6 +6173,8 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
if (status != STATUS_SUCCESS && status != STATUS_NO_SUCH_FILE)
|
||||
goto cleanup;
|
||||
dest_allocated = TRUE;
|
||||
+
|
||||
+have_dest:
|
||||
/* check that the source and destination paths are the same up to the relative path */
|
||||
if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
{
|
||||
@@ -6179,14 +6190,17 @@ NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
|
||||
/* Encode the reparse tag into the symlink */
|
||||
strcpy( magic_dest, "" );
|
||||
- if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
- strcat( magic_dest, "." );
|
||||
- strcat( magic_dest, "/" );
|
||||
- for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
+ if (buffer->ReparseTag != IO_REPARSE_TAG_LX_SYMLINK)
|
||||
{
|
||||
- if ((buffer->ReparseTag >> i) & 1)
|
||||
+ if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
strcat( magic_dest, "." );
|
||||
strcat( magic_dest, "/" );
|
||||
+ for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
+ {
|
||||
+ if ((buffer->ReparseTag >> i) & 1)
|
||||
+ strcat( magic_dest, "." );
|
||||
+ strcat( magic_dest, "/" );
|
||||
+ }
|
||||
}
|
||||
/* Encode the type (file or directory) if NT symlink */
|
||||
if (buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 4507201faf3a7993d4e8f214c5de081f4656ad5e Mon Sep 17 00:00:00 2001
|
||||
From 96096532f7ec6e1fb58ec5216995c944d4d7c2f6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 6 Feb 2021 16:15:46 -0700
|
||||
Subject: [PATCH] ntdll: Strip the wine prefix from reparse point paths
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] ntdll: Strip the wine prefix from reparse point paths
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index b17b53146b3..614f37fb3d6 100644
|
||||
index e3c21bcbc66..346e1e8c84c 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -6051,6 +6051,33 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
@@ -6041,6 +6041,33 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ index b17b53146b3..614f37fb3d6 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.
|
||||
@@ -6183,6 +6210,8 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6185,6 +6212,8 @@ have_dest:
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
From d7dbc8bcef2eb27d629ecf69f3d98fbe8aab3da7 Mon Sep 17 00:00:00 2001
|
||||
From 5952a53690460f2bafac92f10dfeee15aaa709c1 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 a marker to reparse point paths to indicate the
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] ntdll: Add a marker to reparse point paths to indicate the
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 25b542cb4fc..313d17ddbf9 100644
|
||||
index 346e1e8c84c..325ac6ed8a1 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -5938,6 +5938,26 @@ void strip_external_path( char *path, SIZE_T *len )
|
||||
@@ -6068,6 +6068,26 @@ void strip_external_path( char *path, SIZE_T *len )
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ index 25b542cb4fc..313d17ddbf9 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.
|
||||
@@ -6071,7 +6091,10 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
@@ -6213,7 +6233,10 @@ have_dest:
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -51,5 +51,5 @@ index 25b542cb4fc..313d17ddbf9 100644
|
||||
TRACE( "Linking %s to %s\n", unix_src, &unix_dest[relative_offset] );
|
||||
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -1,27 +1,37 @@
|
||||
From 5f87760574f835580a0bf47962c28f6ef8f2859d Mon Sep 17 00:00:00 2001
|
||||
From dc74c7a174aac20be96cf40914bc4927256eac47 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] server: Rewrite absolute reparse point targets if the prefix
|
||||
location changes.
|
||||
|
||||
---
|
||||
server/fd.c | 87 +++++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 74 insertions(+), 13 deletions(-)
|
||||
server/fd.c | 85 +++++++++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 69 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index ee58aa3c8ae..43c0d36dff9 100644
|
||||
index c7c4ad280ef..d795080cfda 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -1902,7 +1902,7 @@ void get_nt_name( struct fd *fd, struct unicode_str *name )
|
||||
@@ -1902,23 +1902,16 @@ void get_nt_name( struct fd *fd, struct unicode_str *name )
|
||||
name->len = fd->nt_namelen;
|
||||
}
|
||||
|
||||
-static void decode_symlink(char *name, int *is_dir)
|
||||
-int check_symlink( char *name )
|
||||
+static char *decode_symlink(const char *name, ULONG *tag, int *is_dir)
|
||||
{
|
||||
char link[MAX_PATH], *p;
|
||||
- struct stat st;
|
||||
-
|
||||
- lstat( name, &st );
|
||||
- return S_ISLNK( st.st_mode );
|
||||
-}
|
||||
-
|
||||
-static void decode_symlink(char *name, int *is_dir)
|
||||
-{
|
||||
- char link[MAX_PATH], *p;
|
||||
+ static char link[MAX_PATH];
|
||||
ULONG reparse_tag;
|
||||
@@ -1910,7 +1910,7 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
int len, i;
|
||||
+ char *p;
|
||||
|
||||
len = readlink( name, link, sizeof(link) );
|
||||
if (len == -1)
|
||||
@ -30,7 +40,7 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
link[len] = 0;
|
||||
p = link;
|
||||
/* skip past relative/absolute indication */
|
||||
@@ -1918,7 +1918,7 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
@@ -1926,7 +1919,7 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
p++;
|
||||
if (*p++ != '/')
|
||||
{
|
||||
@ -39,7 +49,7 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
}
|
||||
/* decode the reparse tag */
|
||||
reparse_tag = 0;
|
||||
@@ -1932,7 +1932,7 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
@@ -1940,7 +1933,7 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
else if (c == '.' && *p++ == '/')
|
||||
val = 1;
|
||||
else
|
||||
@ -48,7 +58,7 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
reparse_tag |= (val << i);
|
||||
}
|
||||
/* decode the directory/file flag */
|
||||
@@ -1945,10 +1945,69 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
@@ -1953,10 +1946,70 @@ static void decode_symlink(char *name, int *is_dir)
|
||||
else if (c == '.' && *p++ == '/')
|
||||
*is_dir = TRUE;
|
||||
else
|
||||
@ -61,7 +71,7 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
+static void rewrite_symlink( const char *path )
|
||||
+static int rewrite_symlink( const char *path )
|
||||
+{
|
||||
+ static char marker[] = "////.//.//"; /* "P" (0x50) encoded as a path (0=/ 1=./) */
|
||||
+ char *link, *prefix_end, *local_link;
|
||||
@ -76,23 +86,23 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
+ {
|
||||
+ char tmp_dir[MAX_PATH];
|
||||
+
|
||||
+ if (getcwd( tmp_dir, sizeof(tmp_dir) ) == NULL) return;
|
||||
+ if (fchdir( config_dir_fd ) == -1) return;
|
||||
+ if (getcwd( config_dir, sizeof(config_dir) ) == NULL) return;
|
||||
+ if (chdir( tmp_dir ) == -1) return;
|
||||
+ if (getcwd( tmp_dir, sizeof(tmp_dir) ) == NULL) return FALSE;
|
||||
+ if (fchdir( config_dir_fd ) == -1) return FALSE;
|
||||
+ if (getcwd( config_dir, sizeof(config_dir) ) == NULL) return FALSE;
|
||||
+ if (chdir( tmp_dir ) == -1) return FALSE;
|
||||
+ config_dir_len = strlen( config_dir );
|
||||
+ }
|
||||
+
|
||||
+ /* grab the current link contents */
|
||||
+ link = decode_symlink( path, &tag, &is_dir );
|
||||
+ if (link == NULL) return;
|
||||
+ if (link == NULL) return FALSE;
|
||||
+
|
||||
+ /* find out if the prefix matches, if it does then do not modify the link */
|
||||
+ prefix_end = strstr( link, marker );
|
||||
+ if (prefix_end == NULL) return;
|
||||
+ if (prefix_end == NULL) return TRUE;
|
||||
+ local_link = prefix_end + strlen( marker );
|
||||
+ len = prefix_end - link;
|
||||
+ if (len == config_dir_len && strncmp( config_dir, link, len ) == 0) return;
|
||||
+ if (len == config_dir_len && strncmp( config_dir, link, len ) == 0) return TRUE;
|
||||
+ /* if the prefix does not match then re-encode the link with the new prefix */
|
||||
+
|
||||
+ /* Encode the reparse tag into the symlink */
|
||||
@ -116,40 +126,20 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
+ /* replace the symlink */
|
||||
+ unlink( path );
|
||||
+ symlink( new_target, path );
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
/* open() wrapper that returns a struct fd with no fd user set */
|
||||
@@ -2016,6 +2075,15 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
flags |= O_SYMLINK;
|
||||
#endif
|
||||
|
||||
+ fd->unix_name = NULL;
|
||||
+ if ((path = dup_fd_name( root, name )))
|
||||
+ {
|
||||
+ rewrite_symlink( path );
|
||||
+ fd->unlink_name = path;
|
||||
+ fd->unix_name = realpath( path, NULL );
|
||||
+ if (!fd->unix_name) fd->unix_name = dup_fd_name( root, name ); /* dangling symlink */
|
||||
+ }
|
||||
+
|
||||
if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
|
||||
@@ -2022,7 +2075,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
fd->unix_name = NULL;
|
||||
if ((path = dup_fd_name( root, name )))
|
||||
{
|
||||
/* if we tried to open a directory for write access, retry read-only */
|
||||
@@ -2033,13 +2101,6 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
}
|
||||
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
- fd->unix_name = NULL;
|
||||
- if ((path = dup_fd_name( root, name )))
|
||||
- {
|
||||
- fd->unlink_name = path;
|
||||
- fd->unix_name = realpath( path, NULL );
|
||||
- if (!fd->unix_name) fd->unix_name = dup_fd_name( root, name ); /* dangling symlink */
|
||||
- }
|
||||
|
||||
closed_fd->unix_fd = fd->unix_fd;
|
||||
closed_fd->unlink = 0;
|
||||
@@ -2073,7 +2134,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
- int is_symlink = check_symlink( path );
|
||||
+ int is_symlink = rewrite_symlink( path );
|
||||
#if defined(O_SYMLINK)
|
||||
if (is_symlink && (options & FILE_OPEN_REPARSE_POINT) && !(flags & O_CREAT))
|
||||
flags |= O_SYMLINK;
|
||||
@@ -2082,7 +2135,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
*mode = st.st_mode;
|
||||
is_dir = S_ISDIR(st.st_mode);
|
||||
if (is_link)
|
||||
@ -159,5 +149,5 @@ index ee58aa3c8ae..43c0d36dff9 100644
|
||||
/* check directory options */
|
||||
if ((options & FILE_DIRECTORY_FILE) && !is_dir)
|
||||
--
|
||||
2.20.1
|
||||
2.30.2
|
||||
|
@ -2131,8 +2131,8 @@ fi
|
||||
# | Modified files:
|
||||
# | * configure.ac, dlls/kernel32/path.c, dlls/kernel32/tests/path.c, dlls/kernelbase/file.c, dlls/mountmgr.sys/device.c,
|
||||
# | dlls/msvcp120/tests/msvcp120.c, dlls/msvcp140/tests/msvcp140.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c,
|
||||
# | include/Makefile.in, include/ntifs.h, include/winternl.h, programs/cmd/builtins.c, programs/cmd/directory.c,
|
||||
# | server/fd.c, server/file.c, server/protocol.def
|
||||
# | include/Makefile.in, include/ntifs.h, include/winnt.h, include/winternl.h, programs/cmd/builtins.c,
|
||||
# | programs/cmd/directory.c, server/fd.c, server/file.c, server/protocol.def
|
||||
# |
|
||||
if test "$enable_ntdll_Junction_Points" -eq 1; then
|
||||
patch_apply ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch
|
||||
@ -2157,22 +2157,23 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
|
||||
patch_apply ntdll-Junction_Points/0020-kernelbase-Use-FILE_OPEN_REPARSE_POINT-in-RemoveDire.patch
|
||||
patch_apply ntdll-Junction_Points/0021-ntdll-Always-report-symbolic-links-as-containing-zer.patch
|
||||
patch_apply ntdll-Junction_Points/0022-ntdll-Find-dangling-symlinks-quickly.patch
|
||||
patch_apply ntdll-Junction_Points/0023-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch
|
||||
patch_apply ntdll-Junction_Points/0024-kernel32-Add-reparse-support-to-FindNextFile.patch
|
||||
patch_apply ntdll-Junction_Points/0025-wcmd-Display-reparse-point-type-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0026-wcmd-Show-reparse-point-target-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0027-wcmd-Add-junction-point-support-to-mklink.patch
|
||||
patch_apply ntdll-Junction_Points/0028-server-Fix-obtaining-information-about-a-symlink.patch
|
||||
patch_apply ntdll-Junction_Points/0029-ntdll-Succeed-with-no-data-for-NtReadFile-on-reparse.patch
|
||||
patch_apply ntdll-Junction_Points/0030-ntdll-Support-reparse-point-properties-in-fd_get_fil.patch
|
||||
patch_apply ntdll-Junction_Points/0031-ntdll-Add-support-for-FileAttributeTagInformation.patch
|
||||
patch_apply ntdll-Junction_Points/0023-server-Fix-obtaining-information-about-a-symlink.patch
|
||||
patch_apply ntdll-Junction_Points/0024-ntdll-Succeed-with-no-data-for-NtReadFile-on-reparse.patch
|
||||
patch_apply ntdll-Junction_Points/0025-ntdll-Support-reparse-point-properties-in-fd_get_fil.patch
|
||||
patch_apply ntdll-Junction_Points/0026-ntdll-Add-support-for-FileAttributeTagInformation.patch
|
||||
patch_apply ntdll-Junction_Points/0027-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch
|
||||
patch_apply ntdll-Junction_Points/0028-kernel32-Add-reparse-support-to-FindNextFile.patch
|
||||
patch_apply ntdll-Junction_Points/0029-wcmd-Display-reparse-point-type-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0030-wcmd-Show-reparse-point-target-in-directory-listing.patch
|
||||
patch_apply ntdll-Junction_Points/0031-wcmd-Add-junction-point-support-to-mklink.patch
|
||||
patch_apply ntdll-Junction_Points/0032-server-Properly-handle-renames-involving-symlinks.patch
|
||||
patch_apply ntdll-Junction_Points/0033-kernelbase-Use-FILE_OPEN_REPARSE_POINT-in-MoveFileWi.patch
|
||||
patch_apply ntdll-Junction_Points/0034-kernelbase-Use-FILE_OPEN_REPARSE_POINT-in-DeleteFile.patch
|
||||
patch_apply ntdll-Junction_Points/0035-ntdll-Treat-undecoded-unix-symlinks-as-NT-symlinks.patch
|
||||
patch_apply ntdll-Junction_Points/0036-ntdll-Strip-the-wine-prefix-from-reparse-point-paths.patch
|
||||
patch_apply ntdll-Junction_Points/0037-ntdll-Add-a-marker-to-reparse-point-paths-to-indicat.patch
|
||||
patch_apply ntdll-Junction_Points/0038-server-Rewrite-absolute-reparse-point-targets-if-the.patch
|
||||
patch_apply ntdll-Junction_Points/0035-ntdll-Treat-undecoded-unix-symlinks-as-WSL-Linux-Uni.patch
|
||||
patch_apply ntdll-Junction_Points/0036-ntdll-Add-support-for-creating-Unix-Linux-symlinks.patch
|
||||
patch_apply ntdll-Junction_Points/0037-ntdll-Strip-the-wine-prefix-from-reparse-point-paths.patch
|
||||
patch_apply ntdll-Junction_Points/0038-ntdll-Add-a-marker-to-reparse-point-paths-to-indicat.patch
|
||||
patch_apply ntdll-Junction_Points/0039-server-Rewrite-absolute-reparse-point-targets-if-the.patch
|
||||
fi
|
||||
|
||||
# Patchset server-Key_State
|
||||
|
Loading…
Reference in New Issue
Block a user