mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Updated ntdll-Junction_Points patchset
This commit is contained in:
parent
992845eae7
commit
082a898ad4
@ -1,4 +1,4 @@
|
||||
From 935694ac40ed4b264ef0ede519bd8b9b2f1f28de Mon Sep 17 00:00:00 2001
|
||||
From 78f4401a1e5d50097be8dd8458273ef1d4a548a7 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Tue, 19 Aug 2014 22:10:49 -0600
|
||||
Subject: [PATCH] ntdll: Implement retrieving DOS attributes in
|
||||
@ -6,15 +6,15 @@ Subject: [PATCH] ntdll: Implement retrieving DOS attributes in
|
||||
|
||||
---
|
||||
configure.ac | 12 ++++++++++++
|
||||
dlls/ntdll/file.c | 22 +++++++++++++++++++++-
|
||||
dlls/ntdll/file.c | 16 ++++++++++++++++
|
||||
include/wine/port.h | 8 ++++++++
|
||||
libs/port/Makefile.in | 4 +++-
|
||||
libs/port/xattr.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 83 insertions(+), 2 deletions(-)
|
||||
5 files changed, 78 insertions(+), 1 deletion(-)
|
||||
create mode 100644 libs/port/xattr.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 1905733..6f0429e 100644
|
||||
index 9385d20..60d43d3 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -85,6 +85,7 @@ AC_ARG_WITH(udev, AS_HELP_STRING([--without-udev],[do not use udev (plug an
|
||||
@ -25,7 +25,7 @@ index 1905733..6f0429e 100644
|
||||
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
|
||||
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
|
||||
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
|
||||
@@ -698,6 +699,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
@@ -711,6 +712,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
#include <sys/socket.h>
|
||||
#endif])
|
||||
|
||||
@ -44,7 +44,7 @@ index 1905733..6f0429e 100644
|
||||
|
||||
AC_SUBST(DLLFLAGS,"-D_REENTRANT")
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index 919eaea..1ffa675 100644
|
||||
index b70477e..2c99c1d 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -127,6 +127,22 @@ static const WCHAR ntfsW[] = {'N','T','F','S'};
|
||||
@ -70,24 +70,6 @@ index 919eaea..1ffa675 100644
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
{
|
||||
@@ -144,12 +160,16 @@ static inline ULONG get_file_attributes( const struct stat *st )
|
||||
/* get the stat info and file attributes for a file (by file descriptor) */
|
||||
int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
|
||||
{
|
||||
- int ret;
|
||||
+ char hexattr[11];
|
||||
+ int len, ret;
|
||||
|
||||
*attr = 0;
|
||||
ret = fstat( fd, st );
|
||||
if (ret == -1) return ret;
|
||||
*attr |= get_file_attributes( st );
|
||||
+ len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
|
||||
+ if (len == -1) return ret;
|
||||
+ *attr |= get_file_xattr( hexattr, len );
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 19c8682..eaa23bc 100644
|
||||
--- a/include/wine/port.h
|
||||
|
@ -1,7 +1,8 @@
|
||||
From c65dec8465c321f09ee3bfd0317994da8cd0c0c1 Mon Sep 17 00:00:00 2001
|
||||
From 347997c4118fa01fbf87cf7cadb6ba04a83a97c4 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 20 Aug 2014 00:08:52 -0600
|
||||
Subject: ntdll: Implement storing DOS attributes in NtSetInformationFile.
|
||||
Subject: [PATCH] ntdll: Implement storing DOS attributes in
|
||||
NtSetInformationFile.
|
||||
|
||||
---
|
||||
dlls/ntdll/file.c | 54 +++++++++++++++++++++++++++++++------------------
|
||||
@ -11,11 +12,11 @@ Subject: ntdll: Implement storing DOS attributes in NtSetInformationFile.
|
||||
4 files changed, 60 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index b977e45..521ab64 100644
|
||||
index 6743d37..12d47ae 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -149,6 +149,39 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
|
||||
return ret;
|
||||
@@ -157,6 +157,39 @@ static inline ULONG get_file_attributes( const struct stat *st )
|
||||
return attr;
|
||||
}
|
||||
|
||||
+/* set the stat info and file attributes for a file (by file descriptor) */
|
||||
@ -54,7 +55,7 @@ index b977e45..521ab64 100644
|
||||
/* get the stat info and file attributes for a file (by name) */
|
||||
int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
{
|
||||
@@ -2320,7 +2353,6 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
@@ -3097,7 +3130,6 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
case FileBasicInformation:
|
||||
if (len >= sizeof(FILE_BASIC_INFORMATION))
|
||||
{
|
||||
@ -62,7 +63,7 @@ index b977e45..521ab64 100644
|
||||
const FILE_BASIC_INFORMATION *info = ptr;
|
||||
|
||||
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||
@@ -2330,25 +2362,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
@@ -3107,25 +3139,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
io->u.Status = set_file_times( fd, &info->LastWriteTime, &info->LastAccessTime );
|
||||
|
||||
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)
|
||||
@ -90,10 +91,10 @@ index b977e45..521ab64 100644
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index d70ed6b..7a8e5d4 100644
|
||||
index d0646aa..39f9013 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -1234,7 +1234,7 @@ static void test_file_basic_information(void)
|
||||
@@ -1341,7 +1341,7 @@ static void test_file_basic_information(void)
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
|
||||
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
|
||||
@ -102,7 +103,7 @@ index d70ed6b..7a8e5d4 100644
|
||||
|
||||
/* Then HIDDEN */
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
@@ -1247,7 +1247,7 @@ static void test_file_basic_information(void)
|
||||
@@ -1354,7 +1354,7 @@ static void test_file_basic_information(void)
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
|
||||
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
|
||||
@ -111,7 +112,7 @@ index d70ed6b..7a8e5d4 100644
|
||||
|
||||
/* Check NORMAL last of all (to make sure we can clear attributes) */
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
@@ -1304,7 +1304,7 @@ static void test_file_all_information(void)
|
||||
@@ -1411,7 +1411,7 @@ static void test_file_all_information(void)
|
||||
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
|
||||
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
|
||||
ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
|
||||
@ -120,7 +121,7 @@ index d70ed6b..7a8e5d4 100644
|
||||
|
||||
/* Then HIDDEN */
|
||||
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
|
||||
@@ -1317,7 +1317,7 @@ static void test_file_all_information(void)
|
||||
@@ -1424,7 +1424,7 @@ static void test_file_all_information(void)
|
||||
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
|
||||
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
|
||||
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
|
||||
@ -130,10 +131,10 @@ index d70ed6b..7a8e5d4 100644
|
||||
/* Check NORMAL last of all (to make sure we can clear attributes) */
|
||||
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 7977eb9..cc572f3 100644
|
||||
index de6b995..c075958 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -370,6 +370,8 @@ extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
|
||||
@@ -351,6 +351,8 @@ extern int mkstemps(char *template, int suffix_len);
|
||||
#endif
|
||||
|
||||
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 87bbbc7d6c67c2ec3e13f84a7eecccb71e486ac0 Mon Sep 17 00:00:00 2001
|
||||
From 589bbdea7af00507d3dce26feec1c6db1d8e9746 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: ntdll: Add support for junction point creation.
|
||||
@ -18,10 +18,10 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
create mode 100644 libs/port/renameat2.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d1502bacf7..84307f0f54 100644
|
||||
index 0ad8417735..39a9571a95 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2207,6 +2207,8 @@ AC_CHECK_FUNCS(\
|
||||
@@ -2206,6 +2206,8 @@ AC_CHECK_FUNCS(\
|
||||
pwrite \
|
||||
readdir \
|
||||
readlink \
|
||||
@ -305,10 +305,10 @@ index 8e54dbb541..322dadefe3 100644
|
||||
+ test_reparse_points();
|
||||
}
|
||||
diff --git a/include/Makefile.in b/include/Makefile.in
|
||||
index 4a0f927082..519a34c856 100644
|
||||
index 979695f552..2a1382e811 100644
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -480,6 +480,7 @@ SOURCES = \
|
||||
@@ -482,6 +482,7 @@ SOURCES = \
|
||||
ntddvdeo.h \
|
||||
ntdef.h \
|
||||
ntdsapi.h \
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 38245bc3099137dd16dc78e3f41c6d50b7f0f804 Mon Sep 17 00:00:00 2001
|
||||
From 56730d38b6326cee609916af394a37d4559d249e 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: ntdll: Add support for reading junction points.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 9f0a95668d86bacd6cd006e6fe6c6d463cfb5e9b Mon Sep 17 00:00:00 2001
|
||||
From 424814c370108dcad48290dc203adff96672dea9 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: ntdll: Add support for deleting junction points.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 52fb88dc16f22188dd2b3800fc1cd0034dbd118e Mon Sep 17 00:00:00 2001
|
||||
From 3e60e844c4ce938fb12ff09d561967a75e110f82 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: ntdll: Add a test for junction point advertisement.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From db064094e068f3e6434f4b4302c5b2eadf8395ef Mon Sep 17 00:00:00 2001
|
||||
From f0ac5c57f3a0c2ddb542ed1cc1e78513ad4a60fe 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: kernel32,ntdll: Add support for deleting junction points with
|
||||
|
@ -1,4 +1,4 @@
|
||||
From aa5ad3e25315a3ca2113df9a80e178fdfef58296 Mon Sep 17 00:00:00 2001
|
||||
From 944851b4f7cda627c3c35a6735f14121b87d0148 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 21:03:47 -0700
|
||||
Subject: kernel32: Advertise junction point support.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
1 file changed, 84 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
|
||||
index 12084369cb..76bb32b850 100644
|
||||
index 4fd913aa22..437832e5c9 100644
|
||||
--- a/dlls/kernel32/volume.c
|
||||
+++ b/dlls/kernel32/volume.c
|
||||
@@ -44,6 +44,19 @@
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 8547ee103b062ae2c8e1a5fd058ea3e9dc8a2146 Mon Sep 17 00:00:00 2001
|
||||
From 7183c92e5f02346e8d72432a602fb7dfc3659a5b 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: ntdll: Add support for absolute symlink creation.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b9fa01baf73dc3975bd56b9b0ce0d26eddb45e81 Mon Sep 17 00:00:00 2001
|
||||
From d3129f74304e5fa5ba33eb51bd4ef1e9bfce1b8f 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: ntdll: Add support for reading absolute symlinks.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 90921ac6aba0f98fb9b33104c82d77e07cc82278 Mon Sep 17 00:00:00 2001
|
||||
From 9bc86ef7b245595248c0f5b157c9a57f4ce0c8aa 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: ntdll: Add support for deleting symlinks.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 4cfe8631a57057a13afa650f41576c8c3ae465d5 Mon Sep 17 00:00:00 2001
|
||||
From 0879c8d8575ba4ff1b7e9f408679c4fb92468f62 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: ntdll: Add support for relative symlink creation.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From cdd6070ee2b8876877c66bfdaa44b4b152633b1d Mon Sep 17 00:00:00 2001
|
||||
From 7c02ce3203b8796455d12423b960b720e90a9639 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: ntdll: Add support for reading relative symlinks.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 05a16c210c3dabb07cc5b5514e9745f00fb364ea Mon Sep 17 00:00:00 2001
|
||||
From ac69cecc3f024819efae83723b77d9f310b43251 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: ntdll: Add support for file symlinks.
|
||||
@ -92,7 +92,7 @@ index 5df2d8c3fa..03a07d46cd 100644
|
||||
lchown( tmpfile, st.st_uid, st.st_gid );
|
||||
/* Atomically move the directory into position */
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index c13ee84bf0..f40dc1f51b 100644
|
||||
index c13ee84bf0..5bf8ebf704 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5050,6 +5050,39 @@ static void test_reparse_points(void)
|
||||
@ -106,7 +106,7 @@ index c13ee84bf0..f40dc1f51b 100644
|
||||
+ 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());
|
||||
+ win_skip("Failed to open symlink file handle (0x%x).\n", GetLastError());
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
|
||||
|
@ -0,0 +1,68 @@
|
||||
From 1cb09e87cf0fd0a805849f3483d2b3b7bed5ec18 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: ntdll: Allow creation of dangling reparse points to non-existent
|
||||
paths.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/directory.c | 14 ++++++++++++++
|
||||
dlls/ntdll/file.c | 3 ++-
|
||||
include/winternl.h | 1 +
|
||||
3 files changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
|
||||
index bbdbbe9781..cca1e3c4a8 100644
|
||||
--- a/dlls/ntdll/directory.c
|
||||
+++ b/dlls/ntdll/directory.c
|
||||
@@ -2705,6 +2705,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)
|
||||
+ {
|
||||
+ ret = ntdll_wcstoumbs( 0, name, end - name, unix_name + pos + 1,
|
||||
+ MAX_DIR_ENTRY_LEN, NULL, &used_default );
|
||||
+ if (ret > 0 && !used_default)
|
||||
+ {
|
||||
+ unix_name[pos] = '/';
|
||||
+ unix_name[pos + 1 + ret] = 0;
|
||||
+ status = STATUS_NO_SUCH_FILE;
|
||||
+ pos += strlen( unix_name + pos );
|
||||
+ name = next;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (status != STATUS_SUCCESS) break;
|
||||
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index 03a07d46cd..04d34dd572 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -1722,8 +1722,9 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
|
||||
RtlCreateUnicodeString( &nt_dest, dest );
|
||||
nt_dest.Length = dest_len;
|
||||
}
|
||||
+
|
||||
nt_dest_allocated = TRUE;
|
||||
- status = wine_nt_to_unix_file_name( &nt_dest, &unix_dest, 0, FALSE );
|
||||
+ status = wine_nt_to_unix_file_name( &nt_dest, &unix_dest, FILE_WINE_PATH, FALSE );
|
||||
if (status != STATUS_SUCCESS && status != STATUS_NO_SUCH_FILE)
|
||||
goto cleanup;
|
||||
dest_allocated = TRUE;
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index 2b3fb947b9..7f6b2f57ba 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -1788,6 +1788,7 @@ typedef struct _RTL_HANDLE_TABLE
|
||||
#define FILE_OVERWRITE 4
|
||||
#define FILE_OVERWRITE_IF 5
|
||||
#define FILE_MAXIMUM_DISPOSITION 5
|
||||
+#define FILE_WINE_PATH 6
|
||||
|
||||
/* Characteristics of a File System */
|
||||
#define FILE_REMOVABLE_MEDIA 0x00000001
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,16 +1,16 @@
|
||||
From 9c0229cf831240320ef2797dbfd21493d7871088 Mon Sep 17 00:00:00 2001
|
||||
From 20171f2a705fdf94966e9661d360ac70bb92cb8e 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: ntdll: Correctly report file symbolic links as files.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/file.c | 110 +++++++++++++++++++++++++++-------------
|
||||
dlls/ntdll/file.c | 118 ++++++++++++++++++++++++++--------------
|
||||
dlls/ntdll/tests/file.c | 8 +--
|
||||
2 files changed, 79 insertions(+), 39 deletions(-)
|
||||
2 files changed, 82 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index 03a07d46cd..8b78306fbf 100644
|
||||
index 04d34dd572..8336392ddb 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -124,6 +124,9 @@ mode_t FILE_umask = 0;
|
||||
@ -23,22 +23,25 @@ index 03a07d46cd..8b78306fbf 100644
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
{
|
||||
@@ -160,10 +163,14 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -160,10 +163,13 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
if (ret == -1) return ret;
|
||||
if (S_ISLNK( st->st_mode ))
|
||||
{
|
||||
- ret = stat( path, st );
|
||||
- if (ret == -1) return ret;
|
||||
- /* is a symbolic link and a directory, consider these "reparse points" */
|
||||
- if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
+ BOOL is_dir;
|
||||
+
|
||||
ret = stat( path, st );
|
||||
if (ret == -1) return ret;
|
||||
/* is a symbolic link and a directory, consider these "reparse points" */
|
||||
if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
+ if (FILE_DecodeSymlink( path, NULL, NULL, NULL, NULL, &is_dir) == STATUS_SUCCESS)
|
||||
+ /* 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)
|
||||
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
|
||||
}
|
||||
*attr |= get_file_attributes( st );
|
||||
return ret;
|
||||
@@ -1825,48 +1832,34 @@ cleanup:
|
||||
@@ -1826,48 +1832,33 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
@ -78,13 +81,13 @@ index 03a07d46cd..8b78306fbf 100644
|
||||
- unix_dest.MaximumLength = PATH_MAX;
|
||||
- dest_allocated = TRUE;
|
||||
- ret = readlink( unix_src.Buffer, unix_dest.Buffer, unix_dest.MaximumLength );
|
||||
- if (ret < 0)
|
||||
+ if (unix_dest_len) len = *unix_dest_len;
|
||||
+ if (!unix_dest)
|
||||
+ tmp = RtlAllocateHeap( GetProcessHeap(), 0, len );
|
||||
+ else
|
||||
+ tmp = unix_dest;
|
||||
+ ret = readlink( unix_src, tmp, len );
|
||||
if (ret < 0)
|
||||
+ if ((ret = readlink( unix_src, tmp, len )) < 0)
|
||||
{
|
||||
status = FILE_GetNtStatus();
|
||||
goto cleanup;
|
||||
@ -102,7 +105,7 @@ index 03a07d46cd..8b78306fbf 100644
|
||||
p++;
|
||||
}
|
||||
if (*p++ != '/')
|
||||
@@ -1874,7 +1867,7 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -1875,7 +1866,7 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -111,7 +114,7 @@ index 03a07d46cd..8b78306fbf 100644
|
||||
for (i = 0; i < sizeof(ULONG)*8; i++)
|
||||
{
|
||||
char c = *p++;
|
||||
@@ -1889,21 +1882,68 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
@@ -1890,21 +1881,68 @@ NTSTATUS FILE_GetSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG out_s
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -186,7 +189,7 @@ index 03a07d46cd..8b78306fbf 100644
|
||||
/* convert the relative path into an absolute path */
|
||||
if (flags == SYMLINK_FLAG_RELATIVE)
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index f40dc1f51b..f23bf8644c 100644
|
||||
index 5bf8ebf704..bacfad266e 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5069,13 +5069,13 @@ static void test_reparse_points(void)
|
@ -0,0 +1,137 @@
|
||||
From 4f8611e2dfc7fb70e13a6f05949257e5d441328a Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 1 May 2019 19:46:03 -0600
|
||||
Subject: ntdll: Correctly report fd-based file info for symlinks.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/file.c | 64 ++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 46 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index 8336392ddb..934577bfba 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -141,18 +141,6 @@ static inline ULONG get_file_attributes( const struct stat *st )
|
||||
return attr;
|
||||
}
|
||||
|
||||
-/* get the stat info and file attributes for a file (by file descriptor) */
|
||||
-int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- *attr = 0;
|
||||
- ret = fstat( fd, st );
|
||||
- if (ret == -1) return ret;
|
||||
- *attr |= get_file_attributes( st );
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
/* get the stat info and file attributes for a file (by name) */
|
||||
int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
{
|
||||
@@ -175,6 +163,46 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* get the stat info and file attributes for a file (by file descriptor) */
|
||||
+int fd_get_file_info( HANDLE h, int fd, struct stat *st, ULONG *attr )
|
||||
+{
|
||||
+ ANSI_STRING unix_src;
|
||||
+ struct stat tmp;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ /* if this handle is to a symlink then we need to return information about the symlink */
|
||||
+ if (server_get_unix_name( h, &unix_src ) != STATUS_SUCCESS)
|
||||
+ return ret;
|
||||
+ ret = get_file_info( unix_src.Buffer, st, attr);
|
||||
+ RtlFreeAnsiString( &unix_src );
|
||||
+ if (ret == -1) return ret;
|
||||
+ /* but return the times from the file itself */
|
||||
+ ret = fstat( fd, &tmp );
|
||||
+ if (ret == -1) return ret;
|
||||
+#if defined(HAVE_STRUCT_STAT_ST_ATIM)
|
||||
+ st->st_atim = tmp.st_atim;
|
||||
+#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
|
||||
+ st->st_atimespec = tmp.st_atimespec;
|
||||
+#else
|
||||
+ st->st_atime = tmp.st_atime;
|
||||
+#endif
|
||||
+#if defined(HAVE_STRUCT_STAT_ST_MTIM)
|
||||
+ st->st_mtim = tmp.st_mtim;
|
||||
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
||||
+ st->st_mtimespec = tmp.st_mtimespec;
|
||||
+#else
|
||||
+ st->st_mtime = tmp.st_mtime;
|
||||
+#endif
|
||||
+#if defined(HAVE_STRUCT_STAT_ST_CTIM)
|
||||
+ st->st_ctim = tmp.st_ctim;
|
||||
+#elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
|
||||
+ st->st_ctimespec = tmp.st_ctimespec;
|
||||
+#else
|
||||
+ st->st_ctime = tmp.st_ctime;
|
||||
+#endif
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/**************************************************************************
|
||||
* FILE_CreateFile (internal)
|
||||
* Open a file.
|
||||
@@ -2832,7 +2860,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
switch (class)
|
||||
{
|
||||
case FileBasicInformation:
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1)
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1)
|
||||
io->u.Status = FILE_GetNtStatus();
|
||||
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
@@ -2843,7 +2871,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
{
|
||||
FILE_STANDARD_INFORMATION *info = ptr;
|
||||
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
fill_file_info( &st, attr, info, class );
|
||||
@@ -2860,7 +2888,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
}
|
||||
break;
|
||||
case FileInternalInformation:
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else fill_file_info( &st, attr, ptr, class );
|
||||
break;
|
||||
case FileEaInformation:
|
||||
@@ -2870,7 +2898,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
}
|
||||
break;
|
||||
case FileEndOfFileInformation:
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else fill_file_info( &st, attr, ptr, class );
|
||||
break;
|
||||
case FileAllInformation:
|
||||
@@ -2878,7 +2906,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
FILE_ALL_INFORMATION *info = ptr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
|
||||
@@ -2986,7 +3014,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
}
|
||||
break;
|
||||
case FileIdInformation:
|
||||
- if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
+ if (fd_get_file_info( hFile, fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
FILE_ID_INFORMATION *info = ptr;
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,288 +0,0 @@
|
||||
From 99b54adfcc2740af27224957748f94a0e84b47c3 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: kernel32: Implement CreateSymbolicLink[A|W] with ntdll reparse
|
||||
points.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/kernel32/path.c | 124 +++++++++++++++++++++++++++++++++++--
|
||||
dlls/kernel32/tests/path.c | 94 ++++++++++++++++++++++++++++
|
||||
2 files changed, 214 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
|
||||
index f15b6dd68b..d96471e4c6 100644
|
||||
--- a/dlls/kernel32/path.c
|
||||
+++ b/dlls/kernel32/path.c
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "ntifs.h"
|
||||
|
||||
#include "kernel_private.h"
|
||||
#include "wine/unicode.h"
|
||||
@@ -2087,8 +2089,106 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str )
|
||||
*/
|
||||
BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags)
|
||||
{
|
||||
- FIXME("(%s %s %d): stub\n", debugstr_w(link), debugstr_w(target), flags);
|
||||
- return TRUE;
|
||||
+ static INT struct_size = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]);
|
||||
+ static INT header_size = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer);
|
||||
+ INT buffer_size, data_size, string_len, prefix_len;
|
||||
+ WCHAR *subst_dest, *print_dest, *string;
|
||||
+ REPARSE_DATA_BUFFER *buffer;
|
||||
+ LPWSTR target_path = NULL;
|
||||
+ BOOL is_relative, is_dir;
|
||||
+ int target_path_len = 0;
|
||||
+ UNICODE_STRING nt_name;
|
||||
+ BOOLEAN bret = FALSE;
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE hlink;
|
||||
+ DWORD dwret;
|
||||
+
|
||||
+ TRACE("(%s %s %d)\n", debugstr_w(link), debugstr_w(target), flags);
|
||||
+
|
||||
+ is_relative = (RtlDetermineDosPathNameType_U( target ) == RELATIVE_PATH);
|
||||
+ is_dir = (flags & SYMBOLIC_LINK_FLAG_DIRECTORY);
|
||||
+ if (is_dir && !CreateDirectoryW( link, NULL ))
|
||||
+ return FALSE;
|
||||
+ hlink = CreateFileW( link, GENERIC_READ | GENERIC_WRITE, 0, 0,
|
||||
+ is_dir ? OPEN_EXISTING : CREATE_NEW,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0 );
|
||||
+ if (hlink == INVALID_HANDLE_VALUE)
|
||||
+ goto cleanup;
|
||||
+ if (is_relative)
|
||||
+ {
|
||||
+ UNICODE_STRING nt_path;
|
||||
+ int len;
|
||||
+
|
||||
+ status = RtlDosPathNameToNtPathName_U_WithStatus( link, &nt_path, NULL, NULL );
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ {
|
||||
+ SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ /* obtain the path of the link */
|
||||
+ for (; nt_path.Length > 0; nt_path.Length -= sizeof(WCHAR))
|
||||
+ {
|
||||
+ WCHAR c = nt_path.Buffer[nt_path.Length/sizeof(WCHAR)];
|
||||
+ if (c == '/' || c == '\\')
|
||||
+ {
|
||||
+ nt_path.Length += sizeof(WCHAR);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ /* append the target to the link path */
|
||||
+ target_path_len = nt_path.Length / sizeof(WCHAR);
|
||||
+ len = target_path_len + (strlenW( target ) + 1);
|
||||
+ target_path = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR) );
|
||||
+ lstrcpynW( target_path, nt_path.Buffer, nt_path.Length );
|
||||
+ target_path[nt_path.Length/sizeof(WCHAR)] = 0;
|
||||
+ lstrcatW( target_path, target );
|
||||
+ RtlFreeUnicodeString( &nt_path );
|
||||
+ }
|
||||
+ else
|
||||
+ target_path = (LPWSTR)target;
|
||||
+ status = RtlDosPathNameToNtPathName_U_WithStatus( target_path, &nt_name, NULL, NULL );
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ {
|
||||
+ SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (is_relative && strncmpW( target_path, nt_name.Buffer, target_path_len ) != 0)
|
||||
+ {
|
||||
+ SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ prefix_len = is_relative ? 0 : strlen("\\??\\");
|
||||
+ string = &nt_name.Buffer[target_path_len];
|
||||
+ string_len = lstrlenW( &string[prefix_len] );
|
||||
+ data_size = (prefix_len + 2 * string_len + 2) * sizeof(WCHAR);
|
||||
+ buffer_size = struct_size + data_size;
|
||||
+ buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size );
|
||||
+ buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
|
||||
+ buffer->ReparseDataLength = struct_size - header_size + data_size;
|
||||
+ 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);
|
||||
+ buffer->SymbolicLinkReparseBuffer.Flags = is_relative ? SYMLINK_FLAG_RELATIVE : 0;
|
||||
+ subst_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[0];
|
||||
+ print_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[prefix_len + string_len + 1];
|
||||
+ lstrcpyW( subst_dest, string );
|
||||
+ lstrcpyW( print_dest, &string[prefix_len] );
|
||||
+ RtlFreeUnicodeString( &nt_name );
|
||||
+ bret = DeviceIoControl( hlink, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_size, NULL, 0,
|
||||
+ &dwret, 0 );
|
||||
+ CloseHandle( hlink );
|
||||
+ HeapFree( GetProcessHeap(), 0, buffer );
|
||||
+
|
||||
+cleanup:
|
||||
+ if (!bret)
|
||||
+ {
|
||||
+ if (is_dir)
|
||||
+ RemoveDirectoryW( link );
|
||||
+ else
|
||||
+ DeleteFileW( link );
|
||||
+ }
|
||||
+ if (is_relative) HeapFree( GetProcessHeap(), 0, target_path );
|
||||
+ return bret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -2096,8 +2196,24 @@ BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags)
|
||||
*/
|
||||
BOOLEAN WINAPI CreateSymbolicLinkA(LPCSTR link, LPCSTR target, DWORD flags)
|
||||
{
|
||||
- FIXME("(%s %s %d): stub\n", debugstr_a(link), debugstr_a(target), flags);
|
||||
- return TRUE;
|
||||
+ WCHAR *targetW, *linkW;
|
||||
+ BOOL ret;
|
||||
+
|
||||
+ TRACE("(%s %s %d)\n", debugstr_a(link), debugstr_a(target), flags);
|
||||
+
|
||||
+ if (!(linkW = FILE_name_AtoW( link, TRUE )))
|
||||
+ {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ if (!(targetW = FILE_name_AtoW( target, TRUE )))
|
||||
+ {
|
||||
+ HeapFree( GetProcessHeap(), 0, linkW );
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ ret = CreateSymbolicLinkW( linkW, targetW, flags );
|
||||
+ HeapFree( GetProcessHeap(), 0, linkW );
|
||||
+ HeapFree( GetProcessHeap(), 0, targetW );
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c
|
||||
index 0a03225120..076333b3b1 100644
|
||||
--- a/dlls/kernel32/tests/path.c
|
||||
+++ b/dlls/kernel32/tests/path.c
|
||||
@@ -81,6 +81,9 @@ static void (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
static BOOL (WINAPI *pCheckNameLegalDOS8Dot3W)(const WCHAR *, char *, DWORD, BOOL *, BOOL *);
|
||||
static BOOL (WINAPI *pCheckNameLegalDOS8Dot3A)(const char *, char *, DWORD, BOOL *, BOOL *);
|
||||
|
||||
+/* Present in Vista+ */
|
||||
+static BOOL (WINAPI *pCreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
|
||||
+
|
||||
/* a structure to deal with wine todos somewhat cleanly */
|
||||
typedef struct {
|
||||
DWORD shortlen;
|
||||
@@ -2179,6 +2182,7 @@ static void init_pointers(void)
|
||||
MAKEFUNC(ReleaseActCtx);
|
||||
MAKEFUNC(CheckNameLegalDOS8Dot3W);
|
||||
MAKEFUNC(CheckNameLegalDOS8Dot3A);
|
||||
+ MAKEFUNC(CreateSymbolicLinkW);
|
||||
#undef MAKEFUNC
|
||||
}
|
||||
|
||||
@@ -2435,6 +2439,95 @@ static void test_SetSearchPathMode(void)
|
||||
RemoveDirectoryA( dir );
|
||||
}
|
||||
|
||||
+static void test_CreateSymbolicLink(void)
|
||||
+{
|
||||
+ static const WCHAR target_fileW[] = {'t','a','r','g','e','t','_','f','i','l','e',0};
|
||||
+ static const WCHAR target_dirW[] = {'t','a','r','g','e','t','_','d','i','r',0};
|
||||
+ static const WCHAR linkW[] = {'l','i','n','k',0};
|
||||
+ static const WCHAR fooW[] = {'f','o','o',0};
|
||||
+ static WCHAR volW[] = {'c',':','\\',0};
|
||||
+ static const WCHAR dotW[] = {'.',0};
|
||||
+ WCHAR path[MAX_PATH], old_path[MAX_PATH], tmp[MAX_PATH];
|
||||
+ DWORD dwLen, dwFlags;
|
||||
+ TOKEN_PRIVILEGES tp;
|
||||
+ HANDLE token;
|
||||
+ LUID luid;
|
||||
+ BOOL bret;
|
||||
+ HANDLE h;
|
||||
+
|
||||
+ if (!pCreateSymbolicLinkW)
|
||||
+ {
|
||||
+ win_skip( "CreateSymbolicLink isn't available\n" );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Create a temporary folder for the symlink tests */
|
||||
+ GetTempFileNameW( dotW, fooW, 0, path );
|
||||
+ DeleteFileW( path );
|
||||
+ if (!CreateDirectoryW( path, NULL ))
|
||||
+ {
|
||||
+ win_skip("Unable to create a temporary junction point directory.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ GetCurrentDirectoryW( sizeof(old_path)/sizeof(WCHAR), old_path );
|
||||
+ SetCurrentDirectoryW( path );
|
||||
+
|
||||
+ /* Check that the volume this folder is located on supports reparse points */
|
||||
+ GetFullPathNameW( path, sizeof(tmp)/sizeof(WCHAR), tmp, NULL );
|
||||
+ volW[0] = tmp[0];
|
||||
+ GetVolumeInformationW( volW, 0, 0, 0, &dwLen, &dwFlags, 0, 0 );
|
||||
+ if (!(dwFlags & FILE_SUPPORTS_REPARSE_POINTS))
|
||||
+ {
|
||||
+ skip("File system does not support junction points.\n");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* Establish permissions for symlink creation */
|
||||
+ bret = OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &token );
|
||||
+ ok(bret, "OpenProcessToken failed: %u\n", GetLastError());
|
||||
+ bret = LookupPrivilegeValueA( NULL, "SeCreateSymbolicLinkPrivilege", &luid );
|
||||
+ todo_wine ok(bret || broken(!bret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE) /* winxp */,
|
||||
+ "LookupPrivilegeValue failed: %u\n", GetLastError());
|
||||
+ if (bret)
|
||||
+ {
|
||||
+ tp.PrivilegeCount = 1;
|
||||
+ tp.Privileges[0].Luid = luid;
|
||||
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
+ bret = AdjustTokenPrivileges( token, FALSE, &tp, 0, NULL, NULL );
|
||||
+ ok(bret, "AdjustTokenPrivileges failed: %u\n", GetLastError());
|
||||
+ }
|
||||
+ if ((!bret && GetLastError() != ERROR_NO_SUCH_PRIVILEGE) || GetLastError() == ERROR_NOT_ALL_ASSIGNED)
|
||||
+ {
|
||||
+ win_skip("Insufficient permissions to perform symlink tests.\n");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* Create a destination folder and file for symlinks to target */
|
||||
+ bret = CreateDirectoryW( target_dirW, NULL );
|
||||
+ ok(bret, "Failed to create symlink target directory.\n");
|
||||
+ h = CreateFileW( target_fileW, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
+ ok(h != INVALID_HANDLE_VALUE, "Failed to create symlink target file.\n");
|
||||
+ CloseHandle( h );
|
||||
+
|
||||
+ /* Create a directory symbolic link */
|
||||
+ bret = CreateSymbolicLinkW( linkW, target_dirW, SYMBOLIC_LINK_FLAG_DIRECTORY );
|
||||
+ ok(bret, "Failed to create directory symbolic link! (0x%x)\n", GetLastError());
|
||||
+ bret = RemoveDirectoryW( linkW );
|
||||
+ ok(bret, "Failed to remove directory symbolic link! (0x%x)\n", GetLastError());
|
||||
+
|
||||
+ /* Create a file symbolic link */
|
||||
+ bret = CreateSymbolicLinkW( linkW, target_fileW, 0x0 );
|
||||
+ ok(bret, "Failed to create file symbolic link! (0x%x)\n", GetLastError());
|
||||
+ bret = DeleteFileW( linkW );
|
||||
+ ok(bret, "Failed to remove file symbolic link! (0x%x)\n", GetLastError());
|
||||
+
|
||||
+cleanup:
|
||||
+ DeleteFileW( target_fileW );
|
||||
+ RemoveDirectoryW( target_dirW );
|
||||
+ SetCurrentDirectoryW( old_path );
|
||||
+ RemoveDirectoryW( path );
|
||||
+}
|
||||
+
|
||||
START_TEST(path)
|
||||
{
|
||||
CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
|
||||
@@ -2469,4 +2562,5 @@ START_TEST(path)
|
||||
test_GetFullPathNameW();
|
||||
test_CheckNameLegalDOS8Dot3();
|
||||
test_SetSearchPathMode();
|
||||
+ test_CreateSymbolicLink();
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From e34db8f28e43091a02cccb2eb590f9beda9da059 Mon Sep 17 00:00:00 2001
|
||||
From 417a71fe5c16121c85bf59c13f610ebcdf701508 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Sat, 30 Mar 2019 12:01:50 -0600
|
||||
Subject: kernel32: Set error code when attempting to delete file symlinks as
|
||||
@ -27,7 +27,7 @@ index 76a9512c77..f15b6dd68b 100644
|
||||
}
|
||||
else
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index f23bf8644c..a1323ab4f6 100644
|
||||
index bacfad266e..2f5ee0618c 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5071,9 +5071,9 @@ static void test_reparse_points(void)
|
@ -1,4 +1,4 @@
|
||||
From 245f8c8ad1d014bbf726020fd4c37c99e8bcafea Mon Sep 17 00:00:00 2001
|
||||
From 160758d1973e49d5bb9d76d203fe1d0a8f676240 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: server: Properly handle file symlink deletion.
|
||||
@ -6,11 +6,11 @@ Subject: server: Properly handle file symlink deletion.
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 6 ++--
|
||||
server/fd.c | 64 +++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 62 insertions(+), 8 deletions(-)
|
||||
server/fd.c | 75 ++++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 73 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index a1323ab4f6..8ab8a5da53 100644
|
||||
index 2f5ee0618c..5f42ad5e0b 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -5080,14 +5080,14 @@ static void test_reparse_points(void)
|
||||
@ -32,10 +32,21 @@ index a1323ab4f6..8ab8a5da53 100644
|
||||
/* Create the directory symlink */
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 5d80e218b9..71347e4318 100644
|
||||
index 5d80e218b9..e74fef6a19 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -1069,7 +1069,7 @@ static void inode_destroy( struct object *obj )
|
||||
@@ -105,6 +105,10 @@
|
||||
#include "winternl.h"
|
||||
#include "winioctl.h"
|
||||
|
||||
+#if !defined(O_SYMLINK) && defined(O_PATH)
|
||||
+# define O_SYMLINK (O_NOFOLLOW | O_PATH)
|
||||
+#endif
|
||||
+
|
||||
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL_CREATE)
|
||||
# include <sys/epoll.h>
|
||||
# define USE_EPOLL
|
||||
@@ -1069,7 +1073,7 @@ static void inode_destroy( struct object *obj )
|
||||
{
|
||||
/* make sure it is still the same file */
|
||||
struct stat st;
|
||||
@ -44,7 +55,7 @@ index 5d80e218b9..71347e4318 100644
|
||||
{
|
||||
if (S_ISDIR(st.st_mode)) rmdir( fd->unix_name );
|
||||
else unlink( fd->unix_name );
|
||||
@@ -1747,6 +1747,53 @@ char *dup_fd_name( struct fd *root, const char *name )
|
||||
@@ -1747,6 +1751,53 @@ char *dup_fd_name( struct fd *root, const char *name )
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -98,7 +109,21 @@ index 5d80e218b9..71347e4318 100644
|
||||
/* open() wrapper that returns a struct fd with no fd user set */
|
||||
struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, unsigned int access,
|
||||
unsigned int sharing, unsigned int options )
|
||||
@@ -1826,14 +1873,15 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
@@ -1815,6 +1866,13 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
if ((access & FILE_UNIX_WRITE_ACCESS) || (flags & O_CREAT))
|
||||
fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode );
|
||||
}
|
||||
+#if defined(O_SYMLINK)
|
||||
+ /* if we tried to open a dangling symlink then try again with O_SYMLINK */
|
||||
+ else if (errno == ENOENT)
|
||||
+ {
|
||||
+ fd->unix_fd = open( name, rw_mode | O_SYMLINK | (flags & ~O_TRUNC), *mode );
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
if (fd->unix_fd == -1)
|
||||
{
|
||||
@@ -1826,14 +1884,15 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
closed_fd->unix_fd = fd->unix_fd;
|
||||
closed_fd->unlink = 0;
|
||||
closed_fd->unix_name = fd->unix_name;
|
||||
@ -116,7 +141,7 @@ index 5d80e218b9..71347e4318 100644
|
||||
|
||||
if (!inode)
|
||||
{
|
||||
@@ -1848,13 +1896,19 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
@@ -1848,13 +1907,19 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
list_add_head( &inode->open, &fd->inode_entry );
|
||||
closed_fd = NULL;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user