From 0cd181d0cea4770640325a55daf9f312eb206331 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 26 May 2023 09:22:33 +1000 Subject: [PATCH] Rebase against c293cd781fb4b330b7d93171501134f86a5138b8. --- ...orce-virtual-memory-allocation-order.patch | 16 +- ...ULL-process-handle-in-MapViewOfFile3.patch | 71 ---- ...dll-Pass-allocation-type-to-map_view.patch | 76 ---- ...M_RESERVE_PLACEHOLDER-in-NtAllocateV.patch | 367 ------------------ ...-MEM_REPLACE_PLACEHOLDER-in-map_view.patch | 53 --- ...M_REPLACE_PLACEHOLDER-in-NtAllocateV.patch | 45 --- ...M_PRESERVE_PLACEHOLDER-in-NtFreeVirt.patch | 242 ------------ ...ests-Add-more-tests-for-placeholders.patch | 273 ------------- ...M_COALESCE_PLACEHOLDERS-in-NtFreeVir.patch | 33 +- ...M_PRESERVE_PLACEHOLDER-in-NtUnmapVie.patch | 2 +- ...f-a-WRITECOPY-page-has-been-modified.patch | 18 +- ...rite-DiskSpaceList-logic-using-lists.patch | 40 +- ...pi-Implement-SetupAddToDiskSpaceList.patch | 2 +- ...a-blending-in-X11DRV_UpdateLayeredWi.patch | 29 +- staging/upstream-commit | 2 +- 15 files changed, 72 insertions(+), 1197 deletions(-) delete mode 100644 patches/ntdll-Placeholders/0001-ntdll-Handle-NULL-process-handle-in-MapViewOfFile3.patch delete mode 100644 patches/ntdll-Placeholders/0002-ntdll-Pass-allocation-type-to-map_view.patch delete mode 100644 patches/ntdll-Placeholders/0003-ntdll-Support-MEM_RESERVE_PLACEHOLDER-in-NtAllocateV.patch delete mode 100644 patches/ntdll-Placeholders/0004-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-map_view.patch delete mode 100644 patches/ntdll-Placeholders/0005-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-NtAllocateV.patch delete mode 100644 patches/ntdll-Placeholders/0006-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtFreeVirt.patch delete mode 100644 patches/ntdll-Placeholders/0007-ntdll-tests-Add-more-tests-for-placeholders.patch diff --git a/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch b/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch index 69eb2b3d..6ac41038 100644 --- a/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch +++ b/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch @@ -1,4 +1,4 @@ -From 76467d83722de864a4fa856a3c294c999468954e Mon Sep 17 00:00:00 2001 +From 5be3a73fdd9728f6280a2c0b790166c94309bf73 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Mon, 25 Nov 2019 12:19:20 +0300 Subject: [PATCH] ntdll: Force virtual memory allocation order. @@ -16,7 +16,7 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568 1 file changed, 227 insertions(+), 223 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 82a0a91cf14..b189ded181b 100644 +index 13aa67c2d82..fd5bb86e6de 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -1275,44 +1275,15 @@ static struct file_view *find_view_range( const void *addr, size_t size ) @@ -475,8 +475,8 @@ index 82a0a91cf14..b189ded181b 100644 + if (alloc_type & MEM_REPLACE_PLACEHOLDER) { - if (!(*view_ret = find_view( base, 0 ))) -@@ -2059,6 +2100,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, + struct file_view *view; +@@ -2046,6 +2087,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, return STATUS_SUCCESS; } @@ -485,7 +485,7 @@ index 82a0a91cf14..b189ded181b 100644 if (base) { if (is_beyond_limit( base, size, address_space_limit )) -@@ -2069,52 +2112,10 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, +@@ -2056,52 +2099,10 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, if (status != STATUS_SUCCESS) return status; ptr = base; } @@ -540,7 +540,7 @@ index 82a0a91cf14..b189ded181b 100644 status = create_view( view_ret, ptr, size, vprot ); if (status != STATUS_SUCCESS) unmap_area( ptr, size ); return status; -@@ -3044,6 +3045,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P +@@ -3050,6 +3051,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P done: server_leave_uninterrupted_section( &virtual_mutex, &sigset ); if (needs_close) close( unix_handle ); @@ -548,7 +548,7 @@ index 82a0a91cf14..b189ded181b 100644 return res; } -@@ -3112,6 +3114,7 @@ void virtual_init(void) +@@ -3118,6 +3120,7 @@ void virtual_init(void) if (preload_reserve_start) address_space_start = min( address_space_start, preload_reserve_start ); } @@ -556,7 +556,7 @@ index 82a0a91cf14..b189ded181b 100644 } /* try to find space in a reserved area for the views and pages protection table */ -@@ -5796,6 +5799,7 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL +@@ -5842,6 +5845,7 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL *ret = (ULONG_PTR)base; *size_ptr = size; } diff --git a/patches/ntdll-Placeholders/0001-ntdll-Handle-NULL-process-handle-in-MapViewOfFile3.patch b/patches/ntdll-Placeholders/0001-ntdll-Handle-NULL-process-handle-in-MapViewOfFile3.patch deleted file mode 100644 index 85bba7f5..00000000 --- a/patches/ntdll-Placeholders/0001-ntdll-Handle-NULL-process-handle-in-MapViewOfFile3.patch +++ /dev/null @@ -1,71 +0,0 @@ -From fdf68c567063a626f6e404da32eafe93a10c0c54 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Thu, 10 Nov 2022 18:40:18 -0600 -Subject: [PATCH] ntdll: Handle NULL process handle in MapViewOfFile3(). - -Based on a patch by Nikolay Sivov. ---- - dlls/kernelbase/memory.c | 2 ++ - dlls/kernelbase/tests/process.c | 2 +- - dlls/ntdll/tests/virtual.c | 12 ++++++++++++ - 3 files changed, 15 insertions(+), 1 deletion(-) - -diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c -index 4188eebf181..19381e00b31 100644 ---- a/dlls/kernelbase/memory.c -+++ b/dlls/kernelbase/memory.c -@@ -265,6 +265,8 @@ LPVOID WINAPI DECLSPEC_HOTPATCH MapViewOfFile3( HANDLE handle, HANDLE process, P - LARGE_INTEGER off; - void *addr; - -+ if (!process) process = GetCurrentProcess(); -+ - addr = baseaddr; - off.QuadPart = offset; - if (!set_ntstatus( NtMapViewOfSectionEx( handle, process, &addr, &off, &size, alloc_type, protection, -diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c -index 2979af39551..14eed7d8fe9 100644 ---- a/dlls/kernelbase/tests/process.c -+++ b/dlls/kernelbase/tests/process.c -@@ -123,7 +123,7 @@ static void test_MapViewOfFile3(void) - ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() ); - - SetLastError(0xdeadbeef); -- ptr = pMapViewOfFile3( mapping, GetCurrentProcess(), NULL, 0, 4096, 0, PAGE_READONLY, NULL, 0); -+ ptr = pMapViewOfFile3( mapping, NULL, NULL, 0, 4096, 0, PAGE_READONLY, NULL, 0); - ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() ); - UnmapViewOfFile( ptr ); - -diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c -index c125fdff0d7..549a2b12d5a 100644 ---- a/dlls/ntdll/tests/virtual.c -+++ b/dlls/ntdll/tests/virtual.c -@@ -1131,6 +1131,12 @@ static void test_NtMapViewOfSection(void) - process = create_target_process("sleep"); - ok(process != NULL, "Can't start process\n"); - -+ ptr = NULL; -+ size = 0; -+ offset.QuadPart = 0; -+ status = NtMapViewOfSection(mapping, NULL, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE); -+ ok(status == STATUS_INVALID_HANDLE, "NtMapViewOfSection returned %08lx\n", status); -+ - ptr = NULL; - size = 0; - offset.QuadPart = 0; -@@ -1404,6 +1410,12 @@ static void test_NtMapViewOfSectionEx(void) - process = create_target_process("sleep"); - ok(process != NULL, "Can't start process\n"); - -+ ptr = NULL; -+ size = 0x1000; -+ offset.QuadPart = 0; -+ status = pNtMapViewOfSectionEx(mapping, NULL, &ptr, &offset, &size, 0, PAGE_READWRITE, NULL, 0); -+ ok(status == STATUS_INVALID_HANDLE, "Unexpected status %08lx\n", status); -+ - ptr = NULL; - size = 0x1000; - offset.QuadPart = 0; --- -2.40.1 - diff --git a/patches/ntdll-Placeholders/0002-ntdll-Pass-allocation-type-to-map_view.patch b/patches/ntdll-Placeholders/0002-ntdll-Pass-allocation-type-to-map_view.patch deleted file mode 100644 index 19f679fb..00000000 --- a/patches/ntdll-Placeholders/0002-ntdll-Pass-allocation-type-to-map_view.patch +++ /dev/null @@ -1,76 +0,0 @@ -From da73611080701ad78b851b7d9e428744d1ce939d Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Thu, 10 Nov 2022 18:48:14 -0600 -Subject: [PATCH] ntdll: Pass allocation type to map_view(). - -Based on a patch by Nikolay Sivov. ---- - dlls/ntdll/unix/virtual.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index e807754d16b..19584238d28 100644 ---- a/dlls/ntdll/unix/virtual.c -+++ b/dlls/ntdll/unix/virtual.c -@@ -2011,8 +2011,9 @@ static NTSTATUS map_fixed_area( void *base, size_t size, unsigned int vprot ) - * virtual_mutex must be held by caller. - */ - static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, -- int top_down, unsigned int vprot, ULONG_PTR limit, size_t align_mask ) -+ unsigned int alloc_type, unsigned int vprot, ULONG_PTR limit, size_t align_mask ) - { -+ int top_down = alloc_type & MEM_TOP_DOWN; - void *ptr; - NTSTATUS status; - -@@ -2285,7 +2286,7 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot - if (mmap_is_in_reserved_area( low_64k, dosmem_size - 0x10000 ) != 1) - { - addr = anon_mmap_tryfixed( low_64k, dosmem_size - 0x10000, unix_prot, 0 ); -- if (addr == MAP_FAILED) return map_view( view, NULL, dosmem_size, FALSE, vprot, 0, 0 ); -+ if (addr == MAP_FAILED) return map_view( view, NULL, dosmem_size, 0, vprot, 0, 0 ); - } - - /* now try to allocate the low 64K too */ -@@ -2767,9 +2768,9 @@ static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **ad - if ((ULONG_PTR)base != image_info->base) base = NULL; - - if ((char *)base >= (char *)address_space_start) /* make sure the DOS area remains free */ -- status = map_view( &view, base, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 ); -+ status = map_view( &view, base, size, alloc_type, vprot, limit, 0 ); - -- if (status) status = map_view( &view, NULL, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 ); -+ if (status) status = map_view( &view, NULL, size, alloc_type, vprot, limit, 0 ); - if (status) goto done; - - status = map_image_into_view( view, filename, unix_fd, base, image_info, -@@ -2893,7 +2894,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P - - server_enter_uninterrupted_section( &virtual_mutex, &sigset ); - -- res = map_view( &view, base, size, alloc_type & MEM_TOP_DOWN, vprot, limit, 0 ); -+ res = map_view( &view, base, size, alloc_type, vprot, limit, 0 ); - if (res) goto done; - - TRACE( "handle=%p size=%lx offset=%s\n", handle, size, wine_dbgstr_longlong(offset.QuadPart) ); -@@ -3463,7 +3464,7 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR limit, SIZE_T - - server_enter_uninterrupted_section( &virtual_mutex, &sigset ); - -- status = map_view( &view, NULL, size, FALSE, VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, limit, 0 ); -+ status = map_view( &view, NULL, size, 0, VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, limit, 0 ); - if (status != STATUS_SUCCESS) goto done; - - #ifdef VALGRIND_STACK_REGISTER -@@ -4159,7 +4160,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - - if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION; - else if (is_dos_memory) status = allocate_dos_memory( &view, vprot ); -- else status = map_view( &view, base, size, type & MEM_TOP_DOWN, vprot, limit, -+ else status = map_view( &view, base, size, type, vprot, limit, - align ? align - 1 : granularity_mask ); - - if (status == STATUS_SUCCESS) base = view->base; --- -2.40.1 - diff --git a/patches/ntdll-Placeholders/0003-ntdll-Support-MEM_RESERVE_PLACEHOLDER-in-NtAllocateV.patch b/patches/ntdll-Placeholders/0003-ntdll-Support-MEM_RESERVE_PLACEHOLDER-in-NtAllocateV.patch deleted file mode 100644 index 728dfe25..00000000 --- a/patches/ntdll-Placeholders/0003-ntdll-Support-MEM_RESERVE_PLACEHOLDER-in-NtAllocateV.patch +++ /dev/null @@ -1,367 +0,0 @@ -From cfb6e0a17e03c42aa3483078390eb030edfeb271 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Thu, 10 Nov 2022 18:53:10 -0600 -Subject: [PATCH] ntdll: Support MEM_RESERVE_PLACEHOLDER in - NtAllocateVirtualMemoryEx(). - -Based on a patch by Nikolay Sivov. ---- - dlls/kernelbase/tests/process.c | 37 +++++++------ - dlls/ntdll/tests/virtual.c | 95 +++++++++++++++------------------ - dlls/ntdll/unix/virtual.c | 30 ++++++++++- - 3 files changed, 90 insertions(+), 72 deletions(-) - -diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c -index 14eed7d8fe9..f7b321cc09f 100644 ---- a/dlls/kernelbase/tests/process.c -+++ b/dlls/kernelbase/tests/process.c -@@ -168,9 +168,7 @@ static void test_VirtualAlloc2(void) - - /* Placeholder splitting functionality */ - placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); -- todo_wine - ok(!!placeholder1, "Failed to create a placeholder range.\n"); -- if (!placeholder1) return; - - memset(&info, 0, sizeof(info)); - VirtualQuery(placeholder1, &info, sizeof(info)); -@@ -180,14 +178,14 @@ static void test_VirtualAlloc2(void) - ok(info.RegionSize == 2 * size, "Unexpected size.\n"); - - ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(ret, "Failed to split placeholder.\n"); -+ todo_wine ok(ret, "Failed to split placeholder.\n"); - - memset(&info, 0, sizeof(info)); - VirtualQuery(placeholder1, &info, sizeof(info)); - ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); - ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); - ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); -- ok(info.RegionSize == size, "Unexpected size.\n"); -+ todo_wine ok(info.RegionSize == size, "Unexpected size.\n"); - - placeholder2 = (void *)((BYTE *)placeholder1 + size); - memset(&info, 0, sizeof(info)); -@@ -201,10 +199,10 @@ static void test_VirtualAlloc2(void) - ok(!!section, "Failed to create a section.\n"); - - view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); -- ok(!!view1, "Failed to map a section.\n"); -+ todo_wine ok(!!view1, "Failed to map a section.\n"); - - view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); -- ok(!!view2, "Failed to map a section.\n"); -+ todo_wine ok(!!view2, "Failed to map a section.\n"); - - CloseHandle(section); - UnmapViewOfFile(view1); -@@ -220,16 +218,19 @@ static void test_VirtualAlloc2(void) - p1 = p + size / 2; - p2 = p1 + size / 4; - ret = VirtualFree(p1, size / 4, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(ret, "Failed to split a placeholder.\n"); -- check_region_size(p, size / 2); -- check_region_size(p1, size / 4); -+ todo_wine ok(ret, "Failed to split a placeholder.\n"); -+ if (ret) -+ { -+ check_region_size(p, size / 2); -+ check_region_size(p1, size / 4); -+ } - check_region_size(p2, 2 * size - size / 2 - size / 4); - ret = VirtualFree(p, 0, MEM_RELEASE); - ok(ret, "Failed to release a region.\n"); - ret = VirtualFree(p1, 0, MEM_RELEASE); -- ok(ret, "Failed to release a region.\n"); -+ todo_wine ok(ret, "Failed to release a region.\n"); - ret = VirtualFree(p2, 0, MEM_RELEASE); -- ok(ret, "Failed to release a region.\n"); -+ todo_wine ok(ret, "Failed to release a region.\n"); - - /* Split in two regions, specifying lower part. */ - p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); -@@ -238,13 +239,14 @@ static void test_VirtualAlloc2(void) - p1 = p; - p2 = p + size / 2; - ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(ret, "Failed to split a placeholder.\n"); -- check_region_size(p1, size / 2); -+ todo_wine ok(ret, "Failed to split a placeholder.\n"); -+ if (ret) -+ check_region_size(p1, size / 2); - check_region_size(p2, 2 * size - size / 2); - ret = VirtualFree(p1, 0, MEM_RELEASE); - ok(ret, "Failed to release a region.\n"); - ret = VirtualFree(p2, 0, MEM_RELEASE); -- ok(ret, "Failed to release a region.\n"); -+ todo_wine ok(ret, "Failed to release a region.\n"); - - /* Split in two regions, specifying second half. */ - p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); -@@ -253,13 +255,14 @@ static void test_VirtualAlloc2(void) - p1 = p; - p2 = p + size; - ret = VirtualFree(p2, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(ret, "Failed to split a placeholder.\n"); -- check_region_size(p1, size); -+ todo_wine ok(ret, "Failed to split a placeholder.\n"); -+ if (ret) -+ check_region_size(p1, size); - check_region_size(p2, size); - ret = VirtualFree(p1, 0, MEM_RELEASE); - ok(ret, "Failed to release a region.\n"); - ret = VirtualFree(p2, 0, MEM_RELEASE); -- ok(ret, "Failed to release a region.\n"); -+ todo_wine ok(ret, "Failed to release a region.\n"); - } - - static void test_VirtualAllocFromApp(void) -diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c -index 2c8b1614b84..604e234b100 100644 ---- a/dlls/ntdll/tests/virtual.c -+++ b/dlls/ntdll/tests/virtual.c -@@ -334,15 +334,11 @@ static void test_NtAllocateVirtualMemoryEx(void) - - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); -- todo_wine - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -- if (addr1) -- { -- size = 0; -- status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- } -+ size = 0; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - - /* Placeholder region splitting. */ - -@@ -351,79 +347,72 @@ static void test_NtAllocateVirtualMemoryEx(void) - size = 0x10000; - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); -- todo_wine - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -+ p = addr1; -+ p1 = p + size / 2; -+ p2 = p1 + size / 4; -+ size2 = size / 4; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ - if (status == STATUS_SUCCESS) - { -- p = addr1; -- p1 = p + size / 2; -- p2 = p1 + size / 4; -- size2 = size / 4; -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- - check_region_size(p, size / 2); - check_region_size(p1, size / 4); -- check_region_size(p2, size - size / 2 - size / 4); -- -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - } -+ check_region_size(p2, size - size / 2 - size / 4); -+ -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - - /* Split in two regions, specifying lower part. */ - addr1 = NULL; - size = 0x10000; - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); -- todo_wine - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -- if (status == STATUS_SUCCESS) -- { -- p1 = addr1; -- p2 = p1 + size / 4; -- size2 = size / 4; -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- ok(p1 == addr1, "Unexpected address.\n"); -+ p1 = addr1; -+ p2 = p1 + size / 4; -+ size2 = size / 4; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(p1 == addr1, "Unexpected address.\n"); - -+ if (status == STATUS_SUCCESS) - check_region_size(p1, size / 4); -- check_region_size(p2, size - size / 4); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- } -+ check_region_size(p2, size - size / 4); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - - /* Split in two regions, specifying second half. */ - addr1 = NULL; - size = 0x10000; - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); -- todo_wine - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -- if (status == STATUS_SUCCESS) -- { -- p1 = addr1; -- p2 = p1 + size / 2; -+ p1 = addr1; -+ p2 = p1 + size / 2; - -- size2 = size / 2; -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- ok(p2 == p1 + size / 2, "Unexpected address.\n"); -+ size2 = size / 2; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(p2 == p1 + size / 2, "Unexpected address.\n"); -+ if (status == STATUS_SUCCESS) - check_region_size(p1, size / 2); -- check_region_size(p2, size / 2); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- } -+ check_region_size(p2, size / 2); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - - memset( ext, 0, sizeof(ext) ); - ext[0].Type = MemExtendedParameterAttributeFlags; -diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 19584238d28..feb93302af5 100644 ---- a/dlls/ntdll/unix/virtual.c -+++ b/dlls/ntdll/unix/virtual.c -@@ -125,6 +125,8 @@ struct file_view - #define VPROT_WRITTEN 0x80 - /* per-mapping protection flags */ - #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ -+#define VPROT_PLACEHOLDER 0x0400 -+#define VPROT_FREE_PLACEHOLDER 0x0800 - - /* Conversion from VPROT_* to Win32 flags */ - static const BYTE VIRTUAL_Win32Flags[16] = -@@ -1157,6 +1159,8 @@ static void dump_view( struct file_view *view ) - TRACE( "View: %p - %p", addr, addr + view->size - 1 ); - if (view->protect & VPROT_SYSTEM) - TRACE( " (builtin image)\n" ); -+ else if (view->protect & VPROT_FREE_PLACEHOLDER) -+ TRACE( " (placeholder)\n" ); - else if (view->protect & SEC_IMAGE) - TRACE( " (image)\n" ); - else if (view->protect & SEC_FILE) -@@ -4137,8 +4141,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - - /* Compute the alloc type flags */ - -- if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)) || -- (type & ~(MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET))) -+ if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET))) - { - WARN("called with wrong alloc type flags (%08x) !\n", (int)type); - return STATUS_INVALID_PARAMETER; -@@ -4146,6 +4149,12 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - - if (!arm64ec_map && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) return STATUS_INVALID_PARAMETER; - -+ if (type & MEM_RESERVE_PLACEHOLDER && (protect != PAGE_NOACCESS)) -+ { -+ WARN( "Wrong protect %#x for placeholder.\n", (unsigned int)protect ); -+ return STATUS_INVALID_PARAMETER; -+ } -+ - /* Reserve the memory */ - - server_enter_uninterrupted_section( &virtual_mutex, &sigset ); -@@ -4156,6 +4165,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - { - if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED; - if (type & MEM_WRITE_WATCH) vprot |= VPROT_WRITEWATCH; -+ if (type & MEM_RESERVE_PLACEHOLDER) vprot |= VPROT_PLACEHOLDER | VPROT_FREE_PLACEHOLDER; - if (protect & PAGE_NOCACHE) vprot |= SEC_NOCACHE; - - if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION; -@@ -4175,6 +4185,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - { - if (!(view = find_view( base, size ))) status = STATUS_NOT_MAPPED_VIEW; - else if (view->protect & SEC_FILE) status = STATUS_ALREADY_COMMITTED; -+ else if (view->protect & VPROT_FREE_PLACEHOLDER) status = STATUS_CONFLICTING_ADDRESSES; - else if (!(status = set_protection( view, base, size, protect )) && (view->protect & SEC_RESERVE)) - { - SERVER_START_REQ( add_mapping_committed_range ) -@@ -4210,6 +4221,7 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ - NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR zero_bits, - SIZE_T *size_ptr, ULONG type, ULONG protect ) - { -+ static const ULONG type_mask = MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET; - ULONG_PTR limit; - - TRACE("%p %p %08lx %x %08x\n", process, *ret, *size_ptr, (int)type, (int)protect ); -@@ -4221,6 +4233,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z - if (!is_old_wow64() && zero_bits >= 32) return STATUS_INVALID_PARAMETER_3; - #endif - -+ if (type & ~type_mask) -+ { -+ WARN("Called with wrong alloc type flags %08x.\n", (int)type); -+ return STATUS_INVALID_PARAMETER; -+ } -+ - if (process != NtCurrentProcess()) - { - apc_call_t call; -@@ -4331,6 +4349,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s - ULONG protect, MEM_EXTENDED_PARAMETER *parameters, - ULONG count ) - { -+ static const ULONG type_mask = MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH -+ | MEM_RESET | MEM_RESERVE_PLACEHOLDER; - ULONG_PTR limit = 0; - ULONG_PTR align = 0; - ULONG attributes = 0; -@@ -4343,6 +4363,12 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s - status = get_extended_params( parameters, count, &limit, &align, &attributes, &machine ); - if (status) return status; - -+ if (type & ~type_mask) -+ { -+ WARN( "Called with wrong alloc type flags %08x.\n", (unsigned int)type ); -+ return STATUS_INVALID_PARAMETER; -+ } -+ - if (*ret && (align || limit)) return STATUS_INVALID_PARAMETER; - if (!*size_ptr) return STATUS_INVALID_PARAMETER; - --- -2.40.1 - diff --git a/patches/ntdll-Placeholders/0004-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-map_view.patch b/patches/ntdll-Placeholders/0004-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-map_view.patch deleted file mode 100644 index 2e4e359f..00000000 --- a/patches/ntdll-Placeholders/0004-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-map_view.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0a88728d7d5f32e64537ae01aba70376dba736fc Mon Sep 17 00:00:00 2001 -From: Paul Gofman -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 - diff --git a/patches/ntdll-Placeholders/0005-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-NtAllocateV.patch b/patches/ntdll-Placeholders/0005-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-NtAllocateV.patch deleted file mode 100644 index ced4aa4d..00000000 --- a/patches/ntdll-Placeholders/0005-ntdll-Support-MEM_REPLACE_PLACEHOLDER-in-NtAllocateV.patch +++ /dev/null @@ -1,45 +0,0 @@ -From a72bcf44146603bcc500e1d3808c0a54f2d16da8 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -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 - diff --git a/patches/ntdll-Placeholders/0006-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtFreeVirt.patch b/patches/ntdll-Placeholders/0006-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtFreeVirt.patch deleted file mode 100644 index ad82abca..00000000 --- a/patches/ntdll-Placeholders/0006-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtFreeVirt.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 4779aa6e891f32ff0b9bd37e95ed20e4522662e7 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -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 - diff --git a/patches/ntdll-Placeholders/0007-ntdll-tests-Add-more-tests-for-placeholders.patch b/patches/ntdll-Placeholders/0007-ntdll-tests-Add-more-tests-for-placeholders.patch deleted file mode 100644 index 79e3ee62..00000000 --- a/patches/ntdll-Placeholders/0007-ntdll-tests-Add-more-tests-for-placeholders.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0f2112fa71afccdebea36bdf357fd66a303ce870 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Wed, 9 Nov 2022 21:23:19 -0600 -Subject: [PATCH] ntdll/tests: Add more tests for placeholders. - ---- - dlls/kernelbase/tests/process.c | 14 +++ - dlls/ntdll/tests/virtual.c | 150 +++++++++++++++++++++++++++++++- - 2 files changed, 160 insertions(+), 4 deletions(-) - -diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c -index b629b61ea5d..e5185a2587d 100644 ---- a/dlls/kernelbase/tests/process.c -+++ b/dlls/kernelbase/tests/process.c -@@ -204,6 +204,20 @@ static void test_VirtualAlloc2(void) - view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); - ok(!!view2, "Failed to map a section.\n"); - -+ memset(&info, 0, sizeof(info)); -+ VirtualQuery(placeholder1, &info, sizeof(info)); -+ ok(info.AllocationProtect == PAGE_READWRITE, "Unexpected protection %#lx.\n", info.AllocationProtect); -+ ok(info.State == MEM_COMMIT, "Unexpected state %#lx.\n", info.State); -+ ok(info.Type == MEM_MAPPED, "Unexpected type %#lx.\n", info.Type); -+ ok(info.RegionSize == size, "Unexpected size.\n"); -+ -+ memset(&info, 0, sizeof(info)); -+ VirtualQuery(placeholder2, &info, sizeof(info)); -+ ok(info.AllocationProtect == PAGE_READWRITE, "Unexpected protection %#lx.\n", info.AllocationProtect); -+ ok(info.State == MEM_COMMIT, "Unexpected state %#lx.\n", info.State); -+ ok(info.Type == MEM_MAPPED, "Unexpected type %#lx.\n", info.Type); -+ ok(info.RegionSize == size, "Unexpected size.\n"); -+ - CloseHandle(section); - UnmapViewOfFile(view1); - UnmapViewOfFile(view2); -diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c -index 1718aaf30f9..45ba58868df 100644 ---- a/dlls/ntdll/tests/virtual.c -+++ b/dlls/ntdll/tests/virtual.c -@@ -293,10 +293,14 @@ static void check_region_size_(void *p, SIZE_T s, unsigned int line) - - static void test_NtAllocateVirtualMemoryEx(void) - { -+ MEMORY_BASIC_INFORMATION mbi; - MEM_EXTENDED_PARAMETER ext[2]; -+ void *addresses[16]; - SIZE_T size, size2; - char *p, *p1, *p2; -+ ULONG granularity; - NTSTATUS status; -+ ULONG_PTR count; - void *addr1; - - if (!pNtAllocateVirtualMemoryEx) -@@ -332,15 +336,129 @@ static void test_NtAllocateVirtualMemoryEx(void) - status = NtAllocateVirtualMemory(NtCurrentProcess(), &addr1, 0, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS); - ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status); - -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, -+ PAGE_READWRITE, NULL, 0); -+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status); -+ - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -- size = 0; -- status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE); -- ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, -+ PAGE_READWRITE, NULL, 0); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ -+ memset(addr1, 0xcc, size); -+ -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, -+ PAGE_READONLY, NULL, 0); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ -+ ok(!*(unsigned int *)addr1, "Got %#x.\n", *(unsigned int *)addr1); -+ -+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size ); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ ok(mbi.AllocationProtect == PAGE_READONLY, "Unexpected protection %#lx.\n", mbi.AllocationProtect); -+ ok(mbi.State == MEM_COMMIT, "Unexpected state %#lx.\n", mbi.State); -+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type); -+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n"); -+ -+ size = 0x10000; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ -+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size ); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ ok(mbi.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", mbi.AllocationProtect); -+ ok(mbi.State == MEM_RESERVE, "Unexpected state %#lx.\n", mbi.State); -+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type); -+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n"); -+ -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, -+ PAGE_NOACCESS, NULL, 0); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE, -+ PAGE_NOACCESS, NULL, 0); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ -+ size = 0x1000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_REPLACE_PLACEHOLDER, -+ PAGE_NOACCESS, NULL, 0); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT, PAGE_READWRITE, NULL, 0); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); -+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status); -+ -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, -+ PAGE_READWRITE, NULL, 0); -+ ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status); -+ -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, -+ MEM_WRITE_WATCH | MEM_RESERVE | MEM_REPLACE_PLACEHOLDER, -+ PAGE_READONLY, NULL, 0); -+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Win10 1809, the version where -+ NtAllocateVirtualMemoryEx is introduced */, "Unexpected status %08lx.\n", status); -+ -+ if (!status) -+ { -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_COMMIT, PAGE_READWRITE, NULL, 0); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ -+ status = NtQueryVirtualMemory( NtCurrentProcess(), addr1, MemoryBasicInformation, &mbi, sizeof(mbi), &size ); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ ok(mbi.AllocationProtect == PAGE_READONLY, "Unexpected protection %#lx.\n", mbi.AllocationProtect); -+ ok(mbi.State == MEM_COMMIT, "Unexpected state %#lx.\n", mbi.State); -+ ok(mbi.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", mbi.Type); -+ ok(mbi.RegionSize == 0x10000, "Unexpected size.\n"); -+ -+ size = 0x10000; -+ count = ARRAY_SIZE(addresses); -+ status = NtGetWriteWatch( NtCurrentProcess(), WRITE_WATCH_FLAG_RESET, addr1, size, -+ addresses, &count, &granularity ); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ ok(!count, "Unexpected count %u.\n", (unsigned int)count); -+ *((char *)addr1 + 0x1000) = 1; -+ count = ARRAY_SIZE(addresses); -+ status = NtGetWriteWatch( NtCurrentProcess(), WRITE_WATCH_FLAG_RESET, addr1, size, -+ addresses, &count, &granularity ); -+ ok(!status, "Unexpected status %08lx.\n", status); -+ ok(count == 1, "Unexpected count %u.\n", (unsigned int)count); -+ ok(addresses[0] == (char *)addr1 + 0x1000, "Unexpected address %p.\n", addresses[0]); -+ -+ size = 0; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ } - - /* Placeholder region splitting. */ -+ addr1 = NULL; -+ size = 0x10000; -+ status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE, -+ PAGE_NOACCESS, NULL, 0); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ p = addr1; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size); -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size, MEM_RELEASE); -+ ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size); -+ ok(p == addr1, "Unexpected addr %p, expected %p.\n", p, addr1); -+ - - /* Split in three regions. */ - addr1 = NULL; -@@ -349,12 +467,17 @@ static void test_NtAllocateVirtualMemoryEx(void) - PAGE_NOACCESS, NULL, 0); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx.\n", status); -+ - p = addr1; - p1 = p + size / 2; - p2 = p1 + size / 4; - size2 = size / 4; - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2); -+ ok(p1 == p + size / 2, "Unexpected addr %p, expected %p.\n", p, p + size / 2); - - check_region_size(p, size / 2); - check_region_size(p1, size / 4); -@@ -362,10 +485,16 @@ static void test_NtAllocateVirtualMemoryEx(void) - - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p, &size2, MEM_RELEASE); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2); -+ ok(p == addr1, "Unexpected addr %p, expected %p.\n", p, addr1); - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2); -+ ok(p1 == p + size / 2, "Unexpected addr %p, expected %p.\n", p1, p + size / 2); - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2); -+ ok(p2 == p1 + size / 4, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 4); - - /* Split in two regions, specifying lower part. */ - addr1 = NULL; -@@ -374,12 +503,19 @@ static void test_NtAllocateVirtualMemoryEx(void) - PAGE_NOACCESS, NULL, 0); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - -+ size2 = 0; -+ status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&addr1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); -+ ok(status == STATUS_INVALID_PARAMETER_3, "Unexpected status %08lx.\n", status); -+ ok(!size2, "Unexpected size %#Ix.\n", size2); -+ - p1 = addr1; - p2 = p1 + size / 4; - size2 = size / 4; - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); - ok(p1 == addr1, "Unexpected address.\n"); -+ ok(size2 == 0x4000, "Unexpected size %#Ix.\n", size2); -+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1); - - check_region_size(p1, size / 4); - check_region_size(p2, size - size / 4); -@@ -394,6 +530,7 @@ static void test_NtAllocateVirtualMemoryEx(void) - status = pNtAllocateVirtualMemoryEx(NtCurrentProcess(), &addr1, &size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, - PAGE_NOACCESS, NULL, 0); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size == 0x10000, "Unexpected size %#Ix.\n", size); - - p1 = addr1; - p2 = p1 + size / 2; -@@ -401,13 +538,18 @@ static void test_NtAllocateVirtualMemoryEx(void) - size2 = size / 2; - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -- ok(p2 == p1 + size / 2, "Unexpected address.\n"); -+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2); -+ ok(p2 == p1 + size / 2, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 2); - check_region_size(p1, size / 2); - check_region_size(p2, size / 2); - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p1, &size2, MEM_RELEASE); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2); -+ ok(p1 == addr1, "Unexpected addr %p, expected %p.\n", p1, addr1); - status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); - ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); -+ ok(size2 == 0x8000, "Unexpected size %#Ix.\n", size2); -+ ok(p2 == p1 + size / 2, "Unexpected addr %p, expected %p.\n", p2, p1 + size / 2); - - memset( ext, 0, sizeof(ext) ); - ext[0].Type = MemExtendedParameterAttributeFlags; --- -2.40.1 - diff --git a/patches/ntdll-Placeholders/0008-ntdll-Support-MEM_COALESCE_PLACEHOLDERS-in-NtFreeVir.patch b/patches/ntdll-Placeholders/0008-ntdll-Support-MEM_COALESCE_PLACEHOLDERS-in-NtFreeVir.patch index 6df600f3..8ff2b183 100644 --- a/patches/ntdll-Placeholders/0008-ntdll-Support-MEM_COALESCE_PLACEHOLDERS-in-NtFreeVir.patch +++ b/patches/ntdll-Placeholders/0008-ntdll-Support-MEM_COALESCE_PLACEHOLDERS-in-NtFreeVir.patch @@ -1,4 +1,4 @@ -From c1a82d397f9bf6ba20fe6966a5b1d2209c49d44b Mon Sep 17 00:00:00 2001 +From 03f652283badc478f715d50d63de4cb9064ef7f1 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 10 Nov 2022 19:02:50 -0600 Subject: [PATCH] ntdll: Support MEM_COALESCE_PLACEHOLDERS in @@ -6,8 +6,8 @@ Subject: [PATCH] ntdll: Support MEM_COALESCE_PLACEHOLDERS in --- dlls/ntdll/tests/virtual.c | 72 ++++++++++++++++++++++++++++++++++++-- - dlls/ntdll/unix/virtual.c | 53 +++++++++++++++++++++++++++- - 2 files changed, 122 insertions(+), 3 deletions(-) + dlls/ntdll/unix/virtual.c | 55 ++++++++++++++++++++++++++++- + 2 files changed, 124 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index 45ba58868df..f5f1964e516 100644 @@ -114,7 +114,7 @@ index 45ba58868df..f5f1964e516 100644 /* Split in two regions, specifying second half. */ addr1 = NULL; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index bdb213d968e..f5634e64021 100644 +index f68c5ec84d6..26d4edb019a 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -114,6 +114,9 @@ struct file_view @@ -127,7 +127,7 @@ index bdb213d968e..f5634e64021 100644 /* per-page protection flags */ #define VPROT_READ 0x01 #define VPROT_WRITE 0x02 -@@ -2337,6 +2340,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size, BOO +@@ -2335,6 +2338,52 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size ) } @@ -180,23 +180,26 @@ index bdb213d968e..f5634e64021 100644 /*********************************************************************** * allocate_dos_memory * -@@ -4526,13 +4575,15 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si +@@ -4509,7 +4558,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si else if (!(view = find_view( base, 0 ))) status = STATUS_MEMORY_NOT_ALLOCATED; else if (!is_view_valloc( view )) status = STATUS_INVALID_PARAMETER; else if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE; - else if ((char *)view->base + view->size - base < size) status = STATUS_UNABLE_TO_FREE_VM; + else if ((char *)view->base + view->size - base < size && !(type & MEM_COALESCE_PLACEHOLDERS)) + status = STATUS_UNABLE_TO_FREE_VM; - else if (type == MEM_DECOMMIT) status = decommit_pages( view, base - (char *)view->base, size ); - else if (type == MEM_RELEASE || (type == (MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER))) + else switch (type) { - status = free_pages( view, base, size, type & MEM_PRESERVE_PLACEHOLDER ); - if (!size) size = view->size; - } -+ else if (type & MEM_COALESCE_PLACEHOLDERS) status = coalesce_placeholders( view, base, size, type ); - else status = STATUS_INVALID_PARAMETER; - - if (status == STATUS_SUCCESS) + case MEM_DECOMMIT: +@@ -4522,6 +4572,9 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si + case MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER: + status = free_pages_preserve_placeholder( view, base, size ); + break; ++ case MEM_COALESCE_PLACEHOLDERS: ++ status = coalesce_placeholders( view, base, size, type ); ++ break; + default: + status = STATUS_INVALID_PARAMETER; + break; -- 2.40.1 diff --git a/patches/ntdll-Placeholders/0010-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtUnmapVie.patch b/patches/ntdll-Placeholders/0010-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtUnmapVie.patch index e1056621..7844e8ed 100644 --- a/patches/ntdll-Placeholders/0010-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtUnmapVie.patch +++ b/patches/ntdll-Placeholders/0010-ntdll-Support-MEM_PRESERVE_PLACEHOLDER-in-NtUnmapVie.patch @@ -165,7 +165,7 @@ index fe2e81fbe95..fc120eaafc0 100644 if (view->protect & SEC_IMAGE) release_builtin_module( view->base ); - delete_view( view ); + if (flags & MEM_PRESERVE_PLACEHOLDER) -+ view_make_placeholder( view ); ++ remove_pages_from_view( view, view->base, view->size ); + else + delete_view( view ); } diff --git a/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch b/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch index 573ee0f6..45db327a 100644 --- a/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch +++ b/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch @@ -1,4 +1,4 @@ -From b6a6f7448cb4f202edec1a2644315e745b709afe Mon Sep 17 00:00:00 2001 +From 045f711cb526f02ce6a163bf8ab973b5d06a1c86 Mon Sep 17 00:00:00 2001 From: Andrew Wesie Date: Fri, 24 Apr 2020 14:55:14 -0500 Subject: [PATCH] ntdll: Track if a WRITECOPY page has been modified. @@ -12,18 +12,18 @@ Signed-off-by: Andrew Wesie 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 578ef4139b8..ff15840adb6 100644 +index 2688383cc9f..b0c888d13a0 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -119,6 +119,7 @@ struct file_view +@@ -122,6 +122,7 @@ struct file_view #define VPROT_GUARD 0x10 #define VPROT_COMMITTED 0x20 #define VPROT_WRITEWATCH 0x40 +#define VPROT_WRITTEN 0x80 /* per-mapping protection flags */ #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ - -@@ -1072,7 +1073,7 @@ static int get_unix_prot( BYTE vprot ) + #define VPROT_PLACEHOLDER 0x0400 +@@ -1130,7 +1131,7 @@ static int get_unix_prot( BYTE vprot ) #if defined(__i386__) if (vprot & VPROT_WRITECOPY) { @@ -32,7 +32,7 @@ index 578ef4139b8..ff15840adb6 100644 prot = (prot & ~PROT_WRITE) | PROT_READ; else prot |= PROT_WRITE | PROT_READ; -@@ -1635,7 +1636,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz +@@ -1702,7 +1703,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz */ static DWORD get_win32_prot( BYTE vprot, unsigned int map_prot ) { @@ -45,7 +45,7 @@ index 578ef4139b8..ff15840adb6 100644 if (vprot & VPROT_GUARD) ret |= PAGE_GUARD; if (map_prot & SEC_NOCACHE) ret |= PAGE_NOCACHE; return ret; -@@ -1746,12 +1751,21 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr +@@ -1813,12 +1818,21 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr if (view->protect & VPROT_WRITEWATCH) { /* each page may need different protections depending on write watch flag */ @@ -69,7 +69,7 @@ index 578ef4139b8..ff15840adb6 100644 return TRUE; } -@@ -3325,7 +3339,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) +@@ -3691,7 +3705,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) } if (vprot & VPROT_WRITECOPY) { @@ -79,5 +79,5 @@ index 578ef4139b8..ff15840adb6 100644 } /* ignore fault if page is writable now */ -- -2.38.1 +2.40.1 diff --git a/patches/setupapi-DiskSpaceList/0001-setupapi-Rewrite-DiskSpaceList-logic-using-lists.patch b/patches/setupapi-DiskSpaceList/0001-setupapi-Rewrite-DiskSpaceList-logic-using-lists.patch index ab3abac1..af0c9494 100644 --- a/patches/setupapi-DiskSpaceList/0001-setupapi-Rewrite-DiskSpaceList-logic-using-lists.patch +++ b/patches/setupapi-DiskSpaceList/0001-setupapi-Rewrite-DiskSpaceList-logic-using-lists.patch @@ -1,14 +1,14 @@ -From cf705ac3f0c220d39767670ea5cbc3cf7b35b019 Mon Sep 17 00:00:00 2001 +From 41373705396aeb4703a6267148ccf663bf9a42bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 3 Mar 2016 04:52:35 +0100 Subject: [PATCH] setupapi: Rewrite DiskSpaceList logic using lists. --- - dlls/setupapi/diskspace.c | 183 +++++++++++++++++++++----------------- - 1 file changed, 101 insertions(+), 82 deletions(-) + dlls/setupapi/diskspace.c | 181 +++++++++++++++++++++----------------- + 1 file changed, 100 insertions(+), 81 deletions(-) diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c -index f7f6a22ce2d..b3cc36051cd 100644 +index 5b89fd5ca99..04bc2696236 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -1,6 +1,7 @@ @@ -81,14 +81,14 @@ index f7f6a22ce2d..b3cc36051cd 100644 - if (rc == 0) - return NULL; - -- list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST)); +- list = malloc(sizeof(DISKSPACELIST)); - - list->dwDriveCount = 0; - - ptr = drives; - - while (*ptr) -+ list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list)); ++ list = malloc(sizeof(*list)); + if (list) { - DWORD type = GetDriveTypeW(ptr); @@ -140,8 +140,8 @@ index f7f6a22ce2d..b3cc36051cd 100644 return NULL; } -- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST)); -+ list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy)); +- list_copy = malloc(sizeof(DISKSPACELIST)); ++ list_copy = malloc(sizeof(*list_copy)); if (!list_copy) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -154,13 +154,13 @@ index f7f6a22ce2d..b3cc36051cd 100644 + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { -+ file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy)); ++ file_copy = malloc(sizeof(*file_copy)); + if (!file_copy) goto error; + -+ file_copy->path = strdupW(file->path); ++ file_copy->path = wcsdup(file->path); + if (!file_copy->path) + { -+ HeapFree(GetProcessHeap(), 0, file_copy); ++ free(file_copy); + goto error; + } + @@ -215,7 +215,7 @@ index f7f6a22ce2d..b3cc36051cd 100644 return FALSE; } -- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR)); +- driveW = malloc((wcslen(DriveSpec) + 2) * sizeof(WCHAR)); - if (!driveW) + if (!required) { @@ -245,7 +245,7 @@ index f7f6a22ce2d..b3cc36051cd 100644 + return FALSE; } -- HeapFree(GetProcessHeap(), 0, driveW); +- free(driveW); + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (towlower(file->path[0]) == towlower(drivespec[0]) && @@ -260,7 +260,7 @@ index f7f6a22ce2d..b3cc36051cd 100644 } /*********************************************************************** -@@ -253,10 +257,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, +@@ -253,9 +257,24 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, /*********************************************************************** * SetupDestroyDiskSpaceList (SETUPAPI.@) */ @@ -268,7 +268,6 @@ index f7f6a22ce2d..b3cc36051cd 100644 +BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) { - LPDISKSPACELIST list = DiskSpace; -- HeapFree(GetProcessHeap(),0,list); + struct space_list *list = diskspace; + struct file_entry *file, *file2; + @@ -280,15 +279,14 @@ index f7f6a22ce2d..b3cc36051cd 100644 + + LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry) + { -+ HeapFree(GetProcessHeap(), 0, file->path); ++ free(file->path); + list_remove(&file->entry); -+ HeapFree(GetProcessHeap(), 0, file); ++ free(file); + } + -+ HeapFree(GetProcessHeap(), 0, list); - return TRUE; + free(list); + return TRUE; } - -- -2.34.1 +2.40.1 diff --git a/patches/setupapi-DiskSpaceList/0002-setupapi-Implement-SetupAddToDiskSpaceList.patch b/patches/setupapi-DiskSpaceList/0002-setupapi-Implement-SetupAddToDiskSpaceList.patch index 1526f11c..9abea3a3 100644 --- a/patches/setupapi-DiskSpaceList/0002-setupapi-Implement-SetupAddToDiskSpaceList.patch +++ b/patches/setupapi-DiskSpaceList/0002-setupapi-Implement-SetupAddToDiskSpaceList.patch @@ -111,7 +111,7 @@ index dcfa39b5a92..cc309f9393c 100644 + goto done; + } + -+ file->path = strdupW(fullpathW); ++ file->path = wcsdup(fullpathW); + if (!file->path) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); diff --git a/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch b/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch index ce90f91c..7b8571fd 100644 --- a/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch +++ b/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch @@ -1,18 +1,18 @@ -From bfc1aa75005a50ac1910e727efd7ba385b653c07 Mon Sep 17 00:00:00 2001 +From 3b6ade8a6088fe6030a95b8062d823eafb2bfbfd Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 24 Jan 2017 12:37:46 +0100 Subject: [PATCH] winex11: Fix alpha blending in X11DRV_UpdateLayeredWindow. Based on a patch by Dmitry Timoshkov. --- - dlls/winex11.drv/window.c | 27 +++++++++++++-------------- - 1 file changed, 13 insertions(+), 14 deletions(-) + dlls/winex11.drv/window.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c -index 3b0ccd8d22a..2ae27dacd2a 100644 +index 8399a816fa7..110865d2388 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c -@@ -415,14 +415,11 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) +@@ -424,14 +424,11 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) /*********************************************************************** @@ -30,7 +30,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (opacity == 0xffffffff) XDeleteProperty( display, win, x11drv_atom(_NET_WM_WINDOW_OPACITY) ); -@@ -1603,7 +1600,7 @@ static void create_whole_window( struct x11drv_win_data *data ) +@@ -1662,7 +1659,7 @@ static void create_whole_window( struct x11drv_win_data *data ) /* set the window opacity */ if (!NtUserGetLayeredWindowAttributes( data->hwnd, &key, &alpha, &layered_flags )) layered_flags = 0; @@ -39,7 +39,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 XFlush( data->display ); /* make sure the window exists before we start painting to it */ -@@ -1735,7 +1732,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) +@@ -1794,7 +1791,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) { data->layered = FALSE; set_window_visual( data, &default_visual, FALSE ); @@ -48,7 +48,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (data->surface) set_surface_color_key( data->surface, CLR_INVALID ); } done: -@@ -2662,7 +2659,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO +@@ -2840,7 +2837,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO set_window_visual( data, &default_visual, FALSE ); if (data->whole_window) @@ -57,7 +57,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (data->surface) set_surface_color_key( data->surface, (flags & LWA_COLORKEY) ? key : CLR_INVALID ); -@@ -2686,7 +2683,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO +@@ -2864,7 +2861,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO Window win = X11DRV_get_whole_window( hwnd ); if (win) { @@ -66,7 +66,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (flags & LWA_COLORKEY) FIXME( "LWA_COLORKEY not supported on foreign process window %p\n", hwnd ); } -@@ -2702,7 +2699,6 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, +@@ -2880,7 +2877,6 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, { struct window_surface *surface; struct x11drv_win_data *data; @@ -74,7 +74,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *bmi = (BITMAPINFO *)buffer; -@@ -2730,6 +2726,10 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, +@@ -2908,6 +2904,10 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, } else set_surface_color_key( surface, color_key ); @@ -85,7 +85,7 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (surface) window_surface_add_ref( surface ); mapped = data->mapped; release_win_data( data ); -@@ -2764,16 +2764,15 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, +@@ -2942,17 +2942,15 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, { intersect_rect( &rect, &rect, info->prcDirty ); memcpy( src_bits, dst_bits, bmi->bmiHeader.biSizeImage ); @@ -95,15 +95,16 @@ index 3b0ccd8d22a..2ae27dacd2a 100644 if (info->pptSrc) OffsetRect( &src_rect, info->pptSrc->x, info->pptSrc->y ); NtGdiTransformPoints( info->hdcSrc, (POINT *)&src_rect, (POINT *)&src_rect, 2, NtGdiDPtoLP ); +- if (info->dwFlags & ULW_ALPHA) blend = *info->pblend; - ret = NtGdiAlphaBlend( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + ret = NtGdiStretchBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, info->hdcSrc, src_rect.left, src_rect.top, src_rect.right - src_rect.left, src_rect.bottom - src_rect.top, -- (info->dwFlags & ULW_ALPHA) ? *info->pblend : blend, 0 ); +- *(DWORD *)&blend, 0 ); + SRCCOPY, 0 ); if (ret) { memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage ); -- -2.34.1 +2.40.1 diff --git a/staging/upstream-commit b/staging/upstream-commit index 515bca9d..99be8342 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -e10da7ab2e3d151c8347802600862aa608672f6f +c293cd781fb4b330b7d93171501134f86a5138b8