[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