Rebase against 7ed63c30e8dee3509c52e11230470be2dcfe6cf5.

This commit is contained in:
Alistair Leslie-Hughes 2023-05-31 11:01:58 +10:00
parent ba6e2398d7
commit 6173bd8b0d
9 changed files with 69 additions and 543 deletions

View File

@ -1,22 +1,22 @@
From 271f43a1fafb19e1404b05ec597b504ecad74784 Mon Sep 17 00:00:00 2001
From d4094baaba721220b0a81170d1f9e6c276dae4ae Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 12:09:22 -0500
Subject: [PATCH] ntdll: Create eventfd-based objects for semaphores.
---
dlls/ntdll/Makefile.in | 1 +
dlls/ntdll/unix/esync.c | 271 +++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/esync.c | 270 +++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/esync.h | 35 +++++
dlls/ntdll/unix/loader.c | 2 +
dlls/ntdll/unix/server.c | 4 +-
dlls/ntdll/unix/sync.c | 4 +
server/esync.c | 1 +
7 files changed, 316 insertions(+), 2 deletions(-)
7 files changed, 315 insertions(+), 2 deletions(-)
create mode 100644 dlls/ntdll/unix/esync.c
create mode 100644 dlls/ntdll/unix/esync.h
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 07688a5fcf6..4e490c475a2 100644
index f8ca3e689ec..82af2152595 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -47,6 +47,7 @@ C_SRCS = \
@ -29,10 +29,10 @@ index 07688a5fcf6..4e490c475a2 100644
unix/loadorder.c \
diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c
new file mode 100644
index 00000000000..9e1ef7d8afd
index 00000000000..7be4e03fa34
--- /dev/null
+++ b/dlls/ntdll/unix/esync.c
@@ -0,0 +1,271 @@
@@ -0,0 +1,270 @@
+/*
+ * eventfd-based synchronization objects
+ *
@ -73,7 +73,6 @@ index 00000000000..9e1ef7d8afd
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#define NONAMELESSUNION
+#include "windef.h"
+#include "winternl.h"
+#include "wine/server.h"
@ -346,10 +345,10 @@ index 00000000000..a50a755149a
+
+extern int receive_fd( obj_handle_t *handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 35f2e5f986f..4d95c29ab24 100644
index 5b8b6962b4a..92855f7cccc 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -89,6 +89,7 @@
@@ -87,6 +87,7 @@
#include "winioctl.h"
#include "winternl.h"
#include "unix_private.h"
@ -357,7 +356,7 @@ index 35f2e5f986f..4d95c29ab24 100644
#include "wine/list.h"
#include "wine/debug.h"
@@ -2188,6 +2189,7 @@ static void start_main_thread(void)
@@ -2055,6 +2056,7 @@ static void start_main_thread(void)
signal_alloc_thread( teb );
dbg_init();
startup_info_size = server_init_process();
@ -366,10 +365,10 @@ index 35f2e5f986f..4d95c29ab24 100644
init_cpu_info();
init_files();
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index b7d8733f2bc..8cd5f0474e6 100644
index 227784448d3..99563e43cc3 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -106,7 +106,7 @@ sigset_t server_block_set; /* signals to block during server calls */
@@ -103,7 +103,7 @@ sigset_t server_block_set; /* signals to block during server calls */
static int fd_socket = -1; /* socket to exchange file descriptors with the server */
static int initial_cwd = -1;
static pid_t server_pid;
@ -378,7 +377,7 @@ index b7d8733f2bc..8cd5f0474e6 100644
/* atomically exchange a 64-bit value */
static inline LONG64 interlocked_xchg64( LONG64 *dest, LONG64 val )
@@ -834,7 +834,7 @@ void wine_server_send_fd( int fd )
@@ -907,7 +907,7 @@ void wine_server_send_fd( int fd )
*
* Receive a file descriptor passed from the server.
*/
@ -388,10 +387,10 @@ index b7d8733f2bc..8cd5f0474e6 100644
struct iovec vec;
struct msghdr msghdr;
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 9112572c67d..c5f30428f79 100644
index d1e4e5ee111..b5299c323e3 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -64,6 +64,7 @@
@@ -63,6 +63,7 @@
#include "wine/server.h"
#include "wine/debug.h"
#include "unix_private.h"
@ -399,7 +398,7 @@ index 9112572c67d..c5f30428f79 100644
WINE_DEFAULT_DEBUG_CHANNEL(sync);
@@ -273,6 +274,9 @@ NTSTATUS WINAPI NtCreateSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJ
@@ -272,6 +273,9 @@ NTSTATUS WINAPI NtCreateSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJ
if (max <= 0 || initial < 0 || initial > max) return STATUS_INVALID_PARAMETER;
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
@ -410,7 +409,7 @@ index 9112572c67d..c5f30428f79 100644
{
req->access = access;
diff --git a/server/esync.c b/server/esync.c
index b9dbfa322bc..99e57eca44c 100644
index 35b4833fd4c..75ef586df30 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -41,6 +41,7 @@
@ -422,5 +421,5 @@ index b9dbfa322bc..99e57eca44c 100644
int do_esync(void)
{
--
2.38.1
2.40.1

View File

@ -1,3 +1,2 @@
Fixes: [48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated
Fixes: [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)
Depends: ntdll-Placeholders

View File

@ -1,205 +0,0 @@
From 03f652283badc478f715d50d63de4cb9064ef7f1 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 19:02:50 -0600
Subject: [PATCH] ntdll: Support MEM_COALESCE_PLACEHOLDERS in
NtFreeVirtualMemory().
---
dlls/ntdll/tests/virtual.c | 72 ++++++++++++++++++++++++++++++++++++--
dlls/ntdll/unix/virtual.c | 55 ++++++++++++++++++++++++++++-
2 files changed, 124 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index 45ba58868df..f5f1964e516 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -295,9 +295,9 @@ static void test_NtAllocateVirtualMemoryEx(void)
{
MEMORY_BASIC_INFORMATION mbi;
MEM_EXTENDED_PARAMETER ext[2];
+ char *p, *p1, *p2, *p3;
void *addresses[16];
SIZE_T size, size2;
- char *p, *p1, *p2;
ULONG granularity;
NTSTATUS status;
ULONG_PTR count;
@@ -510,6 +510,7 @@ static void test_NtAllocateVirtualMemoryEx(void)
p1 = addr1;
p2 = p1 + size / 4;
+ p3 = p2 + size / 4;
size2 = size / 4;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
@@ -517,12 +518,79 @@ static void test_NtAllocateVirtualMemoryEx(void)
ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+
+ check_region_size(p1, p2 - p1);
+ check_region_size(p2, p3 - p2);
+ check_region_size(p3, size - (p3 - p1));
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size, MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_INVALID_PARAMETER_4, "Unexpected status %08lx.\n", status);
+
+ size2 = size + 0x1000;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size2 = size - 0x1000;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ p1 = (char *)addr1 + 0x1000;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+ p1 = addr1;
+
+ size2 = 0;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_INVALID_PARAMETER_3, "Unexpected status %08lx.\n", status);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size, MEM_RELEASE);
+ ok(status == STATUS_UNABLE_TO_FREE_VM, "Unexpected status %08lx.\n", status);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size);
+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1);
+ check_region_size(p1, size);
+
+ size2 = size / 4;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1);
check_region_size(p1, size / 4);
check_region_size(p2, size - size / 4);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
+
+ size2 = size - size / 4;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), (void **)&p2, &size2, MEM_RESERVE | MEM_REPLACE_PLACEHOLDER,
+ PAGE_READWRITE, NULL, 0);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size2 = size - size / 4;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0xc000, "Unexpected size %#Ix.\n", size2);
+ ok(p2 == p1 + size / 4, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 4);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size, MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size2 = size / 4;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1);
+
+ size2 = 0;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p3, &size2, MEM_RELEASE);
+ ok(status == STATUS_MEMORY_NOT_ALLOCATED, "Unexpected status %08lx.\n", status);
/* Split in two regions, specifying second half. */
addr1 = NULL;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index f68c5ec84d6..26d4edb019a 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -114,6 +114,9 @@ struct file_view
unsigned int protect; /* protection for all pages at allocation time and SEC_* flags */
};
+/* Assert this so RB_ENTRY_VALUE() result can be checked for NULL. */
+C_ASSERT( offsetof( struct file_view, entry ) == 0 );
+
/* per-page protection flags */
#define VPROT_READ 0x01
#define VPROT_WRITE 0x02
@@ -2335,6 +2338,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size )
}
+/***********************************************************************
+ * coalesce_placeholders
+ *
+ * Coalesce placeholder views.
+ * virtual_mutex must be held by caller.
+ */
+static NTSTATUS coalesce_placeholders( struct file_view *view, char *base, size_t size, ULONG type )
+{
+ struct file_view *curr_view, *next_view;
+ unsigned int i, view_count = 0;
+ size_t views_size = 0;
+
+ if (type != (MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS)) return STATUS_INVALID_PARAMETER_4;
+ if (!size) return STATUS_INVALID_PARAMETER_3;
+ if (base != view->base) return STATUS_CONFLICTING_ADDRESSES;
+
+ curr_view = view;
+ while (curr_view->protect & VPROT_FREE_PLACEHOLDER)
+ {
+ ++view_count;
+ views_size += curr_view->size;
+ if (views_size >= size) break;
+ if (!(next_view = RB_ENTRY_VALUE( rb_next( &curr_view->entry ), struct file_view, entry ))) break;
+ if ((char *)curr_view->base + curr_view->size != next_view->base) break;
+ curr_view = next_view;
+ }
+
+ if (view_count < 2 || size != views_size) return STATUS_CONFLICTING_ADDRESSES;
+
+ for (i = 1; i < view_count; ++i)
+ {
+ curr_view = RB_ENTRY_VALUE( rb_next( &view->entry ), struct file_view, entry );
+ unregister_view( curr_view );
+ free_view( curr_view );
+ }
+
+ unregister_view( view );
+ view->size = views_size;
+ register_view( view );
+
+ VIRTUAL_DEBUG_DUMP_VIEW( view );
+
+ return STATUS_SUCCESS;
+}
+
+
/***********************************************************************
* allocate_dos_memory
*
@@ -4509,7 +4558,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
else if (!(view = find_view( base, 0 ))) status = STATUS_MEMORY_NOT_ALLOCATED;
else if (!is_view_valloc( view )) status = STATUS_INVALID_PARAMETER;
else if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
- else if ((char *)view->base + view->size - base < size) status = STATUS_UNABLE_TO_FREE_VM;
+ else if ((char *)view->base + view->size - base < size && !(type & MEM_COALESCE_PLACEHOLDERS))
+ status = STATUS_UNABLE_TO_FREE_VM;
else switch (type)
{
case MEM_DECOMMIT:
@@ -4522,6 +4572,9 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
case MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER:
status = free_pages_preserve_placeholder( view, base, size );
break;
+ case MEM_COALESCE_PLACEHOLDERS:
+ status = coalesce_placeholders( view, base, size, type );
+ break;
default:
status = STATUS_INVALID_PARAMETER;
break;
--
2.40.1

View File

@ -1,54 +0,0 @@
From 9628228a974df1aaa3649ee8b80361d4ede75b06 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Fri, 11 Nov 2022 12:41:31 -0600
Subject: [PATCH] ntdll: Factor out unmap_view_of_section() function.
---
dlls/ntdll/unix/virtual.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index f5634e64021..fe2e81fbe95 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -5288,11 +5288,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
alloc_type, protect, machine );
}
-/***********************************************************************
- * NtUnmapViewOfSection (NTDLL.@)
- * ZwUnmapViewOfSection (NTDLL.@)
- */
-NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
+NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
{
struct file_view *view;
unsigned int status = STATUS_NOT_MAPPED_VIEW;
@@ -5349,6 +5345,15 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
return status;
}
+/***********************************************************************
+ * NtUnmapViewOfSection (NTDLL.@)
+ * ZwUnmapViewOfSection (NTDLL.@)
+ */
+NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
+{
+ return unmap_view_of_section( process, addr );
+}
+
/***********************************************************************
* NtUnmapViewOfSectionEx (NTDLL.@)
* ZwUnmapViewOfSectionEx (NTDLL.@)
@@ -5356,7 +5361,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
NTSTATUS WINAPI NtUnmapViewOfSectionEx( HANDLE process, PVOID addr, ULONG flags )
{
if (flags) FIXME("Ignoring flags %#x.\n", (int)flags);
- return NtUnmapViewOfSection( process, addr );
+ return unmap_view_of_section( process, addr );
}
/******************************************************************************
--
2.40.1

View File

@ -1,210 +0,0 @@
From 5b6d1300eec9340cccf52cb7551878a82210c8fa Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Fri, 11 Nov 2022 12:54:19 -0600
Subject: [PATCH] ntdll: Support MEM_PRESERVE_PLACEHOLDER in
NtUnmapViewOfSectionEx().
---
dlls/kernelbase/tests/process.c | 53 +++++++++++++++++++++++++++++++--
dlls/ntdll/unix/server.c | 2 +-
dlls/ntdll/unix/virtual.c | 18 ++++++++---
server/protocol.def | 1 +
4 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
index e5185a2587d..d70f947d6aa 100644
--- a/dlls/kernelbase/tests/process.c
+++ b/dlls/kernelbase/tests/process.c
@@ -41,6 +41,7 @@ static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD);
static HANDLE (WINAPI *pOpenFileMappingFromApp)( ULONG, BOOL, LPCWSTR);
static HANDLE (WINAPI *pCreateFileMappingFromApp)(HANDLE, PSECURITY_ATTRIBUTES, ULONG, ULONG64, PCWSTR);
static LPVOID (WINAPI *pMapViewOfFileFromApp)(HANDLE, ULONG, ULONG64, SIZE_T);
+static BOOL (WINAPI *pUnmapViewOfFile2)(HANDLE, void *, ULONG);
static void test_CompareObjectHandles(void)
{
@@ -166,6 +167,13 @@ static void test_VirtualAlloc2(void)
ret = VirtualFree(addr, 0, MEM_RELEASE);
ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError());
+ placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
+ ok(!!placeholder1, "Failed to create a placeholder range.\n");
+ ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
+ ret = VirtualFree(placeholder1, 0, MEM_RELEASE);
+ ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError());
+
/* Placeholder splitting functionality */
placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
ok(!!placeholder1, "Failed to create a placeholder range.\n");
@@ -198,11 +206,20 @@ static void test_VirtualAlloc2(void)
section = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL);
ok(!!section, "Failed to create a section.\n");
- view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
+ view1 = pMapViewOfFile3(section, NULL, NULL, 0, size, 0, PAGE_READWRITE, NULL, 0);
ok(!!view1, "Failed to map a section.\n");
+ ret = VirtualFree( view1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
+ ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
+ ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, 0);
+ ok(ret, "Got error %lu.\n", GetLastError());
+
+ view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
+ ok(view1 == placeholder1, "Address does not match.\n");
view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
- ok(!!view2, "Failed to map a section.\n");
+ ok(view2 == placeholder2, "Address does not match.\n");
memset(&info, 0, sizeof(info));
VirtualQuery(placeholder1, &info, sizeof(info));
@@ -219,7 +236,34 @@ static void test_VirtualAlloc2(void)
ok(info.RegionSize == size, "Unexpected size.\n");
CloseHandle(section);
- UnmapViewOfFile(view1);
+ ret = pUnmapViewOfFile2(NULL, view1, MEM_PRESERVE_PLACEHOLDER);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got error %lu.\n", GetLastError());
+
+ ret = VirtualFree( placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
+
+ ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
+ ok(ret, "Got error %lu.\n", GetLastError());
+ memset(&info, 0, sizeof(info));
+ VirtualQuery(placeholder1, &info, sizeof(info));
+ ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect);
+ ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State);
+ ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type);
+ ok(info.RegionSize == size, "Unexpected size.\n");
+
+ ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got error %lu.\n", GetLastError());
+
+ ret = UnmapViewOfFile(view1);
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got error %lu.\n", GetLastError());
+
+ ret = VirtualFree( placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
+ ret = VirtualFreeEx(GetCurrentProcess(), placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
+ ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
+ ret = VirtualFree(placeholder1, 0, MEM_RELEASE);
+ ok(ret, "Got error %lu.\n", GetLastError());
+
UnmapViewOfFile(view2);
VirtualFree(placeholder1, 0, MEM_RELEASE);
@@ -249,6 +293,8 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size / 2;
+ ret = VirtualFree(p1, 0, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(ret, "Failed to split a placeholder.\n");
check_region_size(p1, size / 2);
@@ -461,6 +507,7 @@ static void init_funcs(void)
X(VirtualAlloc2);
X(VirtualAlloc2FromApp);
X(VirtualAllocFromApp);
+ X(UnmapViewOfFile2);
hmod = GetModuleHandleA("ntdll.dll");
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 5de4a7374bc..b3a8d79194f 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -624,7 +624,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
result->type = call->type;
addr = wine_server_get_ptr( call->unmap_view.addr );
if ((ULONG_PTR)addr == call->unmap_view.addr)
- result->unmap_view.status = NtUnmapViewOfSection( NtCurrentProcess(), addr );
+ result->unmap_view.status = NtUnmapViewOfSectionEx( NtCurrentProcess(), addr, call->unmap_view.flags );
else
result->unmap_view.status = STATUS_INVALID_PARAMETER;
break;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index fe2e81fbe95..fc120eaafc0 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -5288,7 +5288,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
alloc_type, protect, machine );
}
-NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
+static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
{
struct file_view *view;
unsigned int status = STATUS_NOT_MAPPED_VIEW;
@@ -5303,6 +5303,7 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
call.unmap_view.type = APC_UNMAP_VIEW;
call.unmap_view.addr = wine_server_client_ptr( addr );
+ call.unmap_view.flags = flags;
status = server_queue_process_apc( process, &call, &result );
if (status == STATUS_SUCCESS) status = result.unmap_view.status;
return status;
@@ -5311,6 +5312,11 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
if ((view = find_view( addr, 0 )) && !is_view_valloc( view ))
{
+ if (flags & MEM_PRESERVE_PLACEHOLDER && !(view->protect & VPROT_PLACEHOLDER))
+ {
+ status = STATUS_CONFLICTING_ADDRESSES;
+ goto done;
+ }
if (view->protect & VPROT_SYSTEM)
{
struct builtin_module *builtin;
@@ -5337,10 +5343,14 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
if (!status)
{
if (view->protect & SEC_IMAGE) release_builtin_module( view->base );
- delete_view( view );
+ if (flags & MEM_PRESERVE_PLACEHOLDER)
+ remove_pages_from_view( view, view->base, view->size );
+ else
+ delete_view( view );
}
else FIXME( "failed to unmap %p %x\n", view->base, status );
}
+done:
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
return status;
}
@@ -5351,7 +5361,7 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
*/
NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
{
- return unmap_view_of_section( process, addr );
+ return unmap_view_of_section( process, addr, 0 );
}
/***********************************************************************
@@ -5361,7 +5371,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
NTSTATUS WINAPI NtUnmapViewOfSectionEx( HANDLE process, PVOID addr, ULONG flags )
{
if (flags) FIXME("Ignoring flags %#x.\n", (int)flags);
- return unmap_view_of_section( process, addr );
+ return unmap_view_of_section( process, addr, flags );
}
/******************************************************************************
diff --git a/server/protocol.def b/server/protocol.def
index 4c8de97041c..40125371249 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -616,6 +616,7 @@ typedef union
enum apc_type type; /* APC_UNMAP_VIEW */
int __pad;
client_ptr_t addr; /* view address */
+ unsigned int flags; /* unmap flags */
} unmap_view;
struct
{
--
2.40.1

View File

@ -1,4 +0,0 @@
# Originally written for Proton games, specifically "King under the Mountain"
# and "Halo Infinite". Neither have been tested with upstream Wine. Added to
# wine-staging primarly because ntdll-ForceBottomUpAlloc touches the same area.
Depends: ntdll-WRITECOPY

View File

@ -1,4 +1,4 @@
From 3c53044557316db957a20471118c1481bb712a6c Mon Sep 17 00:00:00 2001
From 76aacbedda940eb85cbb98ea7207adcedcd039d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 23 Jan 2020 11:00:19 +0100
Subject: [PATCH] winex11.drv: Support XInput2 events for individual windows.
@ -6,30 +6,31 @@ Subject: [PATCH] winex11.drv: Support XInput2 events for individual windows.
This will allow us to listen to the XInput version of several events,
which can bring additional information.
---
dlls/winex11.drv/desktop.c | 1 +
dlls/winex11.drv/desktop.c | 2 ++
dlls/winex11.drv/event.c | 7 +++++
dlls/winex11.drv/mouse.c | 59 +++++++++++++++++++++++++++-----------
dlls/winex11.drv/window.c | 3 ++
dlls/winex11.drv/x11drv.h | 12 +++++++-
5 files changed, 65 insertions(+), 17 deletions(-)
5 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index bc2ba60397b..96f74478600 100644
index 168029367d3..7a8fb70059e 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -363,6 +363,7 @@ NTSTATUS x11drv_create_desktop( void *arg )
0, 0, params->width, params->height, 0, default_visual.depth, InputOutput,
@@ -379,6 +379,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
0, 0, width, height, 0, default_visual.depth, InputOutput,
default_visual.visual, CWEventMask | CWCursor | CWColormap, &win_attr );
if (!win) return FALSE;
+
+ x11drv_xinput_enable( display, win, win_attr.event_mask );
if (!create_desktop_win_data( win )) return FALSE;
XFlush( display );
X11DRV_init_desktop( win, params->width, params->height );
X11DRV_init_desktop( win, width, height );
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index f81d2338faf..93032cedf70 100644
index b33fd6e0390..af96c10bbab 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -237,6 +237,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
@@ -235,6 +235,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
return (mask & QS_MOUSEBUTTON) != 0;
#ifdef GenericEvent
case GenericEvent:
@ -44,7 +45,7 @@ index f81d2338faf..93032cedf70 100644
case MotionNotify:
case EnterNotify:
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index b0dce3b245f..0725da89f67 100644
index f9cf4a33255..edde25b7b43 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -305,20 +305,32 @@ void x11drv_xinput_init(void)
@ -157,7 +158,7 @@ index b0dce3b245f..0725da89f67 100644
#endif
}
@@ -421,7 +448,7 @@ static BOOL grab_clipping_window( const RECT *clip )
@@ -420,7 +447,7 @@ static BOOL grab_clipping_window( const RECT *clip )
}
/* enable XInput2 unless we are already clipping */
@ -166,7 +167,7 @@ index b0dce3b245f..0725da89f67 100644
if (data->xi2_state != xi_enabled)
{
@@ -451,7 +478,7 @@ static BOOL grab_clipping_window( const RECT *clip )
@@ -450,7 +477,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
@ -175,7 +176,7 @@ index b0dce3b245f..0725da89f67 100644
NtUserDestroyWindow( msg_hwnd );
return FALSE;
}
@@ -534,7 +561,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd )
@@ -533,7 +560,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd )
TRACE( "clip hwnd reset from %p\n", hwnd );
data->clip_hwnd = 0;
data->clip_reset = NtGetTickCount();
@ -185,10 +186,10 @@ index b0dce3b245f..0725da89f67 100644
}
else if (prev_clip_hwnd)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 5d9a93688c3..bfad72482e6 100644
index 63827aa1aa6..39aff46c864 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -361,6 +361,7 @@ static void sync_window_style( struct x11drv_win_data *data )
@@ -362,6 +362,7 @@ static void sync_window_style( struct x11drv_win_data *data )
int mask = get_window_attributes( data, &attr );
XChangeWindowAttributes( data->display, data->whole_window, mask, &attr );
@ -196,7 +197,7 @@ index 5d9a93688c3..bfad72482e6 100644
}
}
@@ -1599,6 +1600,7 @@ static void create_whole_window( struct x11drv_win_data *data )
@@ -1647,6 +1648,7 @@ static void create_whole_window( struct x11drv_win_data *data )
data->vis.visual, mask, &attr );
if (!data->whole_window) goto done;
@ -204,7 +205,7 @@ index 5d9a93688c3..bfad72482e6 100644
set_initial_wm_hints( data->display, data->whole_window );
set_wm_hints( data );
@@ -1911,6 +1913,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd )
@@ -1982,6 +1984,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd )
data->clip_window = XCreateWindow( data->display, root_window, 0, 0, 1, 1, 0, 0,
InputOnly, default_visual.visual,
CWOverrideRedirect | CWEventMask, &attr );
@ -213,10 +214,10 @@ index 5d9a93688c3..bfad72482e6 100644
NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window );
X11DRV_DisplayDevices_RegisterEventHandlers();
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 9fd5fb481a7..c1c5f1ac34d 100644
index 5d176a9ef14..5666cd26434 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -259,6 +259,8 @@ extern void X11DRV_ThreadDetach(void) DECLSPEC_HIDDEN;
@@ -264,6 +264,8 @@ extern void X11DRV_ThreadDetach(void) DECLSPEC_HIDDEN;
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
extern void x11drv_xinput_load(void) DECLSPEC_HIDDEN;
extern void x11drv_xinput_init(void) DECLSPEC_HIDDEN;
@ -225,7 +226,7 @@ index 9fd5fb481a7..c1c5f1ac34d 100644
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
@@ -364,6 +366,14 @@ struct x11drv_escape_flush_gl_drawable
@@ -379,6 +381,14 @@ struct x11drv_escape_flush_gl_drawable
* X11 USER driver
*/
@ -240,7 +241,7 @@ index 9fd5fb481a7..c1c5f1ac34d 100644
struct x11drv_thread_data
{
Display *display;
@@ -379,7 +389,7 @@ struct x11drv_thread_data
@@ -395,7 +405,7 @@ struct x11drv_thread_data
HWND clip_hwnd; /* message window stored in desktop while clipping is active */
DWORD clip_reset; /* time when clipping was last reset */
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
@ -250,5 +251,5 @@ index 9fd5fb481a7..c1c5f1ac34d 100644
int xi2_device_count;
XIValuatorClassInfo x_valuator;
--
2.36.1
2.40.1

View File

@ -1,4 +1,4 @@
From 03498b316b233944923db2098138f730c64b407d Mon Sep 17 00:00:00 2001
From b7fbd9046a0478532bad38ff443cf2631c8d821c Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 10 Feb 2016 15:09:29 +0800
Subject: [PATCH] winex11.drv: Add support for _NET_ACTIVE_WINDOW. (v2)
@ -18,10 +18,10 @@ For bug #2155.
8 files changed, 67 insertions(+)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 1c0708461a1..515a4db9b69 100644
index 7a2e4c3bcdd..06d856f2eb6 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -824,6 +824,10 @@ static BOOL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
@@ -838,6 +838,10 @@ static BOOL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
hdc, rect.left - dx, rect.top - dy, SRCCOPY, 0, 0 );
}
@ -32,24 +32,24 @@ index 1c0708461a1..515a4db9b69 100644
static void nulldrv_SetCapture( HWND hwnd, UINT flags )
{
}
@@ -1192,6 +1196,7 @@ static const struct user_driver_funcs lazy_load_driver =
@@ -1241,6 +1245,7 @@ static const struct user_driver_funcs lazy_load_driver =
nulldrv_ProcessEvents,
nulldrv_ReleaseDC,
nulldrv_ScrollDC,
+ nulldrv_SetActiveWindow,
nulldrv_SetCapture,
loaderdrv_SetDesktopWindow,
nulldrv_SetFocus,
loaderdrv_SetLayeredWindowAttributes,
@@ -1267,6 +1272,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version
@@ -1320,6 +1325,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version
SET_USER_FUNC(ProcessEvents);
SET_USER_FUNC(ReleaseDC);
SET_USER_FUNC(ScrollDC);
+ SET_USER_FUNC(SetActiveWindow);
SET_USER_FUNC(SetCapture);
SET_USER_FUNC(SetDesktopWindow);
SET_USER_FUNC(SetFocus);
SET_USER_FUNC(SetLayeredWindowAttributes);
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
index f768453594f..0863aed6bdc 100644
index 15dd41182b9..313b798d78e 100644
--- a/dlls/win32u/input.c
+++ b/dlls/win32u/input.c
@@ -1887,6 +1887,8 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@ -62,10 +62,10 @@ index f768453594f..0863aed6bdc 100644
if (focus)
{
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 1ae39eb9edf..3d600a2879e 100644
index 701d0c1faf6..b33fd6e0390 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -578,6 +578,9 @@ static void set_focus( Display *display, HWND hwnd, Time time )
@@ -576,6 +576,9 @@ static void set_focus( Display *display, HWND hwnd, Time time )
Window win;
GUITHREADINFO threadinfo;
@ -75,7 +75,7 @@ index 1ae39eb9edf..3d600a2879e 100644
TRACE( "setting foreground window to %p\n", hwnd );
NtUserSetForegroundWindow( hwnd );
@@ -836,6 +839,8 @@ static void focus_out( Display *display , HWND hwnd )
@@ -833,6 +836,8 @@ static void focus_out( Display *display , HWND hwnd )
if (!focus_win)
{
@ -85,22 +85,22 @@ index 1ae39eb9edf..3d600a2879e 100644
Foreground window, because in most cases the messages sent
above must have already changed the foreground window, in which
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index e26cfb5a789..476694c6737 100644
index 1f1b6fcf7e1..b28529f6669 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -416,6 +416,7 @@ static const struct user_driver_funcs x11drv_funcs =
@@ -421,6 +421,7 @@ static const struct user_driver_funcs x11drv_funcs =
.pProcessEvents = X11DRV_ProcessEvents,
.pReleaseDC = X11DRV_ReleaseDC,
.pScrollDC = X11DRV_ScrollDC,
+ .pSetActiveWindow = X11DRV_SetActiveWindow,
.pSetCapture = X11DRV_SetCapture,
.pSetDesktopWindow = X11DRV_SetDesktopWindow,
.pSetFocus = X11DRV_SetFocus,
.pSetLayeredWindowAttributes = X11DRV_SetLayeredWindowAttributes,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 17fc6d867f5..eca4b354e50 100644
index 4fa4fb59c90..63827aa1aa6 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2434,6 +2434,54 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
@@ -2431,6 +2431,54 @@ BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
}
@ -156,18 +156,18 @@ index 17fc6d867f5..eca4b354e50 100644
* SetCapture (X11DRV.@)
*/
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 2b0b79e1665..7c4cf136d8e 100644
index 2ebed5cbd52..ea3323cabce 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -228,6 +228,7 @@ extern void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
@@ -231,6 +231,7 @@ extern void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
const RECT *top_rect, DWORD flags ) DECLSPEC_HIDDEN;
extern void X11DRV_ReleaseDC( HWND hwnd, HDC hdc ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) DECLSPEC_HIDDEN;
+extern void X11DRV_SetActiveWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern void X11DRV_SetCapture( HWND hwnd, UINT flags ) DECLSPEC_HIDDEN;
extern void X11DRV_SetDesktopWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha,
DWORD flags ) DECLSPEC_HIDDEN;
@@ -377,6 +378,7 @@ struct x11drv_thread_data
@@ -382,6 +383,7 @@ struct x11drv_thread_data
Display *display;
XEvent *current_event; /* event currently being processed */
HWND grab_hwnd; /* window that currently grabs the mouse */
@ -175,7 +175,7 @@ index 2b0b79e1665..7c4cf136d8e 100644
HWND last_focus; /* last window that had focus */
XIM xim; /* input method */
HWND last_xic_hwnd; /* last xic window */
@@ -485,6 +487,7 @@ enum x11drv_atoms
@@ -488,6 +490,7 @@ enum x11drv_atoms
XATOM__ICC_PROFILE,
XATOM__KDE_NET_WM_STATE_SKIP_SWITCHER,
XATOM__MOTIF_WM_HINTS,
@ -184,10 +184,10 @@ index 2b0b79e1665..7c4cf136d8e 100644
XATOM__NET_STARTUP_INFO,
XATOM__NET_SUPPORTED,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 797e4f92d38..d0c8d8a28e1 100644
index 5b79e6ce7c7..c16f38286a6 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -157,6 +157,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
@@ -154,6 +154,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"_ICC_PROFILE",
"_KDE_NET_WM_STATE_SKIP_SWITCHER",
"_MOTIF_WM_HINTS",
@ -196,17 +196,17 @@ index 797e4f92d38..d0c8d8a28e1 100644
"_NET_STARTUP_INFO",
"_NET_SUPPORTED",
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index dca03934a44..5801995705a 100644
index 8561d0fc52b..cb0a8b1a957 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -311,6 +311,7 @@ struct user_driver_funcs
@@ -316,6 +316,7 @@ struct user_driver_funcs
BOOL (*pProcessEvents)(DWORD);
void (*pReleaseDC)(HWND,HDC);
BOOL (*pScrollDC)(HDC,INT,INT,HRGN);
+ void (*pSetActiveWindow)(HWND);
void (*pSetCapture)(HWND,UINT);
void (*pSetDesktopWindow)(HWND);
void (*pSetFocus)(HWND);
void (*pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
--
2.39.0
2.40.1

View File

@ -1 +1 @@
d0d472bb3e8680e286e404a73fceb29cebe85b73
7ed63c30e8dee3509c52e11230470be2dcfe6cf5