mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against 314368e6c442f043ebfc22b70c1113e4e6232c04.
This commit is contained in:
parent
285e594688
commit
1d149ff59d
@ -1,4 +1,4 @@
|
||||
From 83309ce4174bf56eef86e516221290b8d88bdc27 Mon Sep 17 00:00:00 2001
|
||||
From 9e66f8a5f7579f0e7ef97ab4df66f91d8d8c0949 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Thu, 1 Jun 2017 06:04:53 +0200
|
||||
Subject: [PATCH] ntdll: Fix holes in ELF mappings. (v2)
|
||||
@ -10,10 +10,10 @@ Based on a patch by Andrew Wesie.
|
||||
2 files changed, 36 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index cdc8e1189b3..1f73e72a952 100644
|
||||
index 253d5e31e3d..c518a4f8141 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -968,6 +968,16 @@ static inline BOOL is_write_watch_range( const void *addr, size_t size )
|
||||
@@ -1014,6 +1014,16 @@ static inline BOOL is_write_watch_range( const void *addr, size_t size )
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ index cdc8e1189b3..1f73e72a952 100644
|
||||
/***********************************************************************
|
||||
* find_view_range
|
||||
*
|
||||
@@ -2966,6 +2976,19 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
@@ -2985,6 +2995,19 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
/* ignore fault if page is writable now */
|
||||
if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||||
}
|
||||
@ -42,7 +42,7 @@ index cdc8e1189b3..1f73e72a952 100644
|
||||
+ mprotect_range( page, page_size, 0, 0 );
|
||||
+ if (!mincore( page, page_size, &vec ) && (vec & 1))
|
||||
+ ret = STATUS_SUCCESS;
|
||||
+ else if (wine_anon_mmap( page, page_size, unix_prot, MAP_FIXED ) == page)
|
||||
+ else if (anon_mmap_fixed( page, page_size, unix_prot, 0 ) == page)
|
||||
+ ret = STATUS_SUCCESS;
|
||||
+ else
|
||||
+ set_page_vprot_bits( page, page_size, 0, VPROT_READ | VPROT_EXEC );
|
||||
@ -51,7 +51,7 @@ index cdc8e1189b3..1f73e72a952 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
|
||||
index eb52fc690cf..178f5605a23 100644
|
||||
index d85099455aa..be12af58311 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -195,6 +195,7 @@ todo_wine
|
||||
@ -86,5 +86,5 @@ index eb52fc690cf..178f5605a23 100644
|
||||
|
||||
static BOOL check_with_margin(SIZE_T perf, SIZE_T sysperf, int margin)
|
||||
--
|
||||
2.27.0
|
||||
2.28.0
|
||||
|
||||
|
@ -1,23 +1,19 @@
|
||||
From f96ab0203c4119942b9d8ccc27207cc73389b375 Mon Sep 17 00:00:00 2001
|
||||
From 80247bc4566977f67a1851f46facba226fbd93df 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
|
||||
[fd_]get_file_info().
|
||||
|
||||
---
|
||||
configure.ac | 12 +++++++++++
|
||||
dlls/ntdll/unix/file.c | 22 ++++++++++++++++++-
|
||||
include/wine/port.h | 9 ++++++++
|
||||
libs/port/Makefile.in | 3 ++-
|
||||
libs/port/xattr.c | 49 ++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 93 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libs/port/xattr.c
|
||||
configure.ac | 12 ++++++++++++
|
||||
dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 50 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 4829648c3a5..cff2d4b8288 100644
|
||||
index f60cd593549..cca97ee403b 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -88,6 +88,7 @@ AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb lib
|
||||
@@ -89,6 +89,7 @@ AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb lib
|
||||
AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)]))
|
||||
AC_ARG_WITH(vkd3d, AS_HELP_STRING([--without-vkd3d],[do not use vkd3d (Direct3D 12 support)]))
|
||||
AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan]))
|
||||
@ -25,7 +21,7 @@ index 4829648c3a5..cff2d4b8288 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]),
|
||||
@@ -697,6 +698,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
@@ -698,6 +699,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
#include <sys/socket.h>
|
||||
#endif])
|
||||
|
||||
@ -44,10 +40,41 @@ index 4829648c3a5..cff2d4b8288 100644
|
||||
|
||||
AC_SUBST(DLLFLAGS,"-D_REENTRANT")
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index bf435f109f1..6ac9b18da57 100644
|
||||
index 03e92a5c59e..da8f65af7b3 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1448,6 +1448,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name,
|
||||
@@ -105,6 +105,9 @@
|
||||
#ifdef HAVE_SYS_STATFS_H
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
+#ifdef HAVE_ATTR_XATTR_H
|
||||
+#include <attr/xattr.h>
|
||||
+#endif
|
||||
#include <time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
@@ -369,6 +372,20 @@ NTSTATUS errno_to_status( int err )
|
||||
}
|
||||
}
|
||||
|
||||
+#ifndef XATTR_USER_PREFIX
|
||||
+#define XATTR_USER_PREFIX "user."
|
||||
+#endif
|
||||
+
|
||||
+static int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return getxattr( path, name, value, size );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
/* 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 )
|
||||
{
|
||||
@@ -1448,6 +1465,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name,
|
||||
}
|
||||
|
||||
|
||||
@ -70,7 +97,7 @@ index bf435f109f1..6ac9b18da57 100644
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
{
|
||||
@@ -1491,7 +1507,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
@@ -1491,7 +1524,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
{
|
||||
char *parent_path;
|
||||
@ -80,7 +107,7 @@ index bf435f109f1..6ac9b18da57 100644
|
||||
|
||||
*attr = 0;
|
||||
ret = lstat( path, st );
|
||||
@@ -1517,6 +1534,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
@@ -1517,6 +1551,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
free( parent_path );
|
||||
}
|
||||
*attr |= get_file_attributes( st );
|
||||
@ -90,92 +117,6 @@ index bf435f109f1..6ac9b18da57 100644
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 928730a41d7..4670891ae77 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -352,6 +352,15 @@ int usleep (unsigned int useconds);
|
||||
|
||||
extern int mkstemps(char *template, int suffix_len);
|
||||
|
||||
+/* Extended attribute functions */
|
||||
+
|
||||
+#ifndef XATTR_USER_PREFIX
|
||||
+# define XATTR_USER_PREFIX "user."
|
||||
+#endif
|
||||
+
|
||||
+extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
|
||||
+extern int xattr_get( const char *path, const char *name, void *value, size_t size );
|
||||
+
|
||||
#else /* NO_LIBWINE_PORT */
|
||||
|
||||
#define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable
|
||||
diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in
|
||||
index 7bc67fa3fee..d1de285d527 100644
|
||||
--- a/libs/port/Makefile.in
|
||||
+++ b/libs/port/Makefile.in
|
||||
@@ -21,4 +21,5 @@ C_SRCS = \
|
||||
strnlen.c \
|
||||
symlink.c \
|
||||
usleep.c \
|
||||
- wctype.c
|
||||
+ wctype.c \
|
||||
+ xattr.c
|
||||
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
|
||||
new file mode 100644
|
||||
index 00000000000..88e900dac6d
|
||||
--- /dev/null
|
||||
+++ b/libs/port/xattr.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * extended attributes functions
|
||||
+ *
|
||||
+ * Copyright 2014 Erich E. Hoover
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include "wine/port.h"
|
||||
+
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+# include <attr/xattr.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fgetxattr( filedes, name, value, size );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return getxattr( path, name, value, size );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
2.28.0
|
||||
|
||||
|
@ -1,21 +1,19 @@
|
||||
From b099458217b2855bd8615b8c97bcc2462eb74b25 Mon Sep 17 00:00:00 2001
|
||||
From 6bbf7676b4b7887a54f47b43929b8f3f1d7e77ae 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: [PATCH] ntdll: Implement storing DOS attributes in
|
||||
NtSetInformationFile.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 8 +++---
|
||||
dlls/ntdll/unix/file.c | 54 ++++++++++++++++++++++++++---------------
|
||||
include/wine/port.h | 2 ++
|
||||
libs/port/xattr.c | 20 +++++++++++++++
|
||||
4 files changed, 60 insertions(+), 24 deletions(-)
|
||||
dlls/ntdll/tests/file.c | 8 ++---
|
||||
dlls/ntdll/unix/file.c | 74 ++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 58 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 184b7cdad59..37e5ac5d8a5 100644
|
||||
index 8b9ec4f624d..6d2c8d2fc94 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -1364,7 +1364,7 @@ static void test_file_basic_information(void)
|
||||
@@ -1389,7 +1389,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");
|
||||
@ -24,7 +22,7 @@ index 184b7cdad59..37e5ac5d8a5 100644
|
||||
|
||||
/* Then HIDDEN */
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
@@ -1377,7 +1377,7 @@ static void test_file_basic_information(void)
|
||||
@@ -1402,7 +1402,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");
|
||||
@ -33,7 +31,7 @@ index 184b7cdad59..37e5ac5d8a5 100644
|
||||
|
||||
/* Check NORMAL last of all (to make sure we can clear attributes) */
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
@@ -1434,7 +1434,7 @@ static void test_file_all_information(void)
|
||||
@@ -1459,7 +1459,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);
|
||||
@ -42,7 +40,7 @@ index 184b7cdad59..37e5ac5d8a5 100644
|
||||
|
||||
/* Then HIDDEN */
|
||||
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
|
||||
@@ -1447,7 +1447,7 @@ static void test_file_all_information(void)
|
||||
@@ -1472,7 +1472,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");
|
||||
@ -52,10 +50,37 @@ index 184b7cdad59..37e5ac5d8a5 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/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 70a76ca81ee..924d06b2caa 100644
|
||||
index da8f65af7b3..0a326a7a1bd 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -1497,6 +1497,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
@@ -376,6 +376,26 @@ NTSTATUS errno_to_status( int err )
|
||||
#define XATTR_USER_PREFIX "user."
|
||||
#endif
|
||||
|
||||
+static int xattr_fremove( int filedes, const char *name )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fremovexattr( filedes, name );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fsetxattr( filedes, name, value, size, 0 );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
{
|
||||
#if defined(HAVE_ATTR_XATTR_H)
|
||||
@@ -1520,6 +1540,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +120,7 @@ index 70a76ca81ee..924d06b2caa 100644
|
||||
/* get the stat info and file attributes for a file (by name) */
|
||||
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
{
|
||||
@@ -4000,7 +4033,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4139,7 +4192,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
case FileBasicInformation:
|
||||
if (len >= sizeof(FILE_BASIC_INFORMATION))
|
||||
{
|
||||
@ -103,7 +128,7 @@ index 70a76ca81ee..924d06b2caa 100644
|
||||
const FILE_BASIC_INFORMATION *info = ptr;
|
||||
LARGE_INTEGER mtime, atime;
|
||||
|
||||
@@ -4014,25 +4046,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
@@ -4153,25 +4205,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
io->u.Status = set_file_times( fd, &mtime, &atime );
|
||||
|
||||
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)
|
||||
@ -130,50 +155,6 @@ index 70a76ca81ee..924d06b2caa 100644
|
||||
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 4670891ae77..e0249b4c59f 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -359,6 +359,8 @@ extern int mkstemps(char *template, int suffix_len);
|
||||
#endif
|
||||
|
||||
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
|
||||
+extern int xattr_fremove( int filedes, const char *name );
|
||||
+extern int xattr_fset( int filedes, const char *name, void *value, size_t size );
|
||||
extern int xattr_get( const char *path, const char *name, void *value, size_t size );
|
||||
|
||||
#else /* NO_LIBWINE_PORT */
|
||||
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
|
||||
index 88e900dac6d..6918c9956cc 100644
|
||||
--- a/libs/port/xattr.c
|
||||
+++ b/libs/port/xattr.c
|
||||
@@ -38,6 +38,26 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
#endif
|
||||
}
|
||||
|
||||
+int xattr_fremove( int filedes, const char *name )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fremovexattr( filedes, name );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fsetxattr( filedes, name, value, size, 0 );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
{
|
||||
#if defined(HAVE_ATTR_XATTR_H)
|
||||
--
|
||||
2.27.0
|
||||
2.28.0
|
||||
|
||||
|
@ -1,17 +1,15 @@
|
||||
From 29333aaab5e4d2b62741a8321382b24f1630eb70 Mon Sep 17 00:00:00 2001
|
||||
From 92aeb076183fd7311b5fa05b33af0304d897361d Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 20 Aug 2014 15:28:00 -0600
|
||||
Subject: [PATCH] ntdll: Implement storing DOS attributes in NtCreateFile.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/directory.c | 24 +++++++++++-------------
|
||||
dlls/ntdll/unix/file.c | 31 ++++++++++++++++++++++++++-----
|
||||
include/wine/port.h | 2 ++
|
||||
libs/port/xattr.c | 20 ++++++++++++++++++++
|
||||
4 files changed, 59 insertions(+), 18 deletions(-)
|
||||
dlls/ntdll/tests/directory.c | 24 ++++++++---------
|
||||
dlls/ntdll/unix/file.c | 51 ++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 57 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
|
||||
index 248ed99ab20..e0f4debc624 100644
|
||||
index d21a2e64f8e..dc4f09729ac 100644
|
||||
--- a/dlls/ntdll/tests/directory.c
|
||||
+++ b/dlls/ntdll/tests/directory.c
|
||||
@@ -55,7 +55,6 @@ static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *
|
||||
@ -60,10 +58,37 @@ index 248ed99ab20..e0f4debc624 100644
|
||||
}
|
||||
testfiles[i].nfound++;
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 7ab1c130bf2..7c737edd22c 100644
|
||||
index 0a326a7a1bd..a72d95f8378 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -3549,6 +3549,20 @@ void CDECL set_show_dot_files( BOOL enable )
|
||||
@@ -406,6 +406,26 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
|
||||
#endif
|
||||
}
|
||||
|
||||
+static int xattr_remove( const char *path, const char *name )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return removexattr( path, name );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int xattr_set( const char *path, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return setxattr( path, name, value, size, 0 );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
/* 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 )
|
||||
{
|
||||
@@ -3582,6 +3602,20 @@ void CDECL set_show_dot_files( BOOL enable )
|
||||
show_dot_files = enable;
|
||||
}
|
||||
|
||||
@ -84,7 +109,7 @@ index 7ab1c130bf2..7c737edd22c 100644
|
||||
|
||||
/******************************************************************************
|
||||
* open_unix_file
|
||||
@@ -3636,13 +3650,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
@@ -3669,13 +3703,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
io->u.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -104,7 +129,7 @@ index 7ab1c130bf2..7c737edd22c 100644
|
||||
|
||||
if (io->u.Status == STATUS_SUCCESS)
|
||||
{
|
||||
@@ -3664,6 +3679,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
@@ -3697,6 +3732,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
io->Information = FILE_OVERWRITTEN;
|
||||
break;
|
||||
}
|
||||
@ -116,7 +141,7 @@ index 7ab1c130bf2..7c737edd22c 100644
|
||||
}
|
||||
else if (io->u.Status == STATUS_TOO_MANY_OPENED_FILES)
|
||||
{
|
||||
@@ -3671,6 +3691,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
@@ -3704,6 +3744,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||
if (!once++) ERR_(winediag)( "Too many open files, ulimit -n probably needs to be increased\n" );
|
||||
}
|
||||
|
||||
@ -124,47 +149,6 @@ index 7ab1c130bf2..7c737edd22c 100644
|
||||
return io->u.Status;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index e0249b4c59f..930efeeea1f 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -362,6 +362,8 @@ extern int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
extern int xattr_fremove( int filedes, const char *name );
|
||||
extern int xattr_fset( int filedes, const char *name, void *value, size_t size );
|
||||
extern int xattr_get( const char *path, const char *name, void *value, size_t size );
|
||||
+extern int xattr_remove( const char *path, const char *name );
|
||||
+extern int xattr_set( const char *path, const char *name, void *value, size_t size );
|
||||
|
||||
#else /* NO_LIBWINE_PORT */
|
||||
|
||||
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
|
||||
index 6918c9956cc..683e7a615e2 100644
|
||||
--- a/libs/port/xattr.c
|
||||
+++ b/libs/port/xattr.c
|
||||
@@ -67,3 +67,23 @@ int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
+
|
||||
+int xattr_remove( const char *path, const char *name )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return removexattr( path, name );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+int xattr_set( const char *path, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ return setxattr( path, name, value, size, 0 );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
2.28.0
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
From f083b503de5dd5ae1805e633e191532a10896eab Mon Sep 17 00:00:00 2001
|
||||
From 65442c83060ee1980900cc5fe38978ef8c29eba4 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Mon, 6 Oct 2014 14:21:11 -0600
|
||||
Subject: libport: Add support for Mac OS X style extended attributes.
|
||||
Subject: [PATCH] libport: Add support for Mac OS X style extended attributes.
|
||||
|
||||
---
|
||||
configure.ac | 3 +++
|
||||
libs/port/xattr.c | 27 +++++++++++++++++++++------
|
||||
2 files changed, 24 insertions(+), 6 deletions(-)
|
||||
configure.ac | 3 +++
|
||||
dlls/ntdll/unix/file.c | 23 ++++++++++++++++++-----
|
||||
2 files changed, 21 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 3c91af3..68dca0a 100644
|
||||
index cca97ee403b..5e33bfacf91 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -671,6 +671,9 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
@@ -702,6 +702,9 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
if test "x$with_xattr" != "xno"
|
||||
then
|
||||
AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1])
|
||||
@ -22,35 +22,24 @@ index 3c91af3..68dca0a 100644
|
||||
fi
|
||||
if test "x$with_xattr" = "xyes"
|
||||
then
|
||||
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
|
||||
index 683e7a6..efc65c5 100644
|
||||
--- a/libs/port/xattr.c
|
||||
+++ b/libs/port/xattr.c
|
||||
@@ -22,7 +22,10 @@
|
||||
#include "wine/port.h"
|
||||
|
||||
#if defined(HAVE_ATTR_XATTR_H)
|
||||
+# undef XATTR_ADDITIONAL_OPTIONS
|
||||
# include <attr/xattr.h>
|
||||
+#elif defined(HAVE_SYS_XATTR_H)
|
||||
+# include <sys/xattr.h>
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index a72d95f8378..5e0ac914e1c 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -106,7 +106,10 @@
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
#ifdef HAVE_ATTR_XATTR_H
|
||||
+#undef XATTR_ADDITIONAL_OPTIONS
|
||||
#include <attr/xattr.h>
|
||||
+#elif defined(HAVE_SYS_XATTR_H)
|
||||
+#include <sys/xattr.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@@ -378,7 +381,9 @@ NTSTATUS errno_to_status( int err )
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -30,7 +33,9 @@
|
||||
|
||||
int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
+ return fgetxattr( filedes, name, value, size, 0, 0 );
|
||||
+#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return fgetxattr( filedes, name, value, size );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
@@ -40,7 +45,9 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
|
||||
int xattr_fremove( int filedes, const char *name )
|
||||
static int xattr_fremove( int filedes, const char *name )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@ -59,9 +48,9 @@ index 683e7a6..efc65c5 100644
|
||||
return fremovexattr( filedes, name );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
@@ -50,7 +57,9 @@ int xattr_fremove( int filedes, const char *name )
|
||||
@@ -388,7 +393,9 @@ static int xattr_fremove( int filedes, const char *name )
|
||||
|
||||
int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@ -70,9 +59,9 @@ index 683e7a6..efc65c5 100644
|
||||
return fsetxattr( filedes, name, value, size, 0 );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
@@ -60,7 +69,9 @@ int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
@@ -398,7 +405,9 @@ static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
|
||||
int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
static int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@ -81,9 +70,9 @@ index 683e7a6..efc65c5 100644
|
||||
return getxattr( path, name, value, size );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
@@ -70,7 +81,9 @@ int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
@@ -408,7 +417,9 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
|
||||
|
||||
int xattr_remove( const char *path, const char *name )
|
||||
static int xattr_remove( const char *path, const char *name )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@ -92,9 +81,9 @@ index 683e7a6..efc65c5 100644
|
||||
return removexattr( path, name );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
@@ -80,7 +93,9 @@ int xattr_remove( const char *path, const char *name )
|
||||
@@ -418,7 +429,9 @@ static int xattr_remove( const char *path, const char *name )
|
||||
|
||||
int xattr_set( const char *path, const char *name, void *value, size_t size )
|
||||
static int xattr_set( const char *path, const char *name, void *value, size_t size )
|
||||
{
|
||||
-#if defined(HAVE_ATTR_XATTR_H)
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@ -104,5 +93,5 @@ index 683e7a6..efc65c5 100644
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
--
|
||||
1.9.1
|
||||
2.28.0
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 64708643d4dc9454faaccd720ab9b8a53b5aecf9 Mon Sep 17 00:00:00 2001
|
||||
From f4caa19ffcac13201c0c9bd45d3d93d44cb24980 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Mon, 6 Oct 2014 14:26:24 -0600
|
||||
Subject: libport: Add support for FreeBSD style extended attributes.
|
||||
Subject: [PATCH] libport: Add support for FreeBSD style extended attributes.
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
libs/port/xattr.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 42 insertions(+), 1 deletion(-)
|
||||
configure.ac | 2 +-
|
||||
dlls/ntdll/unix/file.c | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 68dca0a..3b0da05 100644
|
||||
index 5e33bfacf91..aef00416461 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -670,7 +670,7 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
@@ -701,7 +701,7 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
|
||||
if test "x$with_xattr" != "xno"
|
||||
then
|
||||
@ -21,52 +21,11 @@ index 68dca0a..3b0da05 100644
|
||||
AC_CHECK_HEADERS(sys/xattr.h, [HAVE_XATTR=1]
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/xattr.h>]], [[getxattr("", "", "", 0, 0, 0);]])],
|
||||
[AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [Define if xattr functions take additional arguments (Mac OS X)])])])
|
||||
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
|
||||
index efc65c5..92a717e 100644
|
||||
--- a/libs/port/xattr.c
|
||||
+++ b/libs/port/xattr.c
|
||||
@@ -26,17 +26,40 @@
|
||||
# include <attr/xattr.h>
|
||||
#elif defined(HAVE_SYS_XATTR_H)
|
||||
# include <sys/xattr.h>
|
||||
+#elif defined(HAVE_SYS_EXTATTR_H)
|
||||
+# undef XATTR_ADDITIONAL_OPTIONS
|
||||
+# include <sys/extattr.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
+#ifndef XATTR_USER_PREFIX_LEN
|
||||
+# define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HAVE_SYS_EXTATTR_H
|
||||
+static inline int xattr_valid_namespace( const char *name )
|
||||
+{
|
||||
+ if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0)
|
||||
+ {
|
||||
+ errno = EPERM;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
{
|
||||
#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
return fgetxattr( filedes, name, value, size, 0, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return fgetxattr( filedes, name, value, size );
|
||||
+#elif defined(HAVE_SYS_EXTATTR_H)
|
||||
+ if (!xattr_valid_namespace( name )) return -1;
|
||||
+ return extattr_get_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
|
||||
+ value, size );
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -49,6 +72,9 @@ int xattr_fremove( int filedes, const char *name )
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 5e0ac914e1c..c4d5f9c9028 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -385,6 +385,9 @@ static int xattr_fremove( int filedes, const char *name )
|
||||
return fremovexattr( filedes, name, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return fremovexattr( filedes, name );
|
||||
@ -76,7 +35,7 @@ index efc65c5..92a717e 100644
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -61,6 +87,10 @@ int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
@@ -397,6 +400,10 @@ static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
return fsetxattr( filedes, name, value, size, 0, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return fsetxattr( filedes, name, value, size, 0 );
|
||||
@ -87,7 +46,7 @@ index efc65c5..92a717e 100644
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -73,6 +103,10 @@ int xattr_get( const char *path, const char *name, void *value, size_t size )
|
||||
@@ -409,6 +416,10 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
|
||||
return getxattr( path, name, value, size, 0, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return getxattr( path, name, value, size );
|
||||
@ -98,7 +57,7 @@ index efc65c5..92a717e 100644
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -85,6 +119,9 @@ int xattr_remove( const char *path, const char *name )
|
||||
@@ -421,6 +432,9 @@ static int xattr_remove( const char *path, const char *name )
|
||||
return removexattr( path, name, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return removexattr( path, name );
|
||||
@ -108,7 +67,7 @@ index efc65c5..92a717e 100644
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -97,6 +134,10 @@ int xattr_set( const char *path, const char *name, void *value, size_t size )
|
||||
@@ -433,6 +447,10 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si
|
||||
return setxattr( path, name, value, size, 0, 0 );
|
||||
#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
return setxattr( path, name, value, size, 0 );
|
||||
@ -120,5 +79,5 @@ index efc65c5..92a717e 100644
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
--
|
||||
1.9.1
|
||||
2.28.0
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
From 0e03dab87634938bf9b6462a3e7dce1def1289c9 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <gofmanp@gmail.com>
|
||||
From ff02cbe4aea411563e0a9d22ed832acc2747d5b7 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Tue, 14 Jan 2020 21:39:23 +0300
|
||||
Subject: [PATCH] ntdll: Increase step after failed map attempt in
|
||||
Subject: [PATCH 1/4] ntdll: Increase step after failed map attempt in
|
||||
try_map_free_area().
|
||||
|
||||
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 4b8942b1b53b..f4dba39cb160 100644
|
||||
index b469e9df4a1..52915e07323 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -1083,6 +1083,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
@@ -1080,6 +1080,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
step == 0)
|
||||
break;
|
||||
start = (char *)start + step;
|
@ -0,0 +1,29 @@
|
||||
From 01730a2261a59a2826a652360b69dd3c74917fa6 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Thu, 23 Jul 2020 18:40:39 +0300
|
||||
Subject: [PATCH] ntdll: Increase free ranges view block size on 64 bit.
|
||||
|
||||
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index f7eab895f58..54ad53ea088 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -183,7 +183,11 @@ static BYTE *pages_vprot;
|
||||
#endif
|
||||
|
||||
static struct file_view *view_block_start, *view_block_end, *next_free_view;
|
||||
+#ifdef _WIN64
|
||||
+static const size_t view_block_size = 0x200000;
|
||||
+#else
|
||||
static const size_t view_block_size = 0x100000;
|
||||
+#endif
|
||||
static void *preload_reserve_start;
|
||||
static void *preload_reserve_end;
|
||||
static BOOL force_exec_prot; /* whether to force PROT_EXEC on all PROT_READ mmaps */
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,58 +0,0 @@
|
||||
From c9f4923096e5c6dcb1591355e3cdab63167448d4 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <gofmanp@gmail.com>
|
||||
Date: Mon, 25 Nov 2019 12:19:20 +0300
|
||||
Subject: [PATCH] ntdll: Force bottom up allocation order for 64 bit arch
|
||||
unless top down is requested.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48175
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 3907b0db70a9..4b8942b1b53b 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -1775,13 +1775,19 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
}
|
||||
else
|
||||
{
|
||||
- size_t view_size = size + granularity_mask + 1;
|
||||
struct alloc_area alloc;
|
||||
+ size_t view_size;
|
||||
|
||||
alloc.size = size;
|
||||
alloc.top_down = top_down;
|
||||
alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
|
||||
|
||||
+ if (is_win64 && !top_down)
|
||||
+ {
|
||||
+ /* Ditch 0x7ffffe000000 - 0x7fffffff0000 reserved area. */
|
||||
+ alloc.limit = min(alloc.limit, (void *)0x7ffffe000000);
|
||||
+ }
|
||||
+
|
||||
if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
|
||||
{
|
||||
ptr = alloc.result;
|
||||
@@ -1791,7 +1797,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (zero_bits_64)
|
||||
+ if (is_win64 || zero_bits_64)
|
||||
{
|
||||
if (!(ptr = map_free_area( address_space_start, alloc.limit, size,
|
||||
top_down, get_unix_prot(vprot) )))
|
||||
@@ -1800,6 +1806,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ view_size = size + granularity_mask + 1;
|
||||
+
|
||||
for (;;)
|
||||
{
|
||||
if ((ptr = wine_anon_mmap( NULL, view_size, get_unix_prot(vprot), 0 )) == (void *)-1)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,76 +1,26 @@
|
||||
From c8bf6f3b7bd054d712463725ddd891b87801bf27 Mon Sep 17 00:00:00 2001
|
||||
From 1823294e18c99c17f3085486f12dcd2c6f8555b6 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Tue, 14 Jan 2020 21:42:21 +0300
|
||||
Subject: [PATCH] ntdll: Use free area list for virtual memory allocation.
|
||||
Date: Mon, 25 Nov 2019 12:19:20 +0300
|
||||
Subject: [PATCH 3/4] ntdll: Force virtual memory allocation order.
|
||||
|
||||
Windows allocates virtual memory strictly bottom up or
|
||||
top down depending on the requested flags. Modern Linux
|
||||
VM allocator always allocates memory top down. Some
|
||||
applications break if the allocated memory addresses
|
||||
are from higher memory than they expect.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48175
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568
|
||||
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 342 +++++++++++++++++++++++++-------------
|
||||
1 file changed, 230 insertions(+), 112 deletions(-)
|
||||
dlls/ntdll/unix/virtual.c | 417 ++++++++++++++++++--------------------
|
||||
1 file changed, 201 insertions(+), 216 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 2164c08f756..0939893d7c1 100644
|
||||
index 924dff973ce..e7dfc516538 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -185,7 +185,11 @@ static BYTE *pages_vprot;
|
||||
#endif
|
||||
|
||||
static struct file_view *view_block_start, *view_block_end, *next_free_view;
|
||||
+#ifdef _WIN64
|
||||
+static const size_t view_block_size = 0x200000;
|
||||
+#else
|
||||
static const size_t view_block_size = 0x100000;
|
||||
+#endif
|
||||
static void *preload_reserve_start;
|
||||
static void *preload_reserve_end;
|
||||
static BOOL force_exec_prot; /* whether to force PROT_EXEC on all PROT_READ mmaps */
|
||||
@@ -527,13 +531,13 @@ static struct range_entry *free_ranges_lower_bound( void *addr )
|
||||
*
|
||||
* Updates the free_ranges after a new view has been created.
|
||||
*/
|
||||
-static void free_ranges_insert_view( struct file_view *view )
|
||||
+static void free_ranges_remove_range( void *view_base, void *view_end, void *view_base_unaligned )
|
||||
{
|
||||
- void *view_base = ROUND_ADDR( view->base, granularity_mask );
|
||||
- void *view_end = ROUND_ADDR( (char *)view->base + view->size + granularity_mask, granularity_mask );
|
||||
struct range_entry *range = free_ranges_lower_bound( view_base );
|
||||
struct range_entry *next = range + 1;
|
||||
|
||||
+ TRACE("view %p-%p (%p).\n", view_base, view_end, view_base_unaligned);
|
||||
+
|
||||
/* free_ranges initial value is such that the view is either inside range or before another one. */
|
||||
assert( range != free_ranges_end );
|
||||
assert( range->end > view_base || next != free_ranges_end );
|
||||
@@ -544,7 +548,7 @@ static void free_ranges_insert_view( struct file_view *view )
|
||||
(range->end == view_base && next->base >= view_end))
|
||||
{
|
||||
/* on Win64, assert that it's correctly aligned so we're not going to be in trouble later */
|
||||
- assert( (!is_win64 && !is_wow64) || view->base == view_base );
|
||||
+ assert( (!is_win64 && !is_wow64) || view_base_unaligned == view_base );
|
||||
WARN( "range %p - %p is already mapped\n", view_base, view_end );
|
||||
return;
|
||||
}
|
||||
@@ -584,6 +588,12 @@ static void free_ranges_insert_view( struct file_view *view )
|
||||
}
|
||||
}
|
||||
|
||||
+static void free_ranges_insert_view( struct file_view *view )
|
||||
+{
|
||||
+ free_ranges_remove_range(ROUND_ADDR(view->base, granularity_mask),
|
||||
+ ROUND_ADDR((char *)view->base + view->size + granularity_mask, granularity_mask),
|
||||
+ view->base);
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* free_ranges_remove_view
|
||||
@@ -614,6 +624,7 @@ static void free_ranges_remove_view( struct file_view *view )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
+ TRACE("view %p-%p.\n", view_base, view_end);
|
||||
|
||||
/* free_ranges initial value is such that the view is either inside range or before another one. */
|
||||
assert( range != free_ranges_end );
|
||||
@@ -960,44 +971,6 @@ static struct file_view *find_view_range( const void *addr, size_t size )
|
||||
@@ -1020,44 +1020,6 @@ static struct file_view *find_view_range( const void *addr, size_t size )
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +65,7 @@ index 2164c08f756..0939893d7c1 100644
|
||||
/***********************************************************************
|
||||
* try_map_free_area
|
||||
*
|
||||
@@ -1036,65 +1009,11 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
@@ -1090,110 +1052,6 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -172,16 +122,61 @@ index 2164c08f756..0939893d7c1 100644
|
||||
-}
|
||||
-
|
||||
-
|
||||
/***********************************************************************
|
||||
* find_reserved_free_area
|
||||
*
|
||||
* Find a free area between views inside the specified range.
|
||||
* virtual_mutex must be held by caller.
|
||||
-/***********************************************************************
|
||||
- * find_reserved_free_area
|
||||
- *
|
||||
- * Find a free area between views inside the specified range.
|
||||
- * virtual_mutex must be held by caller.
|
||||
- * The range must be inside the preloader reserved range.
|
||||
*/
|
||||
static void *find_reserved_free_area( void *base, void *end, size_t size, int top_down )
|
||||
{
|
||||
@@ -1308,8 +1227,7 @@ static void delete_view( struct file_view *view ) /* [in] View */
|
||||
- */
|
||||
-static void *find_reserved_free_area( void *base, void *end, size_t size, int top_down )
|
||||
-{
|
||||
- struct range_entry *range;
|
||||
- void *start;
|
||||
-
|
||||
- base = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
|
||||
- end = (char *)ROUND_ADDR( (char *)end - size, granularity_mask ) + size;
|
||||
-
|
||||
- if (top_down)
|
||||
- {
|
||||
- start = (char *)end - size;
|
||||
- range = free_ranges_lower_bound( start );
|
||||
- assert(range != free_ranges_end && range->end >= start);
|
||||
-
|
||||
- if ((char *)range->end - (char *)start < size) start = ROUND_ADDR( (char *)range->end - size, granularity_mask );
|
||||
- do
|
||||
- {
|
||||
- if (start >= end || start < base || (char *)end - (char *)start < size) return NULL;
|
||||
- if (start < range->end && start >= range->base && (char *)range->end - (char *)start >= size) break;
|
||||
- if (--range < free_ranges) return NULL;
|
||||
- start = ROUND_ADDR( (char *)range->end - size, granularity_mask );
|
||||
- }
|
||||
- while (1);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- start = base;
|
||||
- range = free_ranges_lower_bound( start );
|
||||
- assert(range != free_ranges_end && range->end >= start);
|
||||
-
|
||||
- if (start < range->base) start = ROUND_ADDR( (char *)range->base + granularity_mask, granularity_mask );
|
||||
- do
|
||||
- {
|
||||
- if (start >= end || start < base || (char *)end - (char *)start < size) return NULL;
|
||||
- if (start < range->end && start >= range->base && (char *)range->end - (char *)start >= size) break;
|
||||
- if (++range == free_ranges_end) return NULL;
|
||||
- start = ROUND_ADDR( (char *)range->base + granularity_mask, granularity_mask );
|
||||
- }
|
||||
- while (1);
|
||||
- }
|
||||
- return start;
|
||||
-}
|
||||
-
|
||||
-
|
||||
/***********************************************************************
|
||||
* add_reserved_area
|
||||
*
|
||||
@@ -1351,8 +1209,7 @@ static void delete_view( struct file_view *view ) /* [in] View */
|
||||
{
|
||||
if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
|
||||
set_page_vprot( view->base, view->size, 0 );
|
||||
@ -191,7 +186,7 @@ index 2164c08f756..0939893d7c1 100644
|
||||
wine_rb_remove( &views_tree, &view->entry );
|
||||
*(struct file_view **)view = next_free_view;
|
||||
next_free_view = view;
|
||||
@@ -1357,8 +1275,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
|
||||
@@ -1400,8 +1257,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
|
||||
set_page_vprot( base, size, vprot );
|
||||
|
||||
wine_rb_put( &views_tree, view->base, &view->entry );
|
||||
@ -201,36 +196,47 @@ index 2164c08f756..0939893d7c1 100644
|
||||
|
||||
*view_ret = view;
|
||||
|
||||
@@ -1590,6 +1507,7 @@ struct alloc_area
|
||||
int top_down;
|
||||
void *limit;
|
||||
void *result;
|
||||
+ int unix_prot;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1631,6 +1549,210 @@ static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *a
|
||||
return 0;
|
||||
@@ -1646,54 +1502,219 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want
|
||||
return ptr;
|
||||
}
|
||||
|
||||
+struct area_alloc_reserved
|
||||
+{
|
||||
-
|
||||
struct alloc_area
|
||||
{
|
||||
+ char *map_area_start, *map_area_end, *result;
|
||||
+ size_t size;
|
||||
size_t size;
|
||||
- int top_down;
|
||||
- void *limit;
|
||||
- void *result;
|
||||
+ ptrdiff_t step;
|
||||
+ int unix_prot;
|
||||
+ BOOL top_down;
|
||||
+};
|
||||
+
|
||||
};
|
||||
|
||||
-/***********************************************************************
|
||||
- * alloc_reserved_area_callback
|
||||
- *
|
||||
- * Try to map some space inside a reserved area. Callback for mmap_enum_reserved_areas.
|
||||
- */
|
||||
-static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *arg )
|
||||
+static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T size, void *arg )
|
||||
+{
|
||||
+ struct area_alloc_reserved *area = arg;
|
||||
+ char *end = (char *)start + size;
|
||||
{
|
||||
- struct alloc_area *alloc = arg;
|
||||
- void *end = (char *)start + size;
|
||||
-
|
||||
- if (start < address_space_start) start = address_space_start;
|
||||
- if (is_beyond_limit( start, size, alloc->limit )) end = alloc->limit;
|
||||
- if (start >= end) return 0;
|
||||
+ char *intersect_start, *intersect_end;
|
||||
+ char *end = (char *)start + size;
|
||||
+ struct alloc_area *area = arg;
|
||||
+ char *alloc_start;
|
||||
+
|
||||
|
||||
- /* make sure we don't touch the preloader reserved range */
|
||||
- if (preload_reserve_end >= start)
|
||||
+ if (area->top_down)
|
||||
+ {
|
||||
{
|
||||
- if (preload_reserve_end >= end)
|
||||
+ if (area->map_area_start >= end)
|
||||
+ return 1;
|
||||
+
|
||||
@ -246,16 +252,24 @@ index 2164c08f756..0939893d7c1 100644
|
||||
+ alloc_start = ROUND_ADDR( (char *)area->map_area_end - size, granularity_mask );
|
||||
+
|
||||
+ if (alloc_start >= intersect_end)
|
||||
+ {
|
||||
{
|
||||
- if (preload_reserve_start <= start) return 0; /* no space in that area */
|
||||
- if (preload_reserve_start < end) end = preload_reserve_start;
|
||||
+ if ((area->result = try_map_free_area( area->map_area_start, alloc_start + size, area->step,
|
||||
+ alloc_start, area->size, area->unix_prot )))
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
- else if (preload_reserve_start <= start) start = preload_reserve_end;
|
||||
- else
|
||||
+
|
||||
+ alloc_start = ROUND_ADDR( intersect_end - area->size, granularity_mask );
|
||||
+ if (alloc_start >= intersect_start)
|
||||
+ {
|
||||
+ if ((area->result = wine_anon_mmap( alloc_start, area->size, area->unix_prot, MAP_FIXED )) != alloc_start)
|
||||
{
|
||||
- /* range is split in two by the preloader reservation, try first part */
|
||||
- if ((alloc->result = find_reserved_free_area( start, preload_reserve_start, alloc->size,
|
||||
- alloc->top_down )))
|
||||
+ if ((area->result = anon_mmap_fixed( alloc_start, area->size,
|
||||
+ area->unix_prot, 0 )) != alloc_start)
|
||||
+ ERR("Could not map in reserved area, alloc_start %p, size %p.\n",
|
||||
+ alloc_start, (void *)area->size);
|
||||
+ return 1;
|
||||
@ -283,12 +297,14 @@ index 2164c08f756..0939893d7c1 100644
|
||||
+ {
|
||||
+ if ((area->result = try_map_free_area( area->map_area_start, intersect_start, area->step,
|
||||
+ area->map_area_start, area->size, area->unix_prot )))
|
||||
+ return 1;
|
||||
+ }
|
||||
return 1;
|
||||
- /* then fall through to try second part */
|
||||
- start = preload_reserve_end;
|
||||
}
|
||||
+
|
||||
+ if (intersect_end - intersect_start >= area->size)
|
||||
+ {
|
||||
+ if ((area->result = wine_anon_mmap( intersect_start, area->size, area->unix_prot, MAP_FIXED ))
|
||||
+ if ((area->result = anon_mmap_fixed( intersect_start, area->size, area->unix_prot, 0 ))
|
||||
+ != intersect_start)
|
||||
+ ERR("Could not map in reserved area.\n");
|
||||
+ return 1;
|
||||
@ -296,66 +312,69 @@ index 2164c08f756..0939893d7c1 100644
|
||||
+ area->map_area_start = intersect_end;
|
||||
+ if (area->map_area_end - area->map_area_start < area->size)
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void *alloc_free_area_in_range(struct area_alloc_reserved *area, char *base, char *end,
|
||||
+ size_t size, int top_down, int unix_prot)
|
||||
}
|
||||
- if ((alloc->result = find_reserved_free_area( start, end, alloc->size, alloc->top_down )))
|
||||
- return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char *end )
|
||||
+{
|
||||
+ char *start;
|
||||
+
|
||||
+ TRACE("range %p-%p.\n", base, end);
|
||||
+
|
||||
+ if (base >= end) return NULL;
|
||||
+ if (base >= end)
|
||||
+ return NULL;
|
||||
+
|
||||
+ area->map_area_start = base;
|
||||
+ area->map_area_end = end;
|
||||
+
|
||||
+ if (top_down)
|
||||
+ if (area->top_down)
|
||||
+ {
|
||||
+ start = ROUND_ADDR( end - size, granularity_mask );
|
||||
+ start = ROUND_ADDR( end - area->size, granularity_mask );
|
||||
+ if (start >= end || start < base)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ start = ROUND_ADDR( base + granularity_mask, granularity_mask );
|
||||
+ if (!start || start >= end || (char *)end - (char *)start < size)
|
||||
+ if (!start || start >= end || (char *)end - (char *)start < area->size)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ mmap_enum_reserved_areas( alloc_area_in_reserved_or_between_callback, area, top_down );
|
||||
+ mmap_enum_reserved_areas( alloc_area_in_reserved_or_between_callback, area, area->top_down );
|
||||
+
|
||||
+ if (area->result)
|
||||
+ return area->result;
|
||||
+
|
||||
+ if (top_down)
|
||||
+ if (area->top_down)
|
||||
+ {
|
||||
+ start = ROUND_ADDR( area->map_area_end - size, granularity_mask );
|
||||
+ start = ROUND_ADDR( area->map_area_end - area->size, granularity_mask );
|
||||
+ if (start >= area->map_area_end || start < area->map_area_start)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return try_map_free_area( area->map_area_start, start + size, area->step,
|
||||
+ start, size, unix_prot );
|
||||
+ return try_map_free_area( area->map_area_start, start + area->size, area->step,
|
||||
+ start, area->size, area->unix_prot );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ start = ROUND_ADDR( area->map_area_start + granularity_mask, granularity_mask );
|
||||
+ if (!start || start >= area->map_area_end
|
||||
+ || area->map_area_end - start < size)
|
||||
+ || area->map_area_end - start < area->size)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return try_map_free_area( start, area->map_area_end, area->step,
|
||||
+ start, size, unix_prot );
|
||||
+ start, area->size, area->unix_prot );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void *alloc_free_area(void *limit, size_t size, BOOL top_down, int unix_prot)
|
||||
+static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_prot )
|
||||
+{
|
||||
+ struct range_entry *range, *ranges_start, *ranges_end;
|
||||
+ char *reserve_start, *reserve_end;
|
||||
+ struct area_alloc_reserved area;
|
||||
+ struct alloc_area area;
|
||||
+ char *base, *end;
|
||||
+ int ranges_inc;
|
||||
+
|
||||
@ -374,14 +393,14 @@ index 2164c08f756..0939893d7c1 100644
|
||||
+ ranges_inc = 1;
|
||||
+ }
|
||||
+
|
||||
+ memset(&area, 0, sizeof(area));
|
||||
+ memset( &area, 0, sizeof(area) );
|
||||
+ area.step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
|
||||
+ area.size = size;
|
||||
+ area.top_down = top_down;
|
||||
+ area.unix_prot = unix_prot;
|
||||
+
|
||||
+ reserve_start = ROUND_ADDR((char *)preload_reserve_start, granularity_mask);
|
||||
+ reserve_end = ROUND_ADDR((char *)preload_reserve_end + granularity_mask, granularity_mask);
|
||||
+ reserve_start = ROUND_ADDR( (char *)preload_reserve_start, granularity_mask );
|
||||
+ reserve_end = ROUND_ADDR( (char *)preload_reserve_end + granularity_mask, granularity_mask );
|
||||
+
|
||||
+ for (range = ranges_start; range != ranges_end; range += ranges_inc)
|
||||
+ {
|
||||
@ -390,28 +409,35 @@ index 2164c08f756..0939893d7c1 100644
|
||||
+
|
||||
+ TRACE("range %p-%p.\n", base, end);
|
||||
+
|
||||
+ if (base < (char *)address_space_start) base = (char *)address_space_start;
|
||||
+ if (end > (char *)ROUND_ADDR(limit, granularity_mask)) end = ROUND_ADDR(limit, granularity_mask);
|
||||
+ if (base < (char *)address_space_start)
|
||||
+ base = (char *)address_space_start;
|
||||
+ if (end > (char *)ROUND_ADDR( limit, granularity_mask ))
|
||||
+ end = ROUND_ADDR( limit, granularity_mask );
|
||||
+
|
||||
+ if (reserve_end >= base)
|
||||
+ {
|
||||
+ if (reserve_end >= end)
|
||||
+ {
|
||||
+ if (reserve_start <= base) continue; /* no space in that area */
|
||||
+ if (reserve_start < end) end = reserve_start;
|
||||
+ if (reserve_start <= base)
|
||||
+ continue; /* no space in that area */
|
||||
+ if (reserve_start < end)
|
||||
+ end = reserve_start;
|
||||
+ }
|
||||
+ else if (reserve_start <= base)
|
||||
+ {
|
||||
+ base = reserve_end;
|
||||
+ }
|
||||
+ else if (reserve_start <= base) base = reserve_end;
|
||||
+ else
|
||||
+ {
|
||||
+ /* range is split in two by the preloader reservation, try first part */
|
||||
+ if ((area.result = alloc_free_area_in_range(&area, base, reserve_start, size, top_down, unix_prot)))
|
||||
+ /* range is split in two by the preloader reservation, try first part. */
|
||||
+ if ((area.result = alloc_free_area_in_range( &area, base, reserve_start )))
|
||||
+ return area.result;
|
||||
+ /* then fall through to try second part */
|
||||
+ /* then fall through to try second part. */
|
||||
+ base = reserve_end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((area.result = alloc_free_area_in_range(&area, base, end, size, top_down, unix_prot)))
|
||||
+ if ((area.result = alloc_free_area_in_range( &area, base, end )))
|
||||
+ return area.result;
|
||||
+ }
|
||||
+ return NULL;
|
||||
@ -420,30 +446,31 @@ index 2164c08f756..0939893d7c1 100644
|
||||
/***********************************************************************
|
||||
* map_fixed_area
|
||||
*
|
||||
@@ -1716,11 +1838,15 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
alloc.size = size;
|
||||
alloc.top_down = top_down;
|
||||
alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
|
||||
+ alloc.unix_prot = get_unix_prot( vprot );
|
||||
|
||||
- if (is_win64 && !top_down)
|
||||
+ if (is_win64 || zero_bits_64)
|
||||
{
|
||||
- /* Ditch 0x7ffffe000000 - 0x7fffffff0000 reserved area. */
|
||||
- alloc.limit = min(alloc.limit, (void *)0x7ffffe000000);
|
||||
+ if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot)))
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+
|
||||
+ TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size );
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
|
||||
@@ -1732,15 +1858,6 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (is_win64 || zero_bits_64)
|
||||
@@ -1765,48 +1786,11 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
ptr = base;
|
||||
}
|
||||
- else
|
||||
+ else if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 )
|
||||
+ & (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) )))
|
||||
{
|
||||
- size_t view_size = size + granularity_mask + 1;
|
||||
- struct alloc_area alloc;
|
||||
-
|
||||
- alloc.size = size;
|
||||
- alloc.top_down = top_down;
|
||||
- alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
|
||||
-
|
||||
- if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
|
||||
- {
|
||||
- ptr = alloc.result;
|
||||
- TRACE( "got mem in reserved area %p-%p\n", ptr, (char *)ptr + size );
|
||||
- if (anon_mmap_fixed( ptr, size, get_unix_prot(vprot), 0 ) != ptr)
|
||||
- return STATUS_INVALID_PARAMETER;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (zero_bits_64)
|
||||
- {
|
||||
- if (!(ptr = map_free_area( address_space_start, alloc.limit, size,
|
||||
- top_down, get_unix_prot(vprot) )))
|
||||
@ -452,10 +479,26 @@ index 2164c08f756..0939893d7c1 100644
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
view_size = size + granularity_mask + 1;
|
||||
|
||||
for (;;)
|
||||
@@ -2393,6 +2510,7 @@ void virtual_init(void)
|
||||
- for (;;)
|
||||
- {
|
||||
- if ((ptr = anon_mmap_alloc( view_size, get_unix_prot(vprot) )) == MAP_FAILED)
|
||||
- {
|
||||
- if (errno == ENOMEM) return STATUS_NO_MEMORY;
|
||||
- return STATUS_INVALID_PARAMETER;
|
||||
- }
|
||||
- TRACE( "got mem with anon mmap %p-%p\n", ptr, (char *)ptr + size );
|
||||
- /* if we got something beyond the user limit, unmap it and retry */
|
||||
- if (is_beyond_limit( ptr, view_size, user_space_limit )) add_reserved_area( ptr, view_size );
|
||||
- else break;
|
||||
- }
|
||||
- ptr = unmap_extra_space( ptr, view_size, size );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
}
|
||||
-done:
|
||||
status = create_view( view_ret, ptr, size, vprot );
|
||||
if (status != STATUS_SUCCESS) unmap_area( ptr, size );
|
||||
return status;
|
||||
@@ -2453,6 +2437,7 @@ void virtual_init(void)
|
||||
if (preload_reserve_start)
|
||||
address_space_start = min( address_space_start, preload_reserve_start );
|
||||
}
|
||||
@ -464,5 +507,5 @@ index 2164c08f756..0939893d7c1 100644
|
||||
|
||||
/* try to find space in a reserved area for the views and pages protection table */
|
||||
--
|
||||
2.27.0
|
||||
2.26.2
|
||||
|
@ -0,0 +1,256 @@
|
||||
From 479dfa05cc83b7ae8ab0f40862e74efedd98df48 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Tue, 2 Jun 2020 21:06:33 +0300
|
||||
Subject: [PATCH 4/4] ntdll: Exclude natively mapped areas from free areas
|
||||
list.
|
||||
|
||||
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 130 ++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 103 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index e7dfc516538..dad12b5a9f2 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -103,6 +103,7 @@ struct file_view
|
||||
#define VPROT_WRITEWATCH 0x40
|
||||
/* per-mapping protection flags */
|
||||
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
|
||||
+#define VPROT_NATIVE 0x0400
|
||||
|
||||
/* Conversion from VPROT_* to Win32 flags */
|
||||
static const BYTE VIRTUAL_Win32Flags[16] =
|
||||
@@ -877,7 +878,9 @@ static void dump_view( struct file_view *view )
|
||||
BYTE prot = get_page_vprot( addr );
|
||||
|
||||
TRACE( "View: %p - %p", addr, addr + view->size - 1 );
|
||||
- if (view->protect & VPROT_SYSTEM)
|
||||
+ if (view->protect & VPROT_NATIVE)
|
||||
+ TRACE(" (native)\n");
|
||||
+ else if (view->protect & VPROT_SYSTEM)
|
||||
TRACE( " (builtin image)\n" );
|
||||
else if (view->protect & SEC_IMAGE)
|
||||
TRACE( " (image)\n" );
|
||||
@@ -1019,6 +1022,16 @@ static struct file_view *find_view_range( const void *addr, size_t size )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+struct alloc_area
|
||||
+{
|
||||
+ char *map_area_start, *map_area_end, *result;
|
||||
+ size_t size;
|
||||
+ ptrdiff_t step;
|
||||
+ int unix_prot;
|
||||
+ BOOL top_down;
|
||||
+ char *native_mapped;
|
||||
+ size_t native_mapped_size;
|
||||
+};
|
||||
|
||||
/***********************************************************************
|
||||
* try_map_free_area
|
||||
@@ -1026,21 +1039,27 @@ static struct file_view *find_view_range( const void *addr, size_t size )
|
||||
* Try mmaping some expected free memory region, eventually stepping and
|
||||
* retrying inside it, and return where it actually succeeded, or NULL.
|
||||
*/
|
||||
-static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
- void *start, size_t size, int unix_prot )
|
||||
+static void* try_map_free_area( struct alloc_area *area, void *base, void *end, void *start )
|
||||
{
|
||||
+ ptrdiff_t step = area->step;
|
||||
void *ptr;
|
||||
|
||||
- while (start && base <= start && (char*)start + size <= (char*)end)
|
||||
+ while (start && base <= start && (char*)start + area->size <= (char*)end)
|
||||
{
|
||||
- if ((ptr = anon_mmap_tryfixed( start, size, unix_prot, 0 )) != MAP_FAILED) return start;
|
||||
+ if ((ptr = anon_mmap_tryfixed( start, area->size, area->unix_prot, 0 )) != MAP_FAILED) return start;
|
||||
TRACE( "Found free area is already mapped, start %p.\n", start );
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
ERR( "mmap() error %s, range %p-%p, unix_prot %#x.\n",
|
||||
- strerror(errno), start, (char *)start + size, unix_prot );
|
||||
+ strerror(errno), start, (char *)start + area->size, area->unix_prot );
|
||||
return NULL;
|
||||
}
|
||||
+ if (!area->native_mapped && step)
|
||||
+ {
|
||||
+ area->native_mapped = start;
|
||||
+ area->native_mapped_size = step > 0 ? step : -step;
|
||||
+ area->native_mapped_size = min(area->native_mapped_size, (char *)end - (char *)start);
|
||||
+ }
|
||||
if ((step > 0 && (char *)end - (char *)start < step) ||
|
||||
(step < 0 && (char *)start - (char *)base < -step) ||
|
||||
step == 0)
|
||||
@@ -1502,15 +1521,6 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want
|
||||
return ptr;
|
||||
}
|
||||
|
||||
-struct alloc_area
|
||||
-{
|
||||
- char *map_area_start, *map_area_end, *result;
|
||||
- size_t size;
|
||||
- ptrdiff_t step;
|
||||
- int unix_prot;
|
||||
- BOOL top_down;
|
||||
-};
|
||||
-
|
||||
static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T size, void *arg )
|
||||
{
|
||||
char *intersect_start, *intersect_end;
|
||||
@@ -1536,8 +1546,8 @@ static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T
|
||||
|
||||
if (alloc_start >= intersect_end)
|
||||
{
|
||||
- if ((area->result = try_map_free_area( area->map_area_start, alloc_start + size, area->step,
|
||||
- alloc_start, area->size, area->unix_prot )))
|
||||
+ if ((area->result = try_map_free_area( area, area->map_area_start,
|
||||
+ alloc_start + size, alloc_start )))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1571,8 +1581,8 @@ static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T
|
||||
|
||||
if (intersect_start - area->map_area_start >= area->size)
|
||||
{
|
||||
- if ((area->result = try_map_free_area( area->map_area_start, intersect_start, area->step,
|
||||
- area->map_area_start, area->size, area->unix_prot )))
|
||||
+ if ((area->result = try_map_free_area( area, area->map_area_start,
|
||||
+ intersect_start, area->map_area_start )))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1627,8 +1637,7 @@ static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char
|
||||
if (start >= area->map_area_end || start < area->map_area_start)
|
||||
return NULL;
|
||||
|
||||
- return try_map_free_area( area->map_area_start, start + area->size, area->step,
|
||||
- start, area->size, area->unix_prot );
|
||||
+ return try_map_free_area( area, area->map_area_start, start + area->size, start );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1637,8 +1646,7 @@ static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char
|
||||
|| area->map_area_end - start < area->size)
|
||||
return NULL;
|
||||
|
||||
- return try_map_free_area( start, area->map_area_end, area->step,
|
||||
- start, area->size, area->unix_prot );
|
||||
+ return try_map_free_area( area, start, area->map_area_end, start );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1648,6 +1656,7 @@ static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_
|
||||
char *reserve_start, *reserve_end;
|
||||
struct alloc_area area;
|
||||
char *base, *end;
|
||||
+ NTSTATUS status;
|
||||
int ranges_inc;
|
||||
|
||||
TRACE("limit %p, size %p, top_down %#x.\n", limit, (void *)size, top_down);
|
||||
@@ -1703,16 +1712,67 @@ static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_
|
||||
{
|
||||
/* range is split in two by the preloader reservation, try first part. */
|
||||
if ((area.result = alloc_free_area_in_range( &area, base, reserve_start )))
|
||||
- return area.result;
|
||||
+ break;
|
||||
/* then fall through to try second part. */
|
||||
base = reserve_end;
|
||||
}
|
||||
}
|
||||
|
||||
if ((area.result = alloc_free_area_in_range( &area, base, end )))
|
||||
- return area.result;
|
||||
+ break;
|
||||
}
|
||||
- return NULL;
|
||||
+
|
||||
+ if (area.native_mapped)
|
||||
+ {
|
||||
+ char *native_mapped_start, *native_mapped_end;
|
||||
+
|
||||
+ TRACE("Excluding %p - %p from free list.\n",
|
||||
+ area.native_mapped, (char *)area.native_mapped + area.native_mapped_size );
|
||||
+
|
||||
+ native_mapped_start = ROUND_ADDR(area.native_mapped, granularity_mask);
|
||||
+ native_mapped_end = ROUND_ADDR((char *)area.native_mapped + area.native_mapped_size + granularity_mask,
|
||||
+ granularity_mask);
|
||||
+
|
||||
+ if (area.result >= native_mapped_end || area.result + size < native_mapped_start)
|
||||
+ /* In case of top down allocation try_map_free_area() result area can overlap the
|
||||
+ * area previously marked as native if the latter was unmapped behind our back. */
|
||||
+ {
|
||||
+ struct file_view *prev, *next;
|
||||
+
|
||||
+ prev = find_view_range( native_mapped_start - 1, native_mapped_end - native_mapped_start + 2 );
|
||||
+ if (prev && (char *)prev->base >= native_mapped_end)
|
||||
+ {
|
||||
+ next = prev;
|
||||
+ prev = WINE_RB_ENTRY_VALUE( wine_rb_prev( &next->entry ), struct file_view, entry );
|
||||
+ }
|
||||
+ else if (prev)
|
||||
+ {
|
||||
+ next = WINE_RB_ENTRY_VALUE( wine_rb_next( &prev->entry ), struct file_view, entry );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ next = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (prev && prev->protect & VPROT_NATIVE && (char *)prev->base + prev->size >= native_mapped_start)
|
||||
+ {
|
||||
+ assert( (char *)prev->base + prev->size == native_mapped_start );
|
||||
+ native_mapped_start = prev->base;
|
||||
+ delete_view( prev );
|
||||
+ }
|
||||
+ if (next && next->protect & VPROT_NATIVE && native_mapped_end >= (char *)next->base)
|
||||
+ {
|
||||
+ assert( native_mapped_end == (char *)next->base );
|
||||
+ native_mapped_end = (char *)next->base + next->size;
|
||||
+ delete_view( next );
|
||||
+ }
|
||||
+ if ((status = create_view( &next, native_mapped_start, native_mapped_end - native_mapped_start,
|
||||
+ VPROT_SYSTEM | VPROT_NATIVE )))
|
||||
+ ERR("Could not cretae view for natively mapped area, status %#x.\n", status);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return area.result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1766,6 +1826,17 @@ static NTSTATUS map_fixed_area( void *base, size_t size, unsigned int vprot )
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+static void clear_native_views(void)
|
||||
+{
|
||||
+ struct file_view *view, *next_view;
|
||||
+
|
||||
+ WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR( view, next_view, &views_tree, struct file_view, entry )
|
||||
+ {
|
||||
+ if (view->protect & VPROT_NATIVE)
|
||||
+ delete_view( view );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* map_view
|
||||
*
|
||||
@@ -1789,7 +1860,12 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
else if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 )
|
||||
& (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) )))
|
||||
{
|
||||
- return STATUS_NO_MEMORY;
|
||||
+ WARN("Allocation failed, clearing native views.\n");
|
||||
+
|
||||
+ clear_native_views();
|
||||
+ if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 )
|
||||
+ & (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) )))
|
||||
+ return STATUS_NO_MEMORY;
|
||||
}
|
||||
status = create_view( view_ret, ptr, size, vprot );
|
||||
if (status != STATUS_SUCCESS) unmap_area( ptr, size );
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,66 +0,0 @@
|
||||
From eda2aae6a4845e3b0f5e4edb805fb4add4316f17 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Tue, 2 Jun 2020 21:06:33 +0300
|
||||
Subject: [PATCH] ntdll: Permanently exclude natively mapped areas from free
|
||||
areas list.
|
||||
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 667401aaa93..c49c60166c2 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -124,6 +124,9 @@ static const BYTE VIRTUAL_Win32Flags[16] =
|
||||
static struct wine_rb_tree views_tree;
|
||||
static pthread_mutex_t virtual_mutex;
|
||||
|
||||
+static void *last_already_mapped;
|
||||
+static size_t last_already_mapped_size;
|
||||
+
|
||||
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
|
||||
static const UINT page_shift = 12;
|
||||
static const UINT_PTR page_mask = 0xfff;
|
||||
@@ -997,6 +1000,13 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
|
||||
if (ptr != (void *)-1)
|
||||
munmap( ptr, size );
|
||||
|
||||
+ if (!last_already_mapped && step)
|
||||
+ {
|
||||
+ last_already_mapped = start;
|
||||
+ last_already_mapped_size = step > 0 ? step : -step;
|
||||
+ last_already_mapped_size = min(last_already_mapped_size, (char *)end - (char *)start);
|
||||
+ }
|
||||
+
|
||||
if ((step > 0 && (char *)end - (char *)start < step) ||
|
||||
(step < 0 && (char *)start - (char *)base < -step) ||
|
||||
step == 0)
|
||||
@@ -1841,9 +1851,24 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
||||
|
||||
if (is_win64 || zero_bits_64)
|
||||
{
|
||||
+ last_already_mapped = NULL;
|
||||
+
|
||||
if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot)))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
+ if (last_already_mapped)
|
||||
+ {
|
||||
+ void *last_mapped_start, *last_mapped_end;
|
||||
+
|
||||
+ TRACE("Permanently excluding %p - %p from free list.\n",
|
||||
+ last_already_mapped, (char *)last_already_mapped + last_already_mapped_size - 1);
|
||||
+ last_mapped_start = ROUND_ADDR(last_already_mapped, granularity_mask);
|
||||
+ last_mapped_end = ROUND_ADDR((char *)last_already_mapped + last_already_mapped_size + granularity_mask,
|
||||
+ granularity_mask);
|
||||
+ if (ptr > last_mapped_end || (char *)ptr + size < (char *)last_mapped_start)
|
||||
+ free_ranges_remove_range(last_mapped_start, last_mapped_end, last_already_mapped);
|
||||
+ }
|
||||
+
|
||||
TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size );
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From cafaad67d4b5ed7985930e2a13e55d400cbbbbc9 Mon Sep 17 00:00:00 2001
|
||||
From 6e22c1cc4c615e07ac3570e152d15f22aab9eead 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.
|
||||
@ -6,22 +6,18 @@ Subject: [PATCH] ntdll: Add support for junction point creation.
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
configure.ac | 2 +
|
||||
dlls/ntdll/tests/file.c | 101 +++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 129 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/tests/file.c | 101 ++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/file.c | 155 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/Makefile.in | 1 +
|
||||
include/ntifs.h | 42 +++++++++++++
|
||||
include/wine/port.h | 9 +++
|
||||
libs/port/Makefile.in | 1 +
|
||||
libs/port/renameat2.c | 55 +++++++++++++++++
|
||||
8 files changed, 340 insertions(+)
|
||||
include/ntifs.h | 42 +++++++++++
|
||||
5 files changed, 301 insertions(+)
|
||||
create mode 100644 include/ntifs.h
|
||||
create mode 100644 libs/port/renameat2.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d85f4dee7c..1bc2b5cbe2 100644
|
||||
index aef00416461..15c0b7e4c26 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2214,6 +2214,8 @@ AC_CHECK_FUNCS(\
|
||||
@@ -2230,6 +2230,8 @@ AC_CHECK_FUNCS(\
|
||||
pwrite \
|
||||
readdir \
|
||||
readlink \
|
||||
@ -31,7 +27,7 @@ index d85f4dee7c..1bc2b5cbe2 100644
|
||||
select \
|
||||
setproctitle \
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 1bb71e711a..84fea2b869 100644
|
||||
index 1492797b0c9..10bdef5d810 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -38,6 +38,7 @@
|
||||
@ -42,7 +38,7 @@ index 1bb71e711a..84fea2b869 100644
|
||||
|
||||
#ifndef IO_COMPLETION_ALL_ACCESS
|
||||
#define IO_COMPLETION_ALL_ACCESS 0x001F0003
|
||||
@@ -5143,6 +5144,105 @@ static void test_mailslot_name(void)
|
||||
@@ -5141,6 +5142,105 @@ static void test_mailslot_name(void)
|
||||
CloseHandle( device );
|
||||
}
|
||||
|
||||
@ -148,7 +144,7 @@ index 1bb71e711a..84fea2b869 100644
|
||||
START_TEST(file)
|
||||
{
|
||||
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||
@@ -5215,5 +5315,6 @@ START_TEST(file)
|
||||
@@ -5213,5 +5313,6 @@ START_TEST(file)
|
||||
test_ioctl();
|
||||
test_query_ea();
|
||||
test_flush_buffers_file();
|
||||
@ -156,7 +152,7 @@ index 1bb71e711a..84fea2b869 100644
|
||||
test_mailslot_name();
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
|
||||
index 7667bd6398..211ebc89df 100644
|
||||
index 290e18e54c5..c2243975e4b 100644
|
||||
--- a/dlls/ntdll/unix/file.c
|
||||
+++ b/dlls/ntdll/unix/file.c
|
||||
@@ -36,6 +36,7 @@
|
||||
@ -167,7 +163,7 @@ index 7667bd6398..211ebc89df 100644
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_MNTENT_H
|
||||
#include <mntent.h>
|
||||
@@ -126,6 +127,7 @@
|
||||
@@ -132,6 +133,7 @@
|
||||
#include "wine/list.h"
|
||||
#include "wine/debug.h"
|
||||
#include "unix_private.h"
|
||||
@ -175,7 +171,40 @@ index 7667bd6398..211ebc89df 100644
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(file);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
@@ -5643,6 +5645,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
@@ -457,6 +459,32 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifndef HAVE_RENAMEAT
|
||||
+int renameat( int olddirfd, const char *oldpath, int newdirfd, const char *newpath )
|
||||
+{
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#ifndef HAVE_RENAMEAT2
|
||||
+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
||||
+ unsigned int flags )
|
||||
+{
|
||||
+ if (flags == 0)
|
||||
+ return renameat( olddirfd, oldpath, newdirfd, newpath );
|
||||
+#if defined(__NR_renameat2)
|
||||
+ return syscall( __NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags );
|
||||
+#elif defined(RENAME_SWAP)
|
||||
+ return renameatx_np(olddirfd, oldpath, newdirfd, newpath,
|
||||
+ (flags & RENAME_EXCHANGE ? RENAME_SWAP : 0));
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+#endif /* HAVE_RENAMEAT2 */
|
||||
+
|
||||
/* 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 )
|
||||
{
|
||||
@@ -5731,6 +5759,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer,
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +321,7 @@ index 7667bd6398..211ebc89df 100644
|
||||
/******************************************************************************
|
||||
* NtFsControlFile (NTDLL.@)
|
||||
*/
|
||||
@@ -5725,6 +5837,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
@@ -5813,6 +5951,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||
break;
|
||||
}
|
||||
|
||||
@ -317,10 +346,10 @@ index 7667bd6398..211ebc89df 100644
|
||||
TRACE("FSCTL_SET_SPARSE: Ignoring request\n");
|
||||
io->Information = 0;
|
||||
diff --git a/include/Makefile.in b/include/Makefile.in
|
||||
index 216adf0d7a..7dc16c230b 100644
|
||||
index 49b174ed319..2dbf84e6c36 100644
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -520,6 +520,7 @@ SOURCES = \
|
||||
@@ -523,6 +523,7 @@ SOURCES = \
|
||||
ntddvdeo.h \
|
||||
ntdef.h \
|
||||
ntdsapi.h \
|
||||
@ -330,7 +359,7 @@ index 216adf0d7a..7dc16c230b 100644
|
||||
ntsecapi.h \
|
||||
diff --git a/include/ntifs.h b/include/ntifs.h
|
||||
new file mode 100644
|
||||
index 0000000000..21d42e1732
|
||||
index 00000000000..21d42e17325
|
||||
--- /dev/null
|
||||
+++ b/include/ntifs.h
|
||||
@@ -0,0 +1,42 @@
|
||||
@ -376,99 +405,6 @@ index 0000000000..21d42e1732
|
||||
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
+
|
||||
+#endif /* __WINE_NTIFS_H */
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 930efeeea1..7d2c738870 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -334,6 +334,15 @@ double rint(double x);
|
||||
float rintf(float x);
|
||||
#endif
|
||||
|
||||
+#ifndef RENAME_EXCHANGE
|
||||
+#define RENAME_EXCHANGE (1 << 1)
|
||||
+#endif /* RENAME_EXCHANGE */
|
||||
+
|
||||
+#ifndef HAVE_RENAMEAT2
|
||||
+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
||||
+ unsigned int flags );
|
||||
+#endif /* HAVE_RENAMEAT2 */
|
||||
+
|
||||
#ifndef HAVE_STATVFS
|
||||
int statvfs( const char *path, struct statvfs *buf );
|
||||
#endif
|
||||
diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in
|
||||
index d1de285d52..4b1ecab751 100644
|
||||
--- a/libs/port/Makefile.in
|
||||
+++ b/libs/port/Makefile.in
|
||||
@@ -14,6 +14,7 @@ C_SRCS = \
|
||||
pread.c \
|
||||
pwrite.c \
|
||||
readlink.c \
|
||||
+ renameat2.c \
|
||||
rint.c \
|
||||
spawn.c \
|
||||
statvfs.c \
|
||||
diff --git a/libs/port/renameat2.c b/libs/port/renameat2.c
|
||||
new file mode 100644
|
||||
index 0000000000..f46f407ec7
|
||||
--- /dev/null
|
||||
+++ b/libs/port/renameat2.c
|
||||
@@ -0,0 +1,55 @@
|
||||
+/*
|
||||
+ * renameat2 function
|
||||
+ *
|
||||
+ * Copyright 2015-2019 Erich E. Hoover
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include "wine/port.h"
|
||||
+
|
||||
+#ifdef HAVE_SYS_SYSCALL_H
|
||||
+# include <sys/syscall.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#ifndef HAVE_RENAMEAT
|
||||
+int renameat( int olddirfd, const char *oldpath, int newdirfd, const char *newpath )
|
||||
+{
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#ifndef HAVE_RENAMEAT2
|
||||
+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
||||
+ unsigned int flags )
|
||||
+{
|
||||
+ if (flags == 0)
|
||||
+ return renameat( olddirfd, oldpath, newdirfd, newpath );
|
||||
+#if defined(__NR_renameat2)
|
||||
+ return syscall( __NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags );
|
||||
+#elif defined(RENAME_SWAP)
|
||||
+ return renameatx_np(olddirfd, oldpath, newdirfd, newpath,
|
||||
+ (flags & RENAME_EXCHANGE ? RENAME_SWAP : 0));
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+#endif /* HAVE_RENAMEAT2 */
|
||||
--
|
||||
2.27.0
|
||||
2.28.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 683ec6017757a1f2cdd33feec608aad6a9022322 Mon Sep 17 00:00:00 2001
|
||||
From c8020cc027be026da2aef0ed866a59629d4e053e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 4 Oct 2014 03:22:09 +0200
|
||||
Subject: [PATCH] ntdll: Properly handle PAGE_WRITECOPY protection. (try 5)
|
||||
@ -9,11 +9,11 @@ For now, only enable it when a special environment variable is set.
|
||||
1 file changed, 39 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 54c6b732d0f..cd0e343c46b 100644
|
||||
index 563ed01deb5..79f6af38b00 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -363,6 +363,21 @@ static int mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T s
|
||||
return ret;
|
||||
@@ -490,6 +490,21 @@ static void reserve_area( void *addr, void *end )
|
||||
#endif /* __APPLE__ */
|
||||
}
|
||||
|
||||
+/* This might look like a hack, but it actually isn't - the 'experimental' version
|
||||
@ -32,9 +32,9 @@ index 54c6b732d0f..cd0e343c46b 100644
|
||||
+ return enabled;
|
||||
+}
|
||||
|
||||
static void reserve_area( void *addr, void *end )
|
||||
static void mmap_init( const struct preload_info *preload_info )
|
||||
{
|
||||
@@ -803,8 +818,19 @@ static int get_unix_prot( BYTE vprot )
|
||||
@@ -847,8 +862,19 @@ static int get_unix_prot( BYTE vprot )
|
||||
{
|
||||
if (vprot & VPROT_READ) prot |= PROT_READ;
|
||||
if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ;
|
||||
@ -55,7 +55,7 @@ index 54c6b732d0f..cd0e343c46b 100644
|
||||
if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE;
|
||||
}
|
||||
if (!prot) prot = PROT_NONE;
|
||||
@@ -1550,7 +1576,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size
|
||||
@@ -1577,7 +1603,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size
|
||||
{
|
||||
TRACE( "updating watch %p-%p-%p\n", base, (char *)base + accessed_size, (char *)base + size );
|
||||
/* clear write watch flag on accessed pages */
|
||||
@ -64,7 +64,7 @@ index 54c6b732d0f..cd0e343c46b 100644
|
||||
/* restore page protections on the entire range */
|
||||
mprotect_range( base, size, 0, 0 );
|
||||
}
|
||||
@@ -2904,12 +2930,13 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
@@ -2919,12 +2945,13 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
|
||||
mprotect_range( page, page_size, 0, 0 );
|
||||
}
|
||||
@ -82,7 +82,7 @@ index 54c6b732d0f..cd0e343c46b 100644
|
||||
}
|
||||
pthread_mutex_unlock( &virtual_mutex );
|
||||
return ret;
|
||||
@@ -2986,11 +3013,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat
|
||||
@@ -3001,11 +3028,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat
|
||||
{
|
||||
BYTE vprot = get_page_vprot( addr + i );
|
||||
if (vprot & VPROT_WRITEWATCH) *has_write_watch = TRUE;
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 065015c3bc777193f4d44ca7969995a9ec563ce2 Mon Sep 17 00:00:00 2001
|
||||
From 6af98b9092396f69ac66c4659581436d9c6c7183 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Wesie <awesie@gmail.com>
|
||||
Date: Fri, 24 Apr 2020 14:55:14 -0500
|
||||
Subject: [PATCH] ntdll: Track if a WRITECOPY page has been modified.
|
||||
@ -12,18 +12,18 @@ Signed-off-by: Andrew Wesie <awesie@gmail.com>
|
||||
1 file changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index f0ec65d12704..98c5aad578c6 100644
|
||||
index f3d7c24515f..045d10d92be 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -97,6 +97,7 @@ struct file_view
|
||||
@@ -101,6 +101,7 @@ struct file_view
|
||||
#define VPROT_GUARD 0x10
|
||||
#define VPROT_COMMITTED 0x20
|
||||
#define VPROT_WRITEWATCH 0x40
|
||||
+#define VPROT_WRITTEN 0x80
|
||||
/* per-mapping protection flags */
|
||||
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
|
||||
|
||||
@@ -820,7 +821,7 @@ static int get_unix_prot( BYTE vprot )
|
||||
#define VPROT_NATIVE 0x0400
|
||||
@@ -871,7 +872,7 @@ static int get_unix_prot( BYTE vprot )
|
||||
#if defined(__i386__)
|
||||
if (vprot & VPROT_WRITECOPY)
|
||||
{
|
||||
@ -32,7 +32,7 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
prot = (prot & ~PROT_WRITE) | PROT_READ;
|
||||
else
|
||||
prot |= PROT_WRITE | PROT_READ;
|
||||
@@ -1406,7 +1407,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
|
||||
@@ -1315,7 +1316,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
|
||||
*/
|
||||
static DWORD get_win32_prot( BYTE vprot, unsigned int map_prot )
|
||||
{
|
||||
@ -45,7 +45,7 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
if (vprot & VPROT_GUARD) ret |= PAGE_GUARD;
|
||||
if (map_prot & SEC_NOCACHE) ret |= PAGE_NOCACHE;
|
||||
return ret;
|
||||
@@ -1517,7 +1522,7 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
@@ -1426,7 +1431,7 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
if (view->protect & VPROT_WRITEWATCH)
|
||||
{
|
||||
/* each page may need different protections depending on write watch flag */
|
||||
@ -54,7 +54,7 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
mprotect_range( base, size, 0, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1533,10 +1538,18 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
@@ -1442,10 +1447,18 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2928,7 +2941,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
@@ -3013,7 +3026,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
}
|
||||
if (vprot & VPROT_WRITECOPY)
|
||||
{
|
||||
@ -83,7 +83,7 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
mprotect_range( page, page_size, 0, 0 );
|
||||
}
|
||||
/* ignore fault if page is writable now */
|
||||
@@ -3873,7 +3886,7 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
@@ -3955,7 +3968,7 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
else if (view->protect & (SEC_FILE | SEC_RESERVE | SEC_COMMIT)) info->Type = MEM_MAPPED;
|
||||
else info->Type = MEM_PRIVATE;
|
||||
for (ptr = base; ptr < base + range_size; ptr += page_size)
|
||||
@ -93,5 +93,5 @@ index f0ec65d12704..98c5aad578c6 100644
|
||||
}
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
--
|
||||
2.20.1
|
||||
2.28.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 5749f2c2ddcf9dc0dc5d1257b4829bd6bdda4c7e Mon Sep 17 00:00:00 2001
|
||||
From 86b7f01ebe8d0cccd81a1d9913c9a42966ea7d3c Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Wesie <awesie@gmail.com>
|
||||
Date: Tue, 28 Apr 2020 03:27:16 -0500
|
||||
Subject: [PATCH] ntdll: Fallback to copy pages for WRITECOPY.
|
||||
@ -16,10 +16,10 @@ Signed-off-by: Andrew Wesie <awesie@gmail.com>
|
||||
1 file changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 8b3f93b70d41..c53b87076075 100644
|
||||
index 148da16f34d..1ca19a24003 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -1538,8 +1538,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
@@ -1447,8 +1447,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ index 8b3f93b70d41..c53b87076075 100644
|
||||
unix_prot |= PROT_WRITE;
|
||||
|
||||
if (mprotect_exec( base, size, unix_prot )) /* FIXME: last error */
|
||||
@@ -2941,10 +2942,26 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
@@ -3026,10 +3027,26 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
|
||||
mprotect_range( page, page_size, 0, 0 );
|
||||
}
|
||||
@ -50,16 +50,16 @@ index 8b3f93b70d41..c53b87076075 100644
|
||||
+ {
|
||||
+ static BYTE *temp_page = NULL;
|
||||
+ if (!temp_page)
|
||||
+ temp_page = wine_anon_mmap( NULL, page_size, PROT_READ | PROT_WRITE, 0 );
|
||||
+ temp_page = anon_mmap_alloc( page_size, PROT_READ | PROT_WRITE );
|
||||
+
|
||||
+ /* original mapping is shared, replace with a private page */
|
||||
+ memcpy( temp_page, page, page_size );
|
||||
+ wine_anon_mmap( page, page_size, get_unix_prot( vprot | VPROT_WRITE | VPROT_WRITTEN ), MAP_FIXED );
|
||||
+ anon_mmap_fixed( page, page_size, get_unix_prot( vprot | VPROT_WRITE | VPROT_WRITTEN ), 0 );
|
||||
+ memcpy( page, temp_page, page_size );
|
||||
+ }
|
||||
}
|
||||
/* ignore fault if page is writable now */
|
||||
if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||||
--
|
||||
2.20.1
|
||||
2.28.0
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Fixes: [29384] Multiple applications expect correct handling of WRITECOPY memory protection (Voobly fails to launch Age of Empires II, MSYS2)
|
||||
|
||||
Depends: ntdll-ForceBottomUpAlloc
|
||||
# Causes regressions?
|
||||
# https://bugs.wine-staging.com/show_bug.cgi?id=207
|
||||
# https://bugs.wine-staging.com/show_bug.cgi?id=521
|
||||
|
@ -52,7 +52,7 @@ usage()
|
||||
# Get the upstream commit sha
|
||||
upstream_commit()
|
||||
{
|
||||
echo "87f41e6b408dd01055ff6a378b90d089d61ec370"
|
||||
echo "314368e6c442f043ebfc22b70c1113e4e6232c04"
|
||||
}
|
||||
|
||||
# Show version information
|
||||
@ -1661,6 +1661,13 @@ if test "$enable_ntdll_Builtin_Prot" -eq 1; then
|
||||
enable_ntdll_WRITECOPY=1
|
||||
fi
|
||||
|
||||
if test "$enable_ntdll_WRITECOPY" -eq 1; then
|
||||
if test "$enable_ntdll_ForceBottomUpAlloc" -gt 1; then
|
||||
abort "Patchset ntdll-ForceBottomUpAlloc disabled, but ntdll-WRITECOPY depends on that."
|
||||
fi
|
||||
enable_ntdll_ForceBottomUpAlloc=1
|
||||
fi
|
||||
|
||||
if test "$enable_ntdll_ApiSetMap" -eq 1; then
|
||||
if test "$enable_ntdll_FLS_Callbacks" -gt 1; then
|
||||
abort "Patchset ntdll-FLS_Callbacks disabled, but ntdll-ApiSetMap depends on that."
|
||||
@ -3415,8 +3422,34 @@ if test "$enable_ntdll_ApiSetMap" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-ForceBottomUpAlloc
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated
|
||||
# | * [#46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect
|
||||
# | 44-bit user-mode VA limitation from Windows < 8.1)
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/unix/virtual.c
|
||||
# |
|
||||
if test "$enable_ntdll_ForceBottomUpAlloc" -eq 1; then
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase step after failed map attempt in try_map_free_area().", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase free ranges view block size on 64 bit.", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Force virtual memory allocation order.", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Exclude natively mapped areas from free areas list.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-WRITECOPY
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * ntdll-ForceBottomUpAlloc
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#29384] Multiple applications expect correct handling of WRITECOPY memory protection (Voobly fails to launch Age of
|
||||
# | Empires II, MSYS2)
|
||||
@ -3453,7 +3486,7 @@ fi
|
||||
# Patchset ntdll-Builtin_Prot
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * ntdll-WRITECOPY
|
||||
# | * ntdll-ForceBottomUpAlloc, ntdll-WRITECOPY
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#44650] Fix holes in ELF mappings
|
||||
@ -3491,8 +3524,7 @@ fi
|
||||
# | * [#15679] cygwin symlinks not working in wine
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * configure.ac, dlls/ntdll/tests/directory.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c, include/wine/port.h,
|
||||
# | libs/port/Makefile.in, libs/port/xattr.c
|
||||
# | * configure.ac, dlls/ntdll/tests/directory.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c
|
||||
# |
|
||||
if test "$enable_ntdll_DOS_Attributes" -eq 1; then
|
||||
patch_apply ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch
|
||||
@ -3567,29 +3599,6 @@ if test "$enable_ntdll_Fix_Alignment" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-ForceBottomUpAlloc
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated
|
||||
# | * [#46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect
|
||||
# | 44-bit user-mode VA limitation from Windows < 8.1)
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/unix/virtual.c
|
||||
# |
|
||||
if test "$enable_ntdll_ForceBottomUpAlloc" -eq 1; then
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch
|
||||
patch_apply ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Force bottom up allocation order for 64 bit arch unless top down is requested.", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase step after failed map attempt in try_map_free_area().", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Use free area list for virtual memory allocation.", 1 },';
|
||||
printf '%s\n' '+ { "Paul Gofman", "ntdll: Permanently exclude natively mapped areas from free areas list.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-HashLinks
|
||||
# |
|
||||
# | Modified files:
|
||||
@ -3677,8 +3686,7 @@ fi
|
||||
# | Modified files:
|
||||
# | * configure.ac, dlls/kernel32/tests/path.c, dlls/kernelbase/file.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/wine/port.h, include/winternl.h, libs/port/Makefile.in, libs/port/renameat2.c, programs/cmd/builtins.c,
|
||||
# | programs/cmd/directory.c, server/fd.c, server/protocol.def
|
||||
# | include/winternl.h, programs/cmd/builtins.c, programs/cmd/directory.c, server/fd.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
|
||||
@ -4420,8 +4428,7 @@ fi
|
||||
# | * [#33576] Support for stored file ACLs
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h, server/object.c,
|
||||
# | server/object.h
|
||||
# | * dlls/advapi32/tests/security.c, server/change.c, server/file.c, server/file.h, server/object.c, server/object.h
|
||||
# |
|
||||
if test "$enable_server_Stored_ACLs" -eq 1; then
|
||||
patch_apply server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch
|
||||
|
@ -1,30 +1,15 @@
|
||||
From f574af9e0d14b048ff0b410831f226cf764c5d05 Mon Sep 17 00:00:00 2001
|
||||
From a36fb419f7a4c4023507b985ed54387354596445 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Mon, 30 Mar 2015 13:04:23 +0200
|
||||
Subject: [PATCH] server: Store file security attributes with extended file
|
||||
attributes. (v8)
|
||||
|
||||
---
|
||||
include/wine/port.h | 3 +++
|
||||
server/file.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 37 insertions(+)
|
||||
server/file.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/include/wine/port.h b/include/wine/port.h
|
||||
index 7d2c73887073..145f78bebdba 100644
|
||||
--- a/include/wine/port.h
|
||||
+++ b/include/wine/port.h
|
||||
@@ -366,6 +366,9 @@ extern int mkstemps(char *template, int suffix_len);
|
||||
#ifndef XATTR_USER_PREFIX
|
||||
# define XATTR_USER_PREFIX "user."
|
||||
#endif
|
||||
+#ifndef XATTR_SIZE_MAX
|
||||
+# define XATTR_SIZE_MAX 65536
|
||||
+#endif
|
||||
|
||||
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
|
||||
extern int xattr_fremove( int filedes, const char *name );
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 9c94f9ba2bba..5e542b62e77e 100644
|
||||
index f0253115c5d..5df300a9a73 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@ -35,10 +20,30 @@ index 9c94f9ba2bba..5e542b62e77e 100644
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
@@ -52,6 +53,14 @@
|
||||
@@ -39,6 +40,12 @@
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
+#ifdef HAVE_ATTR_XATTR_H
|
||||
+#undef XATTR_ADDITIONAL_OPTIONS
|
||||
+#include <attr/xattr.h>
|
||||
+#elif defined(HAVE_SYS_XATTR_H)
|
||||
+#include <sys/xattr.h>
|
||||
+#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -52,6 +59,21 @@
|
||||
#include "process.h"
|
||||
#include "security.h"
|
||||
|
||||
+#ifndef XATTR_USER_PREFIX
|
||||
+#define XATTR_USER_PREFIX "user."
|
||||
+#endif
|
||||
+#ifndef XATTR_SIZE_MAX
|
||||
+#define XATTR_SIZE_MAX 65536
|
||||
+#endif
|
||||
+
|
||||
+/* We intentionally do not match the Samba 4 extended attribute for NT security descriptors (SDs):
|
||||
+ * 1) Samba stores this information using an internal data structure (we use a flat NT SD).
|
||||
+ * 2) Samba uses the attribute "security.NTACL". This attribute is within a namespace that only
|
||||
@ -50,10 +55,26 @@ index 9c94f9ba2bba..5e542b62e77e 100644
|
||||
struct file
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
@@ -204,6 +213,28 @@ int is_file_executable( const char *name )
|
||||
@@ -203,6 +225,44 @@ int is_file_executable( const char *name )
|
||||
return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" ));
|
||||
}
|
||||
|
||||
+static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
+ return fsetxattr( filedes, name, value, size, 0, 0 );
|
||||
+#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fsetxattr( filedes, name, value, size, 0 );
|
||||
+#elif defined(HAVE_SYS_EXTATTR_H)
|
||||
+ if (!xattr_valid_namespace( name )) return -1;
|
||||
+ return extattr_set_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
|
||||
+ value, size );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+{
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
@ -79,7 +100,7 @@ index 9c94f9ba2bba..5e542b62e77e 100644
|
||||
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
|
||||
unsigned int access, unsigned int sharing, int create,
|
||||
unsigned int options, unsigned int attrs,
|
||||
@@ -623,6 +654,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
@@ -622,6 +682,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
*mode = (*mode & S_IFMT) | new_mode;
|
||||
}
|
||||
|
||||
@ -90,5 +111,5 @@ index 9c94f9ba2bba..5e542b62e77e 100644
|
||||
obj->sd = new_sd;
|
||||
return 1;
|
||||
--
|
||||
2.26.2
|
||||
2.28.0
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
From 025a3715592c3f4fe8a3300422e6387f82f38792 Mon Sep 17 00:00:00 2001
|
||||
From f6264626e3a00195c740cd339043d48372005f17 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:01:35 -0600
|
||||
Subject: [PATCH] server: Retrieve file security attributes with extended file
|
||||
attributes. (try 7)
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 19 +++++++++----------
|
||||
server/file.c | 30 +++++++++++++++++++++++++++---
|
||||
2 files changed, 36 insertions(+), 13 deletions(-)
|
||||
dlls/advapi32/tests/security.c | 19 +++++++-------
|
||||
server/file.c | 46 +++++++++++++++++++++++++++++++---
|
||||
2 files changed, 52 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index a27cd41cde81..6968c9a3d2ac 100644
|
||||
index b79ea481e64..849a6b0b032 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3639,7 +3639,7 @@ static void test_CreateDirectoryA(void)
|
||||
@@ -3648,7 +3648,7 @@ static void test_CreateDirectoryA(void)
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
|
||||
@ -22,7 +22,7 @@ index a27cd41cde81..6968c9a3d2ac 100644
|
||||
LocalFree(pSD);
|
||||
|
||||
/* Test inheritance of ACLs in CreateFile without security descriptor */
|
||||
@@ -4093,21 +4093,20 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
@@ -4102,21 +4102,20 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
bret = GetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
@ -50,7 +50,7 @@ index a27cd41cde81..6968c9a3d2ac 100644
|
||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
||||
@@ -4134,8 +4133,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
@@ -4143,8 +4142,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
{
|
||||
bret = GetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get ACE.\n");
|
||||
@ -62,10 +62,33 @@ index a27cd41cde81..6968c9a3d2ac 100644
|
||||
LocalFree(pSD);
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 818bd42af76a..53d59d3e8e2a 100644
|
||||
index a659b1c7872..19d04e050ed 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -495,6 +495,29 @@ static void convert_generic_sd( struct security_descriptor *sd )
|
||||
@@ -225,6 +225,22 @@ int is_file_executable( const char *name )
|
||||
return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" ));
|
||||
}
|
||||
|
||||
+static int xattr_fget( int filedes, const char *name, void *value, size_t size )
|
||||
+{
|
||||
+#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
+ return fgetxattr( filedes, name, value, size, 0, 0 );
|
||||
+#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
|
||||
+ return fgetxattr( filedes, name, value, size );
|
||||
+#elif defined(HAVE_SYS_EXTATTR_H)
|
||||
+ if (!xattr_valid_namespace( name )) return -1;
|
||||
+ return extattr_get_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
|
||||
+ value, size );
|
||||
+#else
|
||||
+ errno = ENOSYS;
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static int xattr_fset( int filedes, const char *name, void *value, size_t size )
|
||||
{
|
||||
#if defined(XATTR_ADDITIONAL_OPTIONS)
|
||||
@@ -523,6 +539,29 @@ static void convert_generic_sd( struct security_descriptor *sd )
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +118,7 @@ index 818bd42af76a..53d59d3e8e2a 100644
|
||||
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
|
||||
uid_t *uid )
|
||||
{
|
||||
@@ -510,9 +533,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
@@ -538,9 +577,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
(st.st_uid == *uid))
|
||||
return obj->sd;
|
||||
|
||||
@ -110,5 +133,5 @@ index 818bd42af76a..53d59d3e8e2a 100644
|
||||
|
||||
*mode = st.st_mode;
|
||||
--
|
||||
2.26.2
|
||||
2.28.0
|
||||
|
||||
|
@ -1 +1 @@
|
||||
87f41e6b408dd01055ff6a378b90d089d61ec370
|
||||
314368e6c442f043ebfc22b70c1113e4e6232c04
|
||||
|
Loading…
Reference in New Issue
Block a user