mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Update and reenable ntdll-Placeholders.
This commit is contained in:
parent
27397d1764
commit
f48794a9ce
@ -1,13 +1,14 @@
|
||||
From ebca5e5a6d9e498ca1f7c0f823e40c25be547500 Mon Sep 17 00:00:00 2001
|
||||
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/ntdll/tests/virtual.c | 13 +++++++++++++
|
||||
2 files changed, 15 insertions(+)
|
||||
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
|
||||
@ -22,11 +23,24 @@ index 4188eebf181..19381e00b31 100644
|
||||
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 ffa462f579f..559ba484d60 100644
|
||||
index c125fdff0d7..549a2b12d5a 100644
|
||||
--- a/dlls/ntdll/tests/virtual.c
|
||||
+++ b/dlls/ntdll/tests/virtual.c
|
||||
@@ -1131,6 +1131,13 @@ static void test_NtMapViewOfSection(void)
|
||||
@@ -1131,6 +1131,12 @@ static void test_NtMapViewOfSection(void)
|
||||
process = create_target_process("sleep");
|
||||
ok(process != NULL, "Can't start process\n");
|
||||
|
||||
@ -35,17 +49,16 @@ index ffa462f579f..559ba484d60 100644
|
||||
+ 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);
|
||||
+ ok(!((ULONG_PTR)ptr & 0xffff), "returned memory %p is not aligned to 64k\n", ptr);
|
||||
+
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
@@ -1404,6 +1411,12 @@ static void test_NtMapViewOfSectionEx(void)
|
||||
@@ -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 = 0;
|
||||
+ 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);
|
@ -0,0 +1,76 @@
|
||||
From 9262ac863f3c124e204a0fe96fbfc9ebefa2ee84 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 a5c1c8214fa..e3df71a695c 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 */
|
||||
@@ -2760,9 +2761,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->header_size,
|
||||
@@ -2885,7 +2886,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) );
|
||||
@@ -3424,7 +3425,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
|
||||
@@ -4120,7 +4121,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
|
||||
|
@ -0,0 +1,367 @@
|
||||
From 73fa163482646dde03d10a2aaab1cb3df2d55225 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 549a2b12d5a..8b21e485736 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.Type = MemExtendedParameterAttributeFlags;
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index e3df71a695c..77b0bc4c4c8 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)
|
||||
@@ -4098,8 +4102,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;
|
||||
@@ -4107,6 +4110,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 );
|
||||
@@ -4117,6 +4126,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;
|
||||
@@ -4136,6 +4146,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 )
|
||||
@@ -4171,6 +4182,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 );
|
||||
@@ -4182,6 +4194,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;
|
||||
@@ -4284,6 +4302,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;
|
||||
@@ -4295,6 +4315,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes );
|
||||
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
|
||||
|
@ -0,0 +1,53 @@
|
||||
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
|
||||
|
@ -0,0 +1,45 @@
|
||||
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
|
||||
|
@ -0,0 +1,242 @@
|
||||
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
|
||||
|
@ -1,26 +1,18 @@
|
||||
From 2248dedbf01f0abeb4290d79c13c3b967010ba97 Mon Sep 17 00:00:00 2001
|
||||
From dc171d61ceb1aae3102063208de1b47ce58139d3 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 | 15 ++-
|
||||
dlls/ntdll/tests/virtual.c | 217 +++++++++++++++++++++++---------
|
||||
2 files changed, 171 insertions(+), 61 deletions(-)
|
||||
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 b8c3bbb7276..03f76a1b73a 100644
|
||||
index b629b61ea5d..e5185a2587d 100644
|
||||
--- a/dlls/kernelbase/tests/process.c
|
||||
+++ b/dlls/kernelbase/tests/process.c
|
||||
@@ -168,7 +168,6 @@ 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;
|
||||
|
||||
@@ -206,6 +205,20 @@ static void test_VirtualAlloc2(void)
|
||||
@@ -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");
|
||||
|
||||
@ -42,7 +34,7 @@ index b8c3bbb7276..03f76a1b73a 100644
|
||||
UnmapViewOfFile(view1);
|
||||
UnmapViewOfFile(view2);
|
||||
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
|
||||
index 335ba118fb9..3000ae68620 100644
|
||||
index 03b9106bc6b..3307c19bbea 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)
|
||||
@ -50,8 +42,8 @@ index 335ba118fb9..3000ae68620 100644
|
||||
static void test_NtAllocateVirtualMemoryEx(void)
|
||||
{
|
||||
+ MEMORY_BASIC_INFORMATION mbi;
|
||||
+ void *addresses[16];
|
||||
MEM_EXTENDED_PARAMETER ext;
|
||||
+ void *addresses[16];
|
||||
SIZE_T size, size2;
|
||||
char *p, *p1, *p2;
|
||||
+ ULONG granularity;
|
||||
@ -60,7 +52,7 @@ index 335ba118fb9..3000ae68620 100644
|
||||
void *addr1;
|
||||
|
||||
if (!pNtAllocateVirtualMemoryEx)
|
||||
@@ -332,48 +336,148 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
@@ -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);
|
||||
|
||||
@ -70,15 +62,11 @@ index 335ba118fb9..3000ae68620 100644
|
||||
+
|
||||
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);
|
||||
+ size = 0x10000;
|
||||
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
|
||||
+ PAGE_READWRITE, NULL, 0);
|
||||
@ -106,8 +94,7 @@ index 335ba118fb9..3000ae68620 100644
|
||||
+ size = 0x10000;
|
||||
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
|
||||
+ ok(!status, "Unexpected status %08lx.\n", status);
|
||||
|
||||
- /* Placeholder region splitting. */
|
||||
+
|
||||
+ 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);
|
||||
@ -145,39 +132,42 @@ index 335ba118fb9..3000ae68620 100644
|
||||
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size,
|
||||
+ MEM_WRITE_WATCH | MEM_RESERVE | MEM_REPLACE_PLACEHOLDER,
|
||||
+ PAGE_READONLY, NULL, 0);
|
||||
+ ok(!status, "Unexpected status %08lx.\n", status);
|
||||
+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Win10 1809, the version where
|
||||
+ NtAllocateVirtualMemoryEx is introduced */, "Unexpected status %08lx.\n", status);
|
||||
+
|
||||
+ size = 0x10000;
|
||||
+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT, PAGE_READWRITE, NULL, 0);
|
||||
+ ok(!status, "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");
|
||||
+ 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);
|
||||
+ trace("addr1 %p, addresses[0] %p.\n", addr1, addresses[0]);
|
||||
+ *((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 = 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. */
|
||||
+ 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,
|
||||
@ -186,126 +176,95 @@ index 335ba118fb9..3000ae68620 100644
|
||||
+ 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;
|
||||
size = 0x10000;
|
||||
status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||
@@ -349,12 +467,17 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
PAGE_NOACCESS, NULL, 0);
|
||||
- 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);
|
||||
- }
|
||||
+ 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);
|
||||
+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
|
||||
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "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);
|
||||
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;
|
||||
@@ -383,22 +487,19 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
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");
|
||||
-
|
||||
- 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);
|
||||
- }
|
||||
+ 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");
|
||||
+
|
||||
+ 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);
|
||||
|
||||
/* Split in two regions, specifying second half. */
|
||||
addr1 = NULL;
|
||||
@@ -407,23 +508,19 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
@@ -374,12 +503,19 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
PAGE_NOACCESS, NULL, 0);
|
||||
todo_wine
|
||||
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
|
||||
+ p1 = addr1;
|
||||
+ p2 = p1 + size / 2;
|
||||
|
||||
- if (status == STATUS_SUCCESS)
|
||||
- {
|
||||
- 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");
|
||||
- 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);
|
||||
- }
|
||||
+ 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");
|
||||
+ 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);
|
||||
+ 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.Type = MemExtendedParameterAttributeFlags;
|
@ -0,0 +1,202 @@
|
||||
From e3fa80eae8154f4e621601d571306a96c71c285b 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 | 53 +++++++++++++++++++++++++++-
|
||||
2 files changed, 122 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
|
||||
index 3307c19bbea..c1e194f9e7d 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;
|
||||
+ 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 07c24a31592..f7f5e44fb57 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
|
||||
@@ -2337,6 +2340,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size, BOO
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * 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
|
||||
*
|
||||
@@ -4478,13 +4527,15 @@ 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)))
|
||||
{
|
||||
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)
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 41d2b081fcdf72704cfc9a7a0e0f53215074346c Mon Sep 17 00:00:00 2001
|
||||
From cf1caf109030ac7b89dae57666ee084b23637a65 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.
|
||||
@ -8,10 +8,10 @@ Subject: [PATCH] ntdll: Factor out unmap_view_of_section() function.
|
||||
1 file changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index ed6d9be8b6f..320596c740e 100644
|
||||
index f7f5e44fb57..71a5b294940 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -5208,11 +5208,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
||||
@@ -5236,11 +5236,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
||||
return virtual_map_section( handle, addr_ptr, limit, 0, offset_ptr, size_ptr, alloc_type, protect );
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ index ed6d9be8b6f..320596c740e 100644
|
||||
{
|
||||
struct file_view *view;
|
||||
unsigned int status = STATUS_NOT_MAPPED_VIEW;
|
||||
@@ -5269,6 +5265,15 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
||||
@@ -5297,6 +5293,15 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ index ed6d9be8b6f..320596c740e 100644
|
||||
/***********************************************************************
|
||||
* NtUnmapViewOfSectionEx (NTDLL.@)
|
||||
* ZwUnmapViewOfSectionEx (NTDLL.@)
|
||||
@@ -5276,7 +5281,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
||||
@@ -5304,7 +5309,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);
|
@ -1,119 +0,0 @@
|
||||
From 5275b219783f0a85e3fad17ac0f999c98d4b7b1c 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().
|
||||
|
||||
Based on a patch by Nikolay Sivov.
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 46 +++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 39 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 7142d2adf79..85c4ab878b3 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -123,6 +123,7 @@ 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
|
||||
|
||||
/* Conversion from VPROT_* to Win32 flags */
|
||||
static const BYTE VIRTUAL_Win32Flags[16] =
|
||||
@@ -1115,6 +1116,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_PLACEHOLDER)
|
||||
+ TRACE( " (placeholder)\n" );
|
||||
else if (view->protect & SEC_IMAGE)
|
||||
TRACE( " (image)\n" );
|
||||
else if (view->protect & SEC_FILE)
|
||||
@@ -4180,7 +4183,7 @@ 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 (type == MEM_RELEASE)
|
||||
+ else if (type == MEM_RELEASE || (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER)))
|
||||
{
|
||||
/* Free the pages */
|
||||
|
||||
@@ -4190,14 +4193,15 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
{
|
||||
if (!size) size = view->size;
|
||||
|
||||
- if (size == view->size)
|
||||
+ if (type == MEM_RELEASE && size == view->size)
|
||||
{
|
||||
assert( base == view->base );
|
||||
delete_view( view );
|
||||
}
|
||||
else
|
||||
{
|
||||
- struct file_view *new_view = NULL;
|
||||
+ struct file_view *new_view = NULL, *preserve_view = NULL;
|
||||
+ int preserve_whole;
|
||||
|
||||
if (view->base != base && base + size != (char *)view->base + view->size
|
||||
&& !(new_view = alloc_view()))
|
||||
@@ -4205,7 +4209,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
ERR( "out of memory for %p-%p\n", base, (char *)base + size );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
- unregister_view( view );
|
||||
+ preserve_whole = (size == view->size);
|
||||
+ if (!preserve_whole) unregister_view( view );
|
||||
|
||||
if (new_view)
|
||||
{
|
||||
@@ -4220,7 +4225,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( new_view );
|
||||
}
|
||||
- else
|
||||
+ else if (!preserve_whole)
|
||||
{
|
||||
if (view->base == base)
|
||||
{
|
||||
@@ -4235,8 +4240,35 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
}
|
||||
|
||||
- set_page_vprot( base, size, 0 );
|
||||
- unmap_area( base, size );
|
||||
+ if (type & MEM_PRESERVE_PLACEHOLDER)
|
||||
+ {
|
||||
+ if (preserve_whole)
|
||||
+ {
|
||||
+ view->protect = VPROT_PLACEHOLDER;
|
||||
+ preserve_view = view;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!(preserve_view = alloc_view()))
|
||||
+ {
|
||||
+ ERR( "out of memory for %p-%p\n", base, (char *)base + size );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ }
|
||||
+ preserve_view->base = base;
|
||||
+ preserve_view->size = size;
|
||||
+ preserve_view->protect = VPROT_PLACEHOLDER;
|
||||
+ register_view( preserve_view );
|
||||
+ }
|
||||
+ set_page_vprot( base, size, 0 );
|
||||
+ if (anon_mmap_fixed(base, size, 0, 0) != base)
|
||||
+ ERR("anon_mmap_fixed failed, err %s.\n", strerror(errno));
|
||||
+ VIRTUAL_DEBUG_DUMP_VIEW( preserve_view );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ set_page_vprot( base, size, 0 );
|
||||
+ unmap_area( base, size );
|
||||
+ }
|
||||
}
|
||||
*addr_ptr = base;
|
||||
*size_ptr = size;
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 81be823356cc1752e878a0c26529d8a579d96a54 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 | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 418ad19d990..71cf44bec39 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -2012,8 +2012,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;
|
||||
|
||||
@@ -2230,7 +2231,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 */
|
||||
@@ -3371,7 +3372,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
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From af7dcbb2688ca53aa22421b30f02e2b7b08601ca Mon Sep 17 00:00:00 2001
|
||||
From 0242eb04e638bde912dec2c7ee189be12ad24b47 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
|
||||
@ -7,12 +7,12 @@ Subject: [PATCH] ntdll: Support MEM_PRESERVE_PLACEHOLDER in
|
||||
---
|
||||
dlls/kernelbase/tests/process.c | 53 +++++++++++++++++++++++++++++++--
|
||||
dlls/ntdll/unix/server.c | 2 +-
|
||||
dlls/ntdll/unix/virtual.c | 25 +++++++++++++---
|
||||
dlls/ntdll/unix/virtual.c | 18 ++++++++---
|
||||
server/protocol.def | 1 +
|
||||
4 files changed, 73 insertions(+), 8 deletions(-)
|
||||
4 files changed, 66 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c
|
||||
index 03f76a1b73a..448369a3743 100644
|
||||
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);
|
||||
@ -37,7 +37,7 @@ index 03f76a1b73a..448369a3743 100644
|
||||
/* 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");
|
||||
@@ -199,11 +207,20 @@ static void test_VirtualAlloc2(void)
|
||||
@@ -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");
|
||||
|
||||
@ -60,7 +60,7 @@ index 03f76a1b73a..448369a3743 100644
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
VirtualQuery(placeholder1, &info, sizeof(info));
|
||||
@@ -220,7 +237,34 @@ static void test_VirtualAlloc2(void)
|
||||
@@ -219,7 +236,34 @@ static void test_VirtualAlloc2(void)
|
||||
ok(info.RegionSize == size, "Unexpected size.\n");
|
||||
|
||||
CloseHandle(section);
|
||||
@ -96,7 +96,7 @@ index 03f76a1b73a..448369a3743 100644
|
||||
UnmapViewOfFile(view2);
|
||||
|
||||
VirtualFree(placeholder1, 0, MEM_RELEASE);
|
||||
@@ -250,6 +294,8 @@ static void test_VirtualAlloc2(void)
|
||||
@@ -249,6 +293,8 @@ static void test_VirtualAlloc2(void)
|
||||
|
||||
p1 = p;
|
||||
p2 = p + size / 2;
|
||||
@ -105,7 +105,7 @@ index 03f76a1b73a..448369a3743 100644
|
||||
ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
|
||||
ok(ret, "Failed to split a placeholder.\n");
|
||||
check_region_size(p1, size / 2);
|
||||
@@ -462,6 +508,7 @@ static void init_funcs(void)
|
||||
@@ -461,6 +507,7 @@ static void init_funcs(void)
|
||||
X(VirtualAlloc2);
|
||||
X(VirtualAlloc2FromApp);
|
||||
X(VirtualAllocFromApp);
|
||||
@ -114,10 +114,10 @@ index 03f76a1b73a..448369a3743 100644
|
||||
hmod = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
|
||||
index c143560e360..40efda551e0 100644
|
||||
index 469c012190c..f481a1394b8 100644
|
||||
--- a/dlls/ntdll/unix/server.c
|
||||
+++ b/dlls/ntdll/unix/server.c
|
||||
@@ -618,7 +618,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
||||
@@ -638,7 +638,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)
|
||||
@ -127,10 +127,10 @@ index c143560e360..40efda551e0 100644
|
||||
result->unmap_view.status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 320596c740e..493f6b80419 100644
|
||||
index 71a5b294940..2e61e8ba22f 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -5208,7 +5208,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
||||
@@ -5236,7 +5236,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
||||
return virtual_map_section( handle, addr_ptr, limit, 0, offset_ptr, size_ptr, alloc_type, protect );
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ index 320596c740e..493f6b80419 100644
|
||||
{
|
||||
struct file_view *view;
|
||||
unsigned int status = STATUS_NOT_MAPPED_VIEW;
|
||||
@@ -5223,6 +5223,7 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
|
||||
@@ -5251,6 +5251,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 );
|
||||
@ -147,11 +147,11 @@ index 320596c740e..493f6b80419 100644
|
||||
status = server_queue_process_apc( process, &call, &result );
|
||||
if (status == STATUS_SUCCESS) status = result.unmap_view.status;
|
||||
return status;
|
||||
@@ -5231,6 +5232,11 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
|
||||
@@ -5259,6 +5260,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_FROMPLACEHOLDER))
|
||||
+ if (flags & MEM_PRESERVE_PLACEHOLDER && !(view->protect & VPROT_PLACEHOLDER))
|
||||
+ {
|
||||
+ status = STATUS_CONFLICTING_ADDRESSES;
|
||||
+ goto done;
|
||||
@ -159,22 +159,15 @@ index 320596c740e..493f6b80419 100644
|
||||
if (view->protect & VPROT_SYSTEM)
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
@@ -5257,10 +5263,21 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
|
||||
@@ -5285,10 +5291,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)
|
||||
+ {
|
||||
+ view->protect = VPROT_PLACEHOLDER;
|
||||
+ set_page_vprot( view->base, view->size, 0 );
|
||||
+ if (anon_mmap_fixed(view->base, view->size, 0, 0) != view->base)
|
||||
+ ERR("anon_mmap_fixed failed, err %s.\n", strerror(errno));
|
||||
+ }
|
||||
+ view_make_placeholder( view );
|
||||
+ else
|
||||
+ {
|
||||
+ delete_view( view );
|
||||
+ }
|
||||
}
|
||||
else FIXME( "failed to unmap %p %x\n", view->base, status );
|
||||
}
|
||||
@ -182,7 +175,7 @@ index 320596c740e..493f6b80419 100644
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
return status;
|
||||
}
|
||||
@@ -5271,7 +5288,7 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
|
||||
@@ -5299,7 +5309,7 @@ NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
|
||||
*/
|
||||
NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
||||
{
|
||||
@ -191,7 +184,7 @@ index 320596c740e..493f6b80419 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -5281,7 +5298,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
||||
@@ -5309,7 +5319,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);
|
||||
@ -201,7 +194,7 @@ index 320596c740e..493f6b80419 100644
|
||||
|
||||
/******************************************************************************
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 8f5202792b4..10729e3ff64 100644
|
||||
index 0515dcb2245..9c084fdfff7 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -615,6 +615,7 @@ typedef union
|
@ -1,100 +0,0 @@
|
||||
From ed0aa7cbd5dcaad27598466c273ed4fb96c71a60 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/ntdll/unix/virtual.c | 26 ++++++++++++++++++++++++--
|
||||
1 file changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 71cf44bec39..d0f1a1d37b1 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -4045,8 +4045,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;
|
||||
@@ -4054,6 +4053,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", protect);
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
/* Reserve the memory */
|
||||
|
||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
@@ -4064,6 +4069,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;
|
||||
if (protect & PAGE_NOCACHE) vprot |= SEC_NOCACHE;
|
||||
|
||||
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
|
||||
@@ -4083,6 +4089,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_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 )
|
||||
@@ -4118,6 +4125,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 );
|
||||
@@ -4129,6 +4137,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", type);
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
@@ -4231,6 +4245,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;
|
||||
@@ -4239,6 +4255,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
||||
TRACE( "%p %p %08lx %x %08x %p %u\n",
|
||||
process, *ret, *size_ptr, (int)type, (int)protect, parameters, (int)count );
|
||||
|
||||
+ if (type & ~type_mask)
|
||||
+ {
|
||||
+ WARN("Called with wrong alloc type flags %08x.\n", type);
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
status = get_extended_params( parameters, count, &limit, &align, &attributes );
|
||||
if (status) return status;
|
||||
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,107 +0,0 @@
|
||||
From 34562a9ed59356de31669c76bdf87886ee9febe4 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 | 41 +++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 37 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index dd146126361..0f2818f563d 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -126,6 +126,7 @@ struct file_view
|
||||
/* per-mapping protection flags */
|
||||
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
|
||||
#define VPROT_PLACEHOLDER 0x0400
|
||||
+#define VPROT_FROMPLACEHOLDER 0x0800
|
||||
|
||||
/* Conversion from VPROT_* to Win32 flags */
|
||||
static const BYTE VIRTUAL_Win32Flags[16] =
|
||||
@@ -2044,6 +2045,31 @@ 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( "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)
|
||||
+ return STATUS_CONFLICTING_ADDRESSES;
|
||||
+ if (!((*view_ret)->protect & VPROT_PLACEHOLDER))
|
||||
+ {
|
||||
+ TRACE("Wrong protect %#x for MEM_REPLACE_PLACEHOLDER.\n", (*view_ret)->protect);
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+ (*view_ret)->protect = vprot | VPROT_FROMPLACEHOLDER;
|
||||
+
|
||||
+ if (!set_vprot( *view_ret, base, size, vprot | VPROT_COMMITTED ))
|
||||
+ ERR("set_protection failed.\n");
|
||||
+ if (vprot & VPROT_WRITEWATCH)
|
||||
+ reset_write_watches( base, size );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+ TRACE("MEM_REPLACE_PLACEHOLDER view not found.\n");
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
if (base)
|
||||
{
|
||||
if (is_beyond_limit( base, size, address_space_limit ))
|
||||
@@ -4048,7 +4074,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 );
|
||||
@@ -4072,7 +4098,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;
|
||||
@@ -4101,7 +4128,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 & (MEM_TOP_DOWN | MEM_REPLACE_PLACEHOLDER), vprot, limit,
|
||||
align ? align - 1 : granularity_mask );
|
||||
|
||||
if (status == STATUS_SUCCESS) base = view->base;
|
||||
@@ -4213,7 +4240,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;
|
||||
@@ -4371,6 +4398,12 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
|
||||
if (size && (char *)view->base + view->size - base < size) status = STATUS_UNABLE_TO_FREE_VM;
|
||||
else if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
|
||||
+ else if (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER) && !size) status = STATUS_INVALID_PARAMETER_3;
|
||||
+ else if (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER) && !((view->protect & VPROT_FROMPLACEHOLDER)
|
||||
+ || (view->protect & VPROT_PLACEHOLDER && size != view->size)))
|
||||
+ {
|
||||
+ status = STATUS_CONFLICTING_ADDRESSES;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
if (!size) size = view->size;
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 96519657b5925777d613f6a6c0e93bc4d85897b9 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Gofman <pgofman@codeweavers.com>
|
||||
Date: Thu, 10 Nov 2022 19:01:50 -0600
|
||||
Subject: [PATCH] ntdll: Support MEM_REPLACE_PLACEHOLDER in
|
||||
virtual_map_section().
|
||||
|
||||
Based on a patch by Nikolay Sivov.
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index a36d2c47269..7f57b436b55 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -2857,7 +2857,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 & (MEM_TOP_DOWN | MEM_REPLACE_PLACEHOLDER), vprot, limit, 0 );
|
||||
if (res) goto done;
|
||||
|
||||
TRACE( "handle=%p size=%lx offset=%s\n", handle, size, wine_dbgstr_longlong(offset.QuadPart) );
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,117 +0,0 @@
|
||||
From b7bd1f2c2c63573e47b07f178711586a1f37d765 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 | 53 +++++++++++++++++++++++++++++++++++++-
|
||||
dlls/ntdll/unix/virtual.c | 24 +++++++++++++++++
|
||||
2 files changed, 76 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
|
||||
index b41f42ac9d1..11ccca2ffb4 100644
|
||||
--- a/dlls/ntdll/tests/virtual.c
|
||||
+++ b/dlls/ntdll/tests/virtual.c
|
||||
@@ -499,11 +499,62 @@ static void test_NtAllocateVirtualMemoryEx(void)
|
||||
|
||||
check_region_size(p1, size / 4);
|
||||
check_region_size(p2, size - size / 4);
|
||||
- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE);
|
||||
+
|
||||
+ 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);
|
||||
+ 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);
|
||||
+ check_region_size(p1, size / 4);
|
||||
+ check_region_size(p2, size - size / 4);
|
||||
+
|
||||
+ 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);
|
||||
|
||||
+ 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);
|
||||
+
|
||||
/* Split in two regions, specifying second half. */
|
||||
addr1 = NULL;
|
||||
size = 0x10000;
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 60203bd4380..226c99c5512 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -4339,6 +4339,30 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||
*size_ptr = size;
|
||||
}
|
||||
}
|
||||
+ else if (type & MEM_COALESCE_PLACEHOLDERS)
|
||||
+ {
|
||||
+ struct file_view *next_view = RB_ENTRY_VALUE( rb_next( &view->entry ), struct file_view, entry );
|
||||
+
|
||||
+ if (type != (MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS)) status = STATUS_INVALID_PARAMETER_4;
|
||||
+ else if (!size) status = STATUS_INVALID_PARAMETER_3;
|
||||
+ else if (!next_view || (char *)view->base + view->size != next_view->base
|
||||
+ || base != view->base || size != view->size + next_view->size
|
||||
+ || !(view->protect & VPROT_PLACEHOLDER) || !(next_view->protect & VPROT_PLACEHOLDER))
|
||||
+ {
|
||||
+ status = STATUS_CONFLICTING_ADDRESSES;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ unregister_view( view );
|
||||
+ unregister_view( next_view );
|
||||
+
|
||||
+ view->size += next_view->size;
|
||||
+ free_view( next_view );
|
||||
+
|
||||
+ register_view( view );
|
||||
+ VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
WARN("called with wrong free type flags (%08x) !\n", (int)type);
|
||||
--
|
||||
2.38.1
|
||||
|
@ -2,4 +2,3 @@
|
||||
# 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
|
||||
Disabled: True
|
||||
|
Loading…
Reference in New Issue
Block a user