Module: wine Branch: master Commit: 03fde5c002c7cb4a7a8aa26a5d64bf8516352542 URL: https://source.winehq.org/git/wine.git/?a=commit;h=03fde5c002c7cb4a7a8aa26a5...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Jun 3 13:36:37 2022 +0300
kernelbase: Implement VirtualAlloc2FromApp().
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
---
dlls/kernelbase/kernelbase.spec | 1 + dlls/kernelbase/memory.c | 32 +++++++++++++++++++-- dlls/kernelbase/tests/process.c | 63 +++++++++++++++++++++++++++++++++-------- include/winbase.h | 1 + 4 files changed, 83 insertions(+), 14 deletions(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 7109628a678..d4b5b5d3eb8 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1707,6 +1707,7 @@ # @ stub VerifyPackageRelativeApplicationId # @ stub VerifyScripts @ stdcall VirtualAlloc2(long ptr long long long ptr long) +@ stdcall VirtualAlloc2FromApp(long ptr long long long ptr long) @ stdcall VirtualAlloc(ptr long long long) @ stdcall VirtualAllocEx(long ptr long long long) @ stdcall VirtualAllocExNuma(long ptr long long long long) diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c index cac456d01be..736d3642995 100644 --- a/dlls/kernelbase/memory.c +++ b/dlls/kernelbase/memory.c @@ -358,6 +358,35 @@ LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAlloc2( HANDLE process, void *addr, SIZE_ return ret; }
+static BOOL is_exec_prot( DWORD protect ) +{ + return protect == PAGE_EXECUTE || protect == PAGE_EXECUTE_READ || protect == PAGE_EXECUTE_READWRITE + || protect == PAGE_EXECUTE_WRITECOPY; +} + +/*********************************************************************** + * VirtualAlloc2FromApp (kernelbase.@) + */ +LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAlloc2FromApp( HANDLE process, void *addr, SIZE_T size, + DWORD type, DWORD protect, MEM_EXTENDED_PARAMETER *parameters, ULONG count ) +{ + LPVOID ret = addr; + + TRACE_(virtual)( "addr %p, size %p, type %#lx, protect %#lx, params %p, count %lu.\n", addr, (void *)size, type, protect, + parameters, count ); + + if (is_exec_prot( protect )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + + if (!process) process = GetCurrentProcess(); + if (!set_ntstatus( NtAllocateVirtualMemoryEx( process, &ret, &size, type, protect, parameters, count ))) + return NULL; + return ret; +} +
/*********************************************************************** * VirtualAllocFromApp (kernelbase.@) @@ -369,8 +398,7 @@ LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAllocFromApp( void *addr, SIZE_T size,
TRACE_(virtual)( "addr %p, size %p, type %#lx, protect %#lx.\n", addr, (void *)size, type, protect );
- if (protect == PAGE_EXECUTE || protect == PAGE_EXECUTE_READ || protect == PAGE_EXECUTE_READWRITE - || protect == PAGE_EXECUTE_WRITECOPY) + if (is_exec_prot( protect )) { SetLastError( ERROR_INVALID_PARAMETER ); return NULL; diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c index 90c4c4c26e1..bb1de49049d 100644 --- a/dlls/kernelbase/tests/process.c +++ b/dlls/kernelbase/tests/process.c @@ -34,6 +34,7 @@ static BOOL (WINAPI *pCompareObjectHandles)(HANDLE, HANDLE); static LPVOID (WINAPI *pMapViewOfFile3)(HANDLE, HANDLE, PVOID, ULONG64 offset, SIZE_T size, ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG); static LPVOID (WINAPI *pVirtualAlloc2)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); +static LPVOID (WINAPI *pVirtualAlloc2FromApp)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD);
static void test_CompareObjectHandles(void) @@ -197,6 +198,14 @@ static void test_VirtualAlloc2(void)
static void test_VirtualAllocFromApp(void) { + static const DWORD prot[] = + { + PAGE_EXECUTE, + PAGE_EXECUTE_READ, + PAGE_EXECUTE_READWRITE, + PAGE_EXECUTE_WRITECOPY, + }; + unsigned int i; BOOL ret; void *p;
@@ -212,18 +221,46 @@ static void test_VirtualAllocFromApp(void) ret = VirtualFree(p, 0, MEM_RELEASE); ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
- SetLastError(0xdeadbeef); - p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE); - ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", - p, GetLastError()); - SetLastError(0xdeadbeef); - p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READ); - ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", - p, GetLastError()); - SetLastError(0xdeadbeef); - p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READWRITE); - ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", - p, GetLastError()); + for (i = 0; i < ARRAY_SIZE(prot); ++i) + { + SetLastError(0xdeadbeef); + p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, prot[i]); + ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", + p, GetLastError()); + } +} + +static void test_VirtualAlloc2FromApp(void) +{ + static const DWORD prot[] = + { + PAGE_EXECUTE, + PAGE_EXECUTE_READ, + PAGE_EXECUTE_READWRITE, + PAGE_EXECUTE_WRITECOPY, + }; + unsigned int i; + void *addr; + BOOL ret; + + if (!pVirtualAlloc2FromApp) + { + win_skip("VirtualAlloc2FromApp is not available.\n"); + return; + } + + addr = pVirtualAlloc2FromApp(NULL, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE, NULL, 0); + ok(!!addr, "Failed to allocate, error %lu.\n", GetLastError()); + ret = VirtualFree(addr, 0, MEM_RELEASE); + ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError()); + + for (i = 0; i < ARRAY_SIZE(prot); ++i) + { + SetLastError(0xdeadbeef); + addr = pVirtualAlloc2FromApp(NULL, NULL, 0x1000, MEM_COMMIT, prot[i], NULL, 0); + ok(!addr && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", + addr, GetLastError()); + } }
static void init_funcs(void) @@ -234,6 +271,7 @@ static void init_funcs(void) X(CompareObjectHandles); X(MapViewOfFile3); X(VirtualAlloc2); + X(VirtualAlloc2FromApp); X(VirtualAllocFromApp); #undef X } @@ -246,4 +284,5 @@ START_TEST(process) test_MapViewOfFile3(); test_VirtualAlloc2(); test_VirtualAllocFromApp(); + test_VirtualAlloc2FromApp(); } diff --git a/include/winbase.h b/include/winbase.h index a400816c4d3..bf191153ddc 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2756,6 +2756,7 @@ WINBASEAPI BOOL WINAPI VerifyVersionInfoW(LPOSVERSIONINFOEXW,DWORD,DWORDL #define VerifyVersionInfo WINELIB_NAME_AW(VerifyVersionInfo) WINBASEAPI LPVOID WINAPI VirtualAlloc(LPVOID,SIZE_T,DWORD,DWORD); WINBASEAPI LPVOID WINAPI VirtualAlloc2(HANDLE,LPVOID,SIZE_T,DWORD,DWORD,MEM_EXTENDED_PARAMETER*,ULONG); +WINBASEAPI LPVOID WINAPI VirtualAlloc2FromApp(HANDLE,LPVOID,SIZE_T,DWORD,DWORD,MEM_EXTENDED_PARAMETER*,ULONG); WINBASEAPI LPVOID WINAPI VirtualAllocEx(HANDLE,LPVOID,SIZE_T,DWORD,DWORD); WINBASEAPI LPVOID WINAPI VirtualAllocExNuma(HANDLE,void*,SIZE_T,DWORD,DWORD,DWORD); WINBASEAPI LPVOID WINAPI VirtualAllocFromApp(LPVOID,SIZE_T,DWORD,DWORD);