[PATCH 2/4] kernelbase: Implement VirtualAlloc2FromApp().
Nikolay Sivov
wine at gitlab.winehq.org
Fri Jun 3 09:09:01 CDT 2022
From: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at 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);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/183
More information about the wine-devel
mailing list