Rebase against c293cd781fb4b330b7d93171501134f86a5138b8.

This commit is contained in:
Alistair Leslie-Hughes 2023-05-26 09:22:33 +10:00
parent a580edefe1
commit 0cd181d0ce
15 changed files with 72 additions and 1197 deletions

View File

@ -1,4 +1,4 @@
From 76467d83722de864a4fa856a3c294c999468954e Mon Sep 17 00:00:00 2001
From 5be3a73fdd9728f6280a2c0b790166c94309bf73 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Mon, 25 Nov 2019 12:19:20 +0300
Subject: [PATCH] ntdll: Force virtual memory allocation order.
@ -16,7 +16,7 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568
1 file changed, 227 insertions(+), 223 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 82a0a91cf14..b189ded181b 100644
index 13aa67c2d82..fd5bb86e6de 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -1275,44 +1275,15 @@ static struct file_view *find_view_range( const void *addr, size_t size )
@ -475,8 +475,8 @@ index 82a0a91cf14..b189ded181b 100644
+
if (alloc_type & MEM_REPLACE_PLACEHOLDER)
{
if (!(*view_ret = find_view( base, 0 )))
@@ -2059,6 +2100,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
struct file_view *view;
@@ -2046,6 +2087,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
return STATUS_SUCCESS;
}
@ -485,7 +485,7 @@ index 82a0a91cf14..b189ded181b 100644
if (base)
{
if (is_beyond_limit( base, size, address_space_limit ))
@@ -2069,52 +2112,10 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
@@ -2056,52 +2099,10 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (status != STATUS_SUCCESS) return status;
ptr = base;
}
@ -540,7 +540,7 @@ index 82a0a91cf14..b189ded181b 100644
status = create_view( view_ret, ptr, size, vprot );
if (status != STATUS_SUCCESS) unmap_area( ptr, size );
return status;
@@ -3044,6 +3045,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
@@ -3050,6 +3051,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
done:
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
if (needs_close) close( unix_handle );
@ -548,7 +548,7 @@ index 82a0a91cf14..b189ded181b 100644
return res;
}
@@ -3112,6 +3114,7 @@ void virtual_init(void)
@@ -3118,6 +3120,7 @@ void virtual_init(void)
if (preload_reserve_start)
address_space_start = min( address_space_start, preload_reserve_start );
}
@ -556,7 +556,7 @@ index 82a0a91cf14..b189ded181b 100644
}
/* try to find space in a reserved area for the views and pages protection table */
@@ -5796,6 +5799,7 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
@@ -5842,6 +5845,7 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
*ret = (ULONG_PTR)base;
*size_ptr = size;
}

View File

@ -1,71 +0,0 @@
From fdf68c567063a626f6e404da32eafe93a10c0c54 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 18:40:18 -0600
Subject: [PATCH] ntdll: Handle NULL process handle in MapViewOfFile3().
Based on a patch by Nikolay Sivov.
---
dlls/kernelbase/memory.c | 2 ++
dlls/kernelbase/tests/process.c | 2 +-
dlls/ntdll/tests/virtual.c | 12 ++++++++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 4188eebf181..19381e00b31 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -265,6 +265,8 @@ LPVOID WINAPI DECLSPEC_HOTPATCH MapViewOfFile3( HANDLE handle, HANDLE process, P
LARGE_INTEGER off;
void *addr;
+ if (!process) process = GetCurrentProcess();
+
addr = baseaddr;
off.QuadPart = offset;
if (!set_ntstatus( NtMapViewOfSectionEx( handle, process, &addr, &off, &size, alloc_type, protection,
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
index 2979af39551..14eed7d8fe9 100644
--- a/dlls/kernelbase/tests/process.c
+++ b/dlls/kernelbase/tests/process.c
@@ -123,7 +123,7 @@ static void test_MapViewOfFile3(void)
ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
SetLastError(0xdeadbeef);
- ptr = pMapViewOfFile3( mapping, GetCurrentProcess(), NULL, 0, 4096, 0, PAGE_READONLY, NULL, 0);
+ ptr = pMapViewOfFile3( mapping, NULL, NULL, 0, 4096, 0, PAGE_READONLY, NULL, 0);
ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
UnmapViewOfFile( ptr );
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index c125fdff0d7..549a2b12d5a 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -1131,6 +1131,12 @@ static void test_NtMapViewOfSection(void)
process = create_target_process("sleep");
ok(process != NULL, "Can't start process\n");
+ ptr = NULL;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, NULL, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_INVALID_HANDLE, "NtMapViewOfSection returned %08lx\n", status);
+
ptr = NULL;
size = 0;
offset.QuadPart = 0;
@@ -1404,6 +1410,12 @@ static void test_NtMapViewOfSectionEx(void)
process = create_target_process("sleep");
ok(process != NULL, "Can't start process\n");
+ ptr = NULL;
+ size = 0x1000;
+ offset.QuadPart = 0;
+ status = pNtMapViewOfSectionEx(mapping, NULL, &ptr, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
+ ok(status == STATUS_INVALID_HANDLE, "Unexpected status %08lx\n", status);
+
ptr = NULL;
size = 0x1000;
offset.QuadPart = 0;
--
2.40.1

View File

@ -1,76 +0,0 @@
From da73611080701ad78b851b7d9e428744d1ce939d Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 18:48:14 -0600
Subject: [PATCH] ntdll: Pass allocation type to map_view().
Based on a patch by Nikolay Sivov.
---
dlls/ntdll/unix/virtual.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index e807754d16b..19584238d28 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2011,8 +2011,9 @@ static NTSTATUS map_fixed_area( void *base, size_t size, unsigned int vprot )
* virtual_mutex must be held by caller.
*/
static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
- int top_down, unsigned int vprot, ULONG_PTR limit, size_t align_mask )
+ unsigned int alloc_type, unsigned int vprot, ULONG_PTR limit, size_t align_mask )
{
+ int top_down = alloc_type & MEM_TOP_DOWN;
void *ptr;
NTSTATUS status;
@@ -2285,7 +2286,7 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot
if (mmap_is_in_reserved_area( low_64k, dosmem_size - 0x10000 ) != 1)
{
addr = anon_mmap_tryfixed( low_64k, dosmem_size - 0x10000, unix_prot, 0 );
- if (addr == MAP_FAILED) return map_view( view, NULL, dosmem_size, FALSE, vprot, 0, 0 );
+ if (addr == MAP_FAILED) return map_view( view, NULL, dosmem_size, 0, vprot, 0, 0 );
}
/* now try to allocate the low 64K too */
@@ -2767,9 +2768,9 @@ static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **ad
if ((ULONG_PTR)base != image_info->base) base = NULL;
if ((char *)base >= (char *)address_space_start) /* make sure the DOS area remains free */
- status = map_view( &view, base, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 );
+ status = map_view( &view, base, size, alloc_type, vprot, limit, 0 );
- if (status) status = map_view( &view, NULL, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 );
+ if (status) status = map_view( &view, NULL, size, alloc_type, vprot, limit, 0 );
if (status) goto done;
status = map_image_into_view( view, filename, unix_fd, base, image_info,
@@ -2893,7 +2894,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
- res = map_view( &view, base, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 );
+ res = map_view( &view, base, size, alloc_type, vprot, limit, 0 );
if (res) goto done;
TRACE( "handle=%p size=%lx offset=%s\n", handle, size, wine_dbgstr_longlong(offset.QuadPart) );
@@ -3463,7 +3464,7 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR limit, SIZE_T
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
- status = map_view( &view, NULL, size, FALSE, VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, limit, 0 );
+ status = map_view( &view, NULL, size, 0, VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, limit, 0 );
if (status != STATUS_SUCCESS) goto done;
#ifdef VALGRIND_STACK_REGISTER
@@ -4159,7 +4160,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
else if (is_dos_memory) status = allocate_dos_memory( &view, vprot );
- else status = map_view( &view, base, size, type & MEM_TOP_DOWN, vprot, limit,
+ else status = map_view( &view, base, size, type, vprot, limit,
align ? align - 1 : granularity_mask );
if (status == STATUS_SUCCESS) base = view->base;
--
2.40.1

View File

@ -1,367 +0,0 @@
From cfb6e0a17e03c42aa3483078390eb030edfeb271 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 18:53:10 -0600
Subject: [PATCH] ntdll: Support MEM_RESERVE_PLACEHOLDER in
NtAllocateVirtualMemoryEx().
Based on a patch by Nikolay Sivov.
---
dlls/kernelbase/tests/process.c | 37 +++++++------
dlls/ntdll/tests/virtual.c | 95 +++++++++++++++------------------
dlls/ntdll/unix/virtual.c | 30 ++++++++++-
3 files changed, 90 insertions(+), 72 deletions(-)
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
index 14eed7d8fe9..f7b321cc09f 100644
--- a/dlls/kernelbase/tests/process.c
+++ b/dlls/kernelbase/tests/process.c
@@ -168,9 +168,7 @@ static void test_VirtualAlloc2(void)
/* Placeholder splitting functionality */
placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
- todo_wine
ok(!!placeholder1, "Failed to create a placeholder range.\n");
- if (!placeholder1) return;
memset(&info, 0, sizeof(info));
VirtualQuery(placeholder1, &info, sizeof(info));
@@ -180,14 +178,14 @@ static void test_VirtualAlloc2(void)
ok(info.RegionSize == 2 * size, "Unexpected size.\n");
ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- ok(ret, "Failed to split placeholder.\n");
+ todo_wine ok(ret, "Failed to split placeholder.\n");
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");
+ todo_wine ok(info.RegionSize == size, "Unexpected size.\n");
placeholder2 = (void *)((BYTE *)placeholder1 + size);
memset(&info, 0, sizeof(info));
@@ -201,10 +199,10 @@ static void test_VirtualAlloc2(void)
ok(!!section, "Failed to create a section.\n");
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
- ok(!!view1, "Failed to map a section.\n");
+ todo_wine ok(!!view1, "Failed to map a section.\n");
view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
- ok(!!view2, "Failed to map a section.\n");
+ todo_wine ok(!!view2, "Failed to map a section.\n");
CloseHandle(section);
UnmapViewOfFile(view1);
@@ -220,16 +218,19 @@ static void test_VirtualAlloc2(void)
p1 = p + size / 2;
p2 = p1 + size / 4;
ret = VirtualFree(p1, size / 4, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- ok(ret, "Failed to split a placeholder.\n");
- check_region_size(p, size / 2);
- check_region_size(p1, size / 4);
+ todo_wine ok(ret, "Failed to split a placeholder.\n");
+ if (ret)
+ {
+ check_region_size(p, size / 2);
+ check_region_size(p1, size / 4);
+ }
check_region_size(p2, 2 * size - size / 2 - size / 4);
ret = VirtualFree(p, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p1, 0, MEM_RELEASE);
- ok(ret, "Failed to release a region.\n");
+ todo_wine ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- ok(ret, "Failed to release a region.\n");
+ todo_wine ok(ret, "Failed to release a region.\n");
/* Split in two regions, specifying lower part. */
p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
@@ -238,13 +239,14 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size / 2;
ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- ok(ret, "Failed to split a placeholder.\n");
- check_region_size(p1, size / 2);
+ todo_wine ok(ret, "Failed to split a placeholder.\n");
+ if (ret)
+ check_region_size(p1, size / 2);
check_region_size(p2, 2 * size - size / 2);
ret = VirtualFree(p1, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- ok(ret, "Failed to release a region.\n");
+ todo_wine ok(ret, "Failed to release a region.\n");
/* Split in two regions, specifying second half. */
p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
@@ -253,13 +255,14 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size;
ret = VirtualFree(p2, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- ok(ret, "Failed to split a placeholder.\n");
- check_region_size(p1, size);
+ todo_wine ok(ret, "Failed to split a placeholder.\n");
+ if (ret)
+ check_region_size(p1, size);
check_region_size(p2, size);
ret = VirtualFree(p1, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- ok(ret, "Failed to release a region.\n");
+ todo_wine ok(ret, "Failed to release a region.\n");
}
static void test_VirtualAllocFromApp(void)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index 2c8b1614b84..604e234b100 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -334,15 +334,11 @@ static void test_NtAllocateVirtualMemoryEx(void)
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
- todo_wine
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- if (addr1)
- {
- size = 0;
- status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- }
+ size = 0;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
/* Placeholder region splitting. */
@@ -351,79 +347,72 @@ static void test_NtAllocateVirtualMemoryEx(void)
size = 0x10000;
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
- todo_wine
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ p = addr1;
+ p1 = p + size / 2;
+ p2 = p1 + size / 4;
+ size2 = size / 4;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+
if (status == STATUS_SUCCESS)
{
- p = addr1;
- p1 = p + size / 2;
- p2 = p1 + 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);
-
check_region_size(p, size / 2);
check_region_size(p1, size / 4);
- check_region_size(p2, size - size / 2 - size / 4);
-
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
}
+ check_region_size(p2, size - size / 2 - size / 4);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
/* Split in two regions, specifying lower part. */
addr1 = NULL;
size = 0x10000;
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
- todo_wine
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- if (status == STATUS_SUCCESS)
- {
- p1 = addr1;
- p2 = p1 + 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);
- ok(p1 == addr1, "Unexpected address.\n");
+ p1 = addr1;
+ p2 = p1 + size / 4;
+ size2 = size / 4;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(p1 == addr1, "Unexpected address.\n");
+ if (status == STATUS_SUCCESS)
check_region_size(p1, size / 4);
- check_region_size(p2, size - size / 4);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- }
+ check_region_size(p2, size - size / 4);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
/* Split in two regions, specifying second half. */
addr1 = NULL;
size = 0x10000;
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
- todo_wine
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- if (status == STATUS_SUCCESS)
- {
- p1 = addr1;
- p2 = p1 + size / 2;
+ p1 = addr1;
+ p2 = p1 + size / 2;
- size2 = size / 2;
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- ok(p2 == p1 + size / 2, "Unexpected address.\n");
+ size2 = size / 2;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(p2 == p1 + size / 2, "Unexpected address.\n");
+ if (status == STATUS_SUCCESS)
check_region_size(p1, size / 2);
- check_region_size(p2, size / 2);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- }
+ check_region_size(p2, size / 2);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
memset( ext, 0, sizeof(ext) );
ext[0].Type = MemExtendedParameterAttributeFlags;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 19584238d28..feb93302af5 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -125,6 +125,8 @@ struct file_view
#define VPROT_WRITTEN 0x80
/* per-mapping protection flags */
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
+#define VPROT_PLACEHOLDER 0x0400
+#define VPROT_FREE_PLACEHOLDER 0x0800
/* Conversion from VPROT_* to Win32 flags */
static const BYTE VIRTUAL_Win32Flags[16] =
@@ -1157,6 +1159,8 @@ static void dump_view( struct file_view *view )
TRACE( "View: %p - %p", addr, addr + view->size - 1 );
if (view->protect & VPROT_SYSTEM)
TRACE( " (builtin image)\n" );
+ else if (view->protect & VPROT_FREE_PLACEHOLDER)
+ TRACE( " (placeholder)\n" );
else if (view->protect & SEC_IMAGE)
TRACE( " (image)\n" );
else if (view->protect & SEC_FILE)
@@ -4137,8 +4141,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
/* Compute the alloc type flags */
- if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)) ||
- (type & ~(MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET)))
+ if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
{
WARN("called with wrong alloc type flags (%08x) !\n", (int)type);
return STATUS_INVALID_PARAMETER;
@@ -4146,6 +4149,12 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
if (!arm64ec_map && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) return STATUS_INVALID_PARAMETER;
+ if (type & MEM_RESERVE_PLACEHOLDER && (protect != PAGE_NOACCESS))
+ {
+ WARN( "Wrong protect %#x for placeholder.\n", (unsigned int)protect );
+ return STATUS_INVALID_PARAMETER;
+ }
+
/* Reserve the memory */
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
@@ -4156,6 +4165,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
{
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
if (type & MEM_WRITE_WATCH) vprot |= VPROT_WRITEWATCH;
+ if (type & MEM_RESERVE_PLACEHOLDER) vprot |= VPROT_PLACEHOLDER | VPROT_FREE_PLACEHOLDER;
if (protect & PAGE_NOCACHE) vprot |= SEC_NOCACHE;
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
@@ -4175,6 +4185,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
{
if (!(view = find_view( base, size ))) status = STATUS_NOT_MAPPED_VIEW;
else if (view->protect & SEC_FILE) status = STATUS_ALREADY_COMMITTED;
+ else if (view->protect & VPROT_FREE_PLACEHOLDER) status = STATUS_CONFLICTING_ADDRESSES;
else if (!(status = set_protection( view, base, size, protect )) && (view->protect & SEC_RESERVE))
{
SERVER_START_REQ( add_mapping_committed_range )
@@ -4210,6 +4221,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR zero_bits,
SIZE_T *size_ptr, ULONG type, ULONG protect )
{
+ static const ULONG type_mask = MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET;
ULONG_PTR limit;
TRACE("%p %p %08lx %x %08x\n", process, *ret, *size_ptr, (int)type, (int)protect );
@@ -4221,6 +4233,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
if (!is_old_wow64() && zero_bits >= 32) return STATUS_INVALID_PARAMETER_3;
#endif
+ if (type & ~type_mask)
+ {
+ WARN("Called with wrong alloc type flags %08x.\n", (int)type);
+ return STATUS_INVALID_PARAMETER;
+ }
+
if (process != NtCurrentProcess())
{
apc_call_t call;
@@ -4331,6 +4349,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
ULONG protect, MEM_EXTENDED_PARAMETER *parameters,
ULONG count )
{
+ static const ULONG type_mask = MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH
+ | MEM_RESET | MEM_RESERVE_PLACEHOLDER;
ULONG_PTR limit = 0;
ULONG_PTR align = 0;
ULONG attributes = 0;
@@ -4343,6 +4363,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
status = get_extended_params( parameters, count, &limit, &align, &attributes, &machine );
if (status) return status;
+ if (type & ~type_mask)
+ {
+ WARN( "Called with wrong alloc type flags %08x.\n", (unsigned int)type );
+ return STATUS_INVALID_PARAMETER;
+ }
+
if (*ret && (align || limit)) return STATUS_INVALID_PARAMETER;
if (!*size_ptr) return STATUS_INVALID_PARAMETER;
--
2.40.1

View File

@ -1,53 +0,0 @@
From 0a88728d7d5f32e64537ae01aba70376dba736fc Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 18 May 2023 20:42:05 -0600
Subject: [PATCH] ntdll: Support MEM_REPLACE_PLACEHOLDER in map_view().
---
dlls/ntdll/unix/virtual.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 77b0bc4c4c8..bd1a7c41543 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2021,6 +2021,36 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
void *ptr;
NTSTATUS status;
+ if (alloc_type & MEM_REPLACE_PLACEHOLDER)
+ {
+ if (!(*view_ret = find_view( base, 0 )))
+ {
+ TRACE( "MEM_REPLACE_PLACEHOLDER view not found.\n" );
+ return STATUS_INVALID_PARAMETER;
+ }
+ TRACE( "found view %p, size %p, protect %#x.\n",
+ (*view_ret)->base, (void *)(*view_ret)->size, (*view_ret)->protect );
+
+ if ((*view_ret)->base != base || (*view_ret)->size != size)
+ {
+ WARN( "Wrond range.\n" );
+ return STATUS_CONFLICTING_ADDRESSES;
+ }
+
+ if (!((*view_ret)->protect & VPROT_FREE_PLACEHOLDER))
+ {
+ TRACE( "Wrong protect %#x for MEM_REPLACE_PLACEHOLDER.\n", (*view_ret)->protect );
+ return STATUS_INVALID_PARAMETER;
+ }
+ (*view_ret)->protect = vprot | VPROT_PLACEHOLDER;
+
+ if (!set_vprot( *view_ret, base, size, vprot ))
+ ERR( "set_protection failed.\n" );
+ if (vprot & VPROT_WRITEWATCH)
+ reset_write_watches( base, size );
+ return STATUS_SUCCESS;
+ }
+
if (base)
{
if (is_beyond_limit( base, size, address_space_limit ))
--
2.40.1

View File

@ -1,45 +0,0 @@
From a72bcf44146603bcc500e1d3808c0a54f2d16da8 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 18:58:26 -0600
Subject: [PATCH] ntdll: Support MEM_REPLACE_PLACEHOLDER in
NtAllocateVirtualMemoryEx().
---
dlls/ntdll/unix/virtual.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index bd1a7c41543..a8af5946221 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4108,7 +4108,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
if (*ret)
{
- if (type & MEM_RESERVE) /* Round down to 64k boundary */
+ if (type & MEM_RESERVE && !(type & MEM_REPLACE_PLACEHOLDER)) /* Round down to 64k boundary */
base = ROUND_ADDR( *ret, granularity_mask );
else
base = ROUND_ADDR( *ret, page_mask );
@@ -4132,7 +4132,8 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
/* Compute the alloc type flags */
- if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
+ if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET))
+ || (type & MEM_REPLACE_PLACEHOLDER && !(type & MEM_RESERVE)))
{
WARN("called with wrong alloc type flags (%08x) !\n", (int)type);
return STATUS_INVALID_PARAMETER;
@@ -4333,7 +4334,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
ULONG count )
{
static const ULONG type_mask = MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH
- | MEM_RESET | MEM_RESERVE_PLACEHOLDER;
+ | MEM_RESET | MEM_RESERVE_PLACEHOLDER | MEM_REPLACE_PLACEHOLDER;
ULONG_PTR limit = 0;
ULONG_PTR align = 0;
ULONG attributes = 0;
--
2.40.1

View File

@ -1,242 +0,0 @@
From 4779aa6e891f32ff0b9bd37e95ed20e4522662e7 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 10 Nov 2022 18:43:05 -0600
Subject: [PATCH] ntdll: Support MEM_PRESERVE_PLACEHOLDER in
NtFreeVirtualMemory().
---
dlls/kernelbase/tests/process.c | 35 +++++++++++-------------
dlls/ntdll/tests/virtual.c | 19 +++++--------
dlls/ntdll/unix/virtual.c | 47 ++++++++++++++++++++++++++++++---
3 files changed, 65 insertions(+), 36 deletions(-)
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
index f7b321cc09f..b629b61ea5d 100644
--- a/dlls/kernelbase/tests/process.c
+++ b/dlls/kernelbase/tests/process.c
@@ -178,14 +178,14 @@ static void test_VirtualAlloc2(void)
ok(info.RegionSize == 2 * size, "Unexpected size.\n");
ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(ret, "Failed to split placeholder.\n");
+ ok(ret, "Failed to split placeholder.\n");
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);
- todo_wine ok(info.RegionSize == size, "Unexpected size.\n");
+ ok(info.RegionSize == size, "Unexpected size.\n");
placeholder2 = (void *)((BYTE *)placeholder1 + size);
memset(&info, 0, sizeof(info));
@@ -199,10 +199,10 @@ static void test_VirtualAlloc2(void)
ok(!!section, "Failed to create a section.\n");
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
- todo_wine ok(!!view1, "Failed to map a section.\n");
+ ok(!!view1, "Failed to map a section.\n");
view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
- todo_wine ok(!!view2, "Failed to map a section.\n");
+ ok(!!view2, "Failed to map a section.\n");
CloseHandle(section);
UnmapViewOfFile(view1);
@@ -218,19 +218,16 @@ static void test_VirtualAlloc2(void)
p1 = p + size / 2;
p2 = p1 + size / 4;
ret = VirtualFree(p1, size / 4, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(ret, "Failed to split a placeholder.\n");
- if (ret)
- {
- check_region_size(p, size / 2);
- check_region_size(p1, size / 4);
- }
+ ok(ret, "Failed to split a placeholder.\n");
+ check_region_size(p, size / 2);
+ check_region_size(p1, size / 4);
check_region_size(p2, 2 * size - size / 2 - size / 4);
ret = VirtualFree(p, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p1, 0, MEM_RELEASE);
- todo_wine ok(ret, "Failed to release a region.\n");
+ ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- todo_wine ok(ret, "Failed to release a region.\n");
+ ok(ret, "Failed to release a region.\n");
/* Split in two regions, specifying lower part. */
p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
@@ -239,14 +236,13 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size / 2;
ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(ret, "Failed to split a placeholder.\n");
- if (ret)
- check_region_size(p1, size / 2);
+ ok(ret, "Failed to split a placeholder.\n");
+ check_region_size(p1, size / 2);
check_region_size(p2, 2 * size - size / 2);
ret = VirtualFree(p1, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- todo_wine ok(ret, "Failed to release a region.\n");
+ ok(ret, "Failed to release a region.\n");
/* Split in two regions, specifying second half. */
p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
@@ -255,14 +251,13 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size;
ret = VirtualFree(p2, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(ret, "Failed to split a placeholder.\n");
- if (ret)
- check_region_size(p1, size);
+ ok(ret, "Failed to split a placeholder.\n");
+ check_region_size(p1, size);
check_region_size(p2, size);
ret = VirtualFree(p1, 0, MEM_RELEASE);
ok(ret, "Failed to release a region.\n");
ret = VirtualFree(p2, 0, MEM_RELEASE);
- todo_wine ok(ret, "Failed to release a region.\n");
+ ok(ret, "Failed to release a region.\n");
}
static void test_VirtualAllocFromApp(void)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index 8b21e485736..03b9106bc6b 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -354,13 +354,10 @@ static void test_NtAllocateVirtualMemoryEx(void)
p2 = p1 + size / 4;
size2 = size / 4;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- if (status == STATUS_SUCCESS)
- {
- check_region_size(p, size / 2);
- check_region_size(p1, size / 4);
- }
+ check_region_size(p, size / 2);
+ check_region_size(p1, size / 4);
check_region_size(p2, size - size / 2 - size / 4);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE);
@@ -381,11 +378,10 @@ static void test_NtAllocateVirtualMemoryEx(void)
p2 = p1 + size / 4;
size2 = size / 4;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
ok(p1 == addr1, "Unexpected address.\n");
- if (status == STATUS_SUCCESS)
- check_region_size(p1, size / 4);
+ check_region_size(p1, size / 4);
check_region_size(p2, size - size / 4);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
@@ -404,10 +400,9 @@ static void test_NtAllocateVirtualMemoryEx(void)
size2 = size / 2;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
- todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
ok(p2 == p1 + size / 2, "Unexpected address.\n");
- if (status == STATUS_SUCCESS)
- check_region_size(p1, size / 2);
+ check_region_size(p1, size / 2);
check_region_size(p2, size / 2);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index a8af5946221..07c24a31592 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2242,18 +2242,43 @@ static NTSTATUS decommit_pages( struct file_view *view, size_t start, size_t siz
}
+/***********************************************************************
+ * view_make_placeholder
+ *
+ * Setup placeholder view.
+ * virtual_mutex must be held by caller.
+ */
+static void view_make_placeholder( struct file_view *view )
+{
+ view->protect = VPROT_PLACEHOLDER | VPROT_FREE_PLACEHOLDER;
+ set_page_vprot( view->base, view->size, 0 );
+ if (arm64ec_map) clear_arm64ec_range( view->base, view->size );
+ if (anon_mmap_fixed( view->base, view->size, PROT_NONE, 0 ) != view->base)
+ ERR( "anon_mmap_fixed failed, err %s.\n", strerror( errno ));
+}
+
+
/***********************************************************************
* free_pages
*
* Free some pages of a given view.
* virtual_mutex must be held by caller.
*/
-static NTSTATUS free_pages( struct file_view *view, char *base, size_t size )
+static NTSTATUS free_pages( struct file_view *view, char *base, size_t size, BOOL preserve_placeholder )
{
+ if (preserve_placeholder)
+ {
+ if (!size) return STATUS_INVALID_PARAMETER_3;
+ if (!(view->protect & VPROT_PLACEHOLDER)) return STATUS_CONFLICTING_ADDRESSES;
+ if (view->protect & VPROT_FREE_PLACEHOLDER && size == view->size) return STATUS_CONFLICTING_ADDRESSES;
+ }
+ else if (!size) size = view->size;
+
if (size == view->size)
{
assert( base == view->base );
- delete_view( view );
+ if (preserve_placeholder) view_make_placeholder( view );
+ else delete_view( view );
return STATUS_SUCCESS;
}
if (view->base != base && base + size != (char *)view->base + view->size)
@@ -2291,6 +2316,20 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size )
VIRTUAL_DEBUG_DUMP_VIEW( view );
}
+ if (preserve_placeholder)
+ {
+ if (!(view = alloc_view()))
+ {
+ ERR( "Out of memory for %p-%p\n", base, base + size );
+ return STATUS_NO_MEMORY;
+ }
+ view->base = base;
+ view->size = size;
+ view_make_placeholder( view );
+ register_view( view );
+ return STATUS_SUCCESS;
+ }
+
set_page_vprot( base, size, 0 );
if (arm64ec_map) clear_arm64ec_range( base, size );
unmap_area( base, size );
@@ -4441,10 +4480,10 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
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 (type == MEM_DECOMMIT) status = decommit_pages( view, base - (char *)view->base, size );
- else if (type == MEM_RELEASE)
+ else if (type == MEM_RELEASE || (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER)))
{
+ status = free_pages( view, base, size, type & MEM_PRESERVE_PLACEHOLDER );
if (!size) size = view->size;
- status = free_pages( view, base, size );
}
else status = STATUS_INVALID_PARAMETER;
--
2.40.1

View File

@ -1,273 +0,0 @@
From 0f2112fa71afccdebea36bdf357fd66a303ce870 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Wed, 9 Nov 2022 21:23:19 -0600
Subject: [PATCH] ntdll/tests: Add more tests for placeholders.
---
dlls/kernelbase/tests/process.c | 14 +++
dlls/ntdll/tests/virtual.c | 150 +++++++++++++++++++++++++++++++-
2 files changed, 160 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
index b629b61ea5d..e5185a2587d 100644
--- a/dlls/kernelbase/tests/process.c
+++ b/dlls/kernelbase/tests/process.c
@@ -204,6 +204,20 @@ static void test_VirtualAlloc2(void)
view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
ok(!!view2, "Failed to map a section.\n");
+ memset(&info, 0, sizeof(info));
+ VirtualQuery(placeholder1, &info, sizeof(info));
+ ok(info.AllocationProtect == PAGE_READWRITE, "Unexpected protection %#lx.\n", info.AllocationProtect);
+ ok(info.State == MEM_COMMIT, "Unexpected state %#lx.\n", info.State);
+ ok(info.Type == MEM_MAPPED, "Unexpected type %#lx.\n", info.Type);
+ ok(info.RegionSize == size, "Unexpected size.\n");
+
+ memset(&info, 0, sizeof(info));
+ VirtualQuery(placeholder2, &info, sizeof(info));
+ ok(info.AllocationProtect == PAGE_READWRITE, "Unexpected protection %#lx.\n", info.AllocationProtect);
+ ok(info.State == MEM_COMMIT, "Unexpected state %#lx.\n", info.State);
+ ok(info.Type == MEM_MAPPED, "Unexpected type %#lx.\n", info.Type);
+ ok(info.RegionSize == size, "Unexpected size.\n");
+
CloseHandle(section);
UnmapViewOfFile(view1);
UnmapViewOfFile(view2);
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index 1718aaf30f9..45ba58868df 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -293,10 +293,14 @@ static void check_region_size_(void *p, SIZE_T s, unsigned int line)
static void test_NtAllocateVirtualMemoryEx(void)
{
+ MEMORY_BASIC_INFORMATION mbi;
MEM_EXTENDED_PARAMETER ext[2];
+ void *addresses[16];
SIZE_T size, size2;
char *p, *p1, *p2;
+ ULONG granularity;
NTSTATUS status;
+ ULONG_PTR count;
void *addr1;
if (!pNtAllocateVirtualMemoryEx)
@@ -332,15 +336,129 @@ static void test_NtAllocateVirtualMemoryEx(void)
status = NtAllocateVirtualMemory(NtCurrentProcess(), &addr1, 0, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS);
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
+ PAGE_READWRITE, NULL, 0);
+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
+
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- size = 0;
- status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
+ PAGE_READWRITE, NULL, 0);
+ ok(!status, "Unexpected status %08lx.\n", status);
+
+ memset(addr1, 0xcc, size);
+
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(!status, "Unexpected status %08lx.\n", status);
+
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
+ PAGE_READONLY, NULL, 0);
+ ok(!status, "Unexpected status %08lx.\n", status);
+
+ ok(!*(unsigned int *)addr1, "Got %#x.\n", *(unsigned int *)addr1);
+
+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size );
+ ok(!status, "Unexpected status %08lx.\n", status);
+ ok(mbi.AllocationProtect == PAGE_READONLY, "Unexpected protection %#lx.\n", mbi.AllocationProtect);
+ ok(mbi.State == MEM_COMMIT, "Unexpected state %#lx.\n", mbi.State);
+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type);
+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n");
+
+ size = 0x10000;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(!status, "Unexpected status %08lx.\n", status);
+
+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size );
+ ok(!status, "Unexpected status %08lx.\n", status);
+ ok(mbi.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", mbi.AllocationProtect);
+ ok(mbi.State == MEM_RESERVE, "Unexpected state %#lx.\n", mbi.State);
+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type);
+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n");
+
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
+ PAGE_NOACCESS, NULL, 0);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE,
+ PAGE_NOACCESS, NULL, 0);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size = 0x1000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_REPLACE_PLACEHOLDER,
+ PAGE_NOACCESS, NULL, 0);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT, PAGE_READWRITE, NULL, 0);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
+
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
+ PAGE_READWRITE, NULL, 0);
+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
+
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size,
+ MEM_WRITE_WATCH | MEM_RESERVE | MEM_REPLACE_PLACEHOLDER,
+ PAGE_READONLY, NULL, 0);
+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Win10 1809, the version where
+ NtAllocateVirtualMemoryEx is introduced */, "Unexpected status %08lx.\n", status);
+
+ if (!status)
+ {
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT, PAGE_READWRITE, NULL, 0);
+ ok(!status, "Unexpected status %08lx.\n", status);
+
+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size );
+ ok(!status, "Unexpected status %08lx.\n", status);
+ ok(mbi.AllocationProtect == PAGE_READONLY, "Unexpected protection %#lx.\n", mbi.AllocationProtect);
+ ok(mbi.State == MEM_COMMIT, "Unexpected state %#lx.\n", mbi.State);
+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type);
+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n");
+
+ size = 0x10000;
+ count = ARRAY_SIZE(addresses);
+ status = NtGetWriteWatch( NtCurrentProcess(), WRITE_WATCH_FLAG_RESET, addr1, size,
+ addresses, &count, &granularity );
+ ok(!status, "Unexpected status %08lx.\n", status);
+ ok(!count, "Unexpected count %u.\n", (unsigned int)count);
+ *((char *)addr1 + 0x1000) = 1;
+ count = ARRAY_SIZE(addresses);
+ status = NtGetWriteWatch( NtCurrentProcess(), WRITE_WATCH_FLAG_RESET, addr1, size,
+ addresses, &count, &granularity );
+ ok(!status, "Unexpected status %08lx.\n", status);
+ ok(count == 1, "Unexpected count %u.\n", (unsigned int)count);
+ ok(addresses[0] == (char *)addr1 + 0x1000, "Unexpected address %p.\n", addresses[0]);
+
+ size = 0;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ }
/* Placeholder region splitting. */
+ addr1 = NULL;
+ size = 0x10000;
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE,
+ PAGE_NOACCESS, NULL, 0);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ p = addr1;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size, MEM_RELEASE);
+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size);
+ ok(p == addr1, "Unexpected addr %p, expected %p.\n", p, addr1);
+
/* Split in three regions. */
addr1 = NULL;
@@ -349,12 +467,17 @@ static void test_NtAllocateVirtualMemoryEx(void)
PAGE_NOACCESS, NULL, 0);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status);
+
p = addr1;
p1 = p + size / 2;
p2 = p1 + 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);
+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
+ ok(p1 == p + size / 2, "Unexpected addr %p, expected %p.\n", p, p + size / 2);
check_region_size(p, size / 2);
check_region_size(p1, size / 4);
@@ -362,10 +485,16 @@ static void test_NtAllocateVirtualMemoryEx(void)
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
+ ok(p == addr1, "Unexpected addr %p, expected %p.\n", p, addr1);
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 == p + size / 2, "Unexpected addr %p, expected %p.\n", p1, p + size / 2);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2);
+ ok(p2 == p1 + size / 4, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 4);
/* Split in two regions, specifying lower part. */
addr1 = NULL;
@@ -374,12 +503,19 @@ static void test_NtAllocateVirtualMemoryEx(void)
PAGE_NOACCESS, NULL, 0);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ size2 = 0;
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ ok(status == STATUS_INVALID_PARAMETER_3, "Unexpected status %08lx.\n", status);
+ ok(!size2, "Unexpected size %#Ix.\n", size2);
+
p1 = addr1;
p2 = p1 + 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);
ok(p1 == addr1, "Unexpected address.\n");
+ 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);
@@ -394,6 +530,7 @@ static void test_NtAllocateVirtualMemoryEx(void)
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, NULL, 0);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size);
p1 = addr1;
p2 = p1 + size / 2;
@@ -401,13 +538,18 @@ static void test_NtAllocateVirtualMemoryEx(void)
size2 = size / 2;
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
- ok(p2 == p1 + size / 2, "Unexpected address.\n");
+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2);
+ ok(p2 == p1 + size / 2, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 2);
check_region_size(p1, size / 2);
check_region_size(p2, size / 2);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2);
+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1);
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2);
+ ok(p2 == p1 + size / 2, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 2);
memset( ext, 0, sizeof(ext) );
ext[0].Type = MemExtendedParameterAttributeFlags;
--
2.40.1

View File

@ -1,4 +1,4 @@
From c1a82d397f9bf6ba20fe6966a5b1d2209c49d44b Mon Sep 17 00:00:00 2001
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
@ -6,8 +6,8 @@ Subject: [PATCH] ntdll: Support MEM_COALESCE_PLACEHOLDERS in
---
dlls/ntdll/tests/virtual.c | 72 ++++++++++++++++++++++++++++++++++++--
dlls/ntdll/unix/virtual.c | 53 +++++++++++++++++++++++++++-
2 files changed, 122 insertions(+), 3 deletions(-)
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
@ -114,7 +114,7 @@ index 45ba58868df..f5f1964e516 100644
/* Split in two regions, specifying second half. */
addr1 = NULL;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index bdb213d968e..f5634e64021 100644
index f68c5ec84d6..26d4edb019a 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -114,6 +114,9 @@ struct file_view
@ -127,7 +127,7 @@ index bdb213d968e..f5634e64021 100644
/* per-page protection flags */
#define VPROT_READ 0x01
#define VPROT_WRITE 0x02
@@ -2337,6 +2340,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size, BOO
@@ -2335,6 +2338,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size )
}
@ -180,23 +180,26 @@ index bdb213d968e..f5634e64021 100644
/***********************************************************************
* allocate_dos_memory
*
@@ -4526,13 +4575,15 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
@@ -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 if (type == MEM_DECOMMIT) status = decommit_pages( view, base - (char *)view->base, size );
else if (type == MEM_RELEASE || (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER)))
else switch (type)
{
status = free_pages( view, base, size, type & MEM_PRESERVE_PLACEHOLDER );
if (!size) size = view->size;
}
+ else if (type & MEM_COALESCE_PLACEHOLDERS) status = coalesce_placeholders( view, base, size, type );
else status = STATUS_INVALID_PARAMETER;
if (status == STATUS_SUCCESS)
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

@ -165,7 +165,7 @@ index fe2e81fbe95..fc120eaafc0 100644
if (view->protect & SEC_IMAGE) release_builtin_module( view->base );
- delete_view( view );
+ if (flags & MEM_PRESERVE_PLACEHOLDER)
+ view_make_placeholder( view );
+ remove_pages_from_view( view, view->base, view->size );
+ else
+ delete_view( view );
}

View File

@ -1,4 +1,4 @@
From b6a6f7448cb4f202edec1a2644315e745b709afe Mon Sep 17 00:00:00 2001
From 045f711cb526f02ce6a163bf8ab973b5d06a1c86 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(+), 5 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 578ef4139b8..ff15840adb6 100644
index 2688383cc9f..b0c888d13a0 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -119,6 +119,7 @@ struct file_view
@@ -122,6 +122,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) */
@@ -1072,7 +1073,7 @@ static int get_unix_prot( BYTE vprot )
#define VPROT_PLACEHOLDER 0x0400
@@ -1130,7 +1131,7 @@ static int get_unix_prot( BYTE vprot )
#if defined(__i386__)
if (vprot & VPROT_WRITECOPY)
{
@ -32,7 +32,7 @@ index 578ef4139b8..ff15840adb6 100644
prot = (prot & ~PROT_WRITE) | PROT_READ;
else
prot |= PROT_WRITE | PROT_READ;
@@ -1635,7 +1636,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
@@ -1702,7 +1703,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 578ef4139b8..ff15840adb6 100644
if (vprot & VPROT_GUARD) ret |= PAGE_GUARD;
if (map_prot & SEC_NOCACHE) ret |= PAGE_NOCACHE;
return ret;
@@ -1746,12 +1751,21 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
@@ -1813,12 +1818,21 @@ 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 */
@ -69,7 +69,7 @@ index 578ef4139b8..ff15840adb6 100644
return TRUE;
}
@@ -3325,7 +3339,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
@@ -3691,7 +3705,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
}
if (vprot & VPROT_WRITECOPY)
{
@ -79,5 +79,5 @@ index 578ef4139b8..ff15840adb6 100644
}
/* ignore fault if page is writable now */
--
2.38.1
2.40.1

View File

@ -1,14 +1,14 @@
From cf705ac3f0c220d39767670ea5cbc3cf7b35b019 Mon Sep 17 00:00:00 2001
From 41373705396aeb4703a6267148ccf663bf9a42bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 3 Mar 2016 04:52:35 +0100
Subject: [PATCH] setupapi: Rewrite DiskSpaceList logic using lists.
---
dlls/setupapi/diskspace.c | 183 +++++++++++++++++++++-----------------
1 file changed, 101 insertions(+), 82 deletions(-)
dlls/setupapi/diskspace.c | 181 +++++++++++++++++++++-----------------
1 file changed, 100 insertions(+), 81 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c
index f7f6a22ce2d..b3cc36051cd 100644
index 5b89fd5ca99..04bc2696236 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -1,6 +1,7 @@
@ -81,14 +81,14 @@ index f7f6a22ce2d..b3cc36051cd 100644
- if (rc == 0)
- return NULL;
-
- list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST));
- list = malloc(sizeof(DISKSPACELIST));
-
- list->dwDriveCount = 0;
-
- ptr = drives;
-
- while (*ptr)
+ list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list));
+ list = malloc(sizeof(*list));
+ if (list)
{
- DWORD type = GetDriveTypeW(ptr);
@ -140,8 +140,8 @@ index f7f6a22ce2d..b3cc36051cd 100644
return NULL;
}
- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST));
+ list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy));
- list_copy = malloc(sizeof(DISKSPACELIST));
+ list_copy = malloc(sizeof(*list_copy));
if (!list_copy)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@ -154,13 +154,13 @@ index f7f6a22ce2d..b3cc36051cd 100644
+
+ LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
+ {
+ file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy));
+ file_copy = malloc(sizeof(*file_copy));
+ if (!file_copy) goto error;
+
+ file_copy->path = strdupW(file->path);
+ file_copy->path = wcsdup(file->path);
+ if (!file_copy->path)
+ {
+ HeapFree(GetProcessHeap(), 0, file_copy);
+ free(file_copy);
+ goto error;
+ }
+
@ -215,7 +215,7 @@ index f7f6a22ce2d..b3cc36051cd 100644
return FALSE;
}
- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR));
- driveW = malloc((wcslen(DriveSpec) + 2) * sizeof(WCHAR));
- if (!driveW)
+ if (!required)
{
@ -245,7 +245,7 @@ index f7f6a22ce2d..b3cc36051cd 100644
+ return FALSE;
}
- HeapFree(GetProcessHeap(), 0, driveW);
- free(driveW);
+ LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
+ {
+ if (towlower(file->path[0]) == towlower(drivespec[0]) &&
@ -260,7 +260,7 @@ index f7f6a22ce2d..b3cc36051cd 100644
}
/***********************************************************************
@@ -253,10 +257,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace,
@@ -253,9 +257,24 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace,
/***********************************************************************
* SetupDestroyDiskSpaceList (SETUPAPI.@)
*/
@ -268,7 +268,6 @@ index f7f6a22ce2d..b3cc36051cd 100644
+BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace)
{
- LPDISKSPACELIST list = DiskSpace;
- HeapFree(GetProcessHeap(),0,list);
+ struct space_list *list = diskspace;
+ struct file_entry *file, *file2;
+
@ -280,15 +279,14 @@ index f7f6a22ce2d..b3cc36051cd 100644
+
+ LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry)
+ {
+ HeapFree(GetProcessHeap(), 0, file->path);
+ free(file->path);
+ list_remove(&file->entry);
+ HeapFree(GetProcessHeap(), 0, file);
+ free(file);
+ }
+
+ HeapFree(GetProcessHeap(), 0, list);
return TRUE;
free(list);
return TRUE;
}
--
2.34.1
2.40.1

View File

@ -111,7 +111,7 @@ index dcfa39b5a92..cc309f9393c 100644
+ goto done;
+ }
+
+ file->path = strdupW(fullpathW);
+ file->path = wcsdup(fullpathW);
+ if (!file->path)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);

View File

@ -1,18 +1,18 @@
From bfc1aa75005a50ac1910e727efd7ba385b653c07 Mon Sep 17 00:00:00 2001
From 3b6ade8a6088fe6030a95b8062d823eafb2bfbfd Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 24 Jan 2017 12:37:46 +0100
Subject: [PATCH] winex11: Fix alpha blending in X11DRV_UpdateLayeredWindow.
Based on a patch by Dmitry Timoshkov.
---
dlls/winex11.drv/window.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
dlls/winex11.drv/window.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 3b0ccd8d22a..2ae27dacd2a 100644
index 8399a816fa7..110865d2388 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -415,14 +415,11 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region )
@@ -424,14 +424,11 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region )
/***********************************************************************
@ -30,7 +30,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (opacity == 0xffffffff)
XDeleteProperty( display, win, x11drv_atom(_NET_WM_WINDOW_OPACITY) );
@@ -1603,7 +1600,7 @@ static void create_whole_window( struct x11drv_win_data *data )
@@ -1662,7 +1659,7 @@ static void create_whole_window( struct x11drv_win_data *data )
/* set the window opacity */
if (!NtUserGetLayeredWindowAttributes( data->hwnd, &key, &alpha, &layered_flags )) layered_flags = 0;
@ -39,7 +39,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
XFlush( data->display ); /* make sure the window exists before we start painting to it */
@@ -1735,7 +1732,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
@@ -1794,7 +1791,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
{
data->layered = FALSE;
set_window_visual( data, &default_visual, FALSE );
@ -48,7 +48,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (data->surface) set_surface_color_key( data->surface, CLR_INVALID );
}
done:
@@ -2662,7 +2659,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
@@ -2840,7 +2837,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
set_window_visual( data, &default_visual, FALSE );
if (data->whole_window)
@ -57,7 +57,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (data->surface)
set_surface_color_key( data->surface, (flags & LWA_COLORKEY) ? key : CLR_INVALID );
@@ -2686,7 +2683,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
@@ -2864,7 +2861,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
Window win = X11DRV_get_whole_window( hwnd );
if (win)
{
@ -66,7 +66,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (flags & LWA_COLORKEY)
FIXME( "LWA_COLORKEY not supported on foreign process window %p\n", hwnd );
}
@@ -2702,7 +2699,6 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
@@ -2880,7 +2877,6 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
{
struct window_surface *surface;
struct x11drv_win_data *data;
@ -74,7 +74,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID;
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *bmi = (BITMAPINFO *)buffer;
@@ -2730,6 +2726,10 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
@@ -2908,6 +2904,10 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
}
else set_surface_color_key( surface, color_key );
@ -85,7 +85,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (surface) window_surface_add_ref( surface );
mapped = data->mapped;
release_win_data( data );
@@ -2764,16 +2764,15 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
@@ -2942,17 +2942,15 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
{
intersect_rect( &rect, &rect, info->prcDirty );
memcpy( src_bits, dst_bits, bmi->bmiHeader.biSizeImage );
@ -95,15 +95,16 @@ index 3b0ccd8d22a..2ae27dacd2a 100644
if (info->pptSrc) OffsetRect( &src_rect, info->pptSrc->x, info->pptSrc->y );
NtGdiTransformPoints( info->hdcSrc, (POINT *)&src_rect, (POINT *)&src_rect, 2, NtGdiDPtoLP );
- if (info->dwFlags & ULW_ALPHA) blend = *info->pblend;
- ret = NtGdiAlphaBlend( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
+ ret = NtGdiStretchBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
info->hdcSrc, src_rect.left, src_rect.top,
src_rect.right - src_rect.left, src_rect.bottom - src_rect.top,
- (info->dwFlags & ULW_ALPHA) ? *info->pblend : blend, 0 );
- *(DWORD *)&blend, 0 );
+ SRCCOPY, 0 );
if (ret)
{
memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage );
--
2.34.1
2.40.1

View File

@ -1 +1 @@
e10da7ab2e3d151c8347802600862aa608672f6f
c293cd781fb4b330b7d93171501134f86a5138b8