[PATCH] kernel32: Implement VirtualAllocFromApp().

Paul Gofman pgofman at codeweavers.com
Wed Apr 14 11:26:52 CDT 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
    Used by Forza Horizon 4.

 .../api-ms-win-core-memory-l1-1-3.spec        |  2 +-
 dlls/kernel32/tests/virtual.c                 | 39 ++++++++++++++++++-
 dlls/kernelbase/kernelbase.spec               |  2 +-
 dlls/kernelbase/memory.c                      | 22 +++++++++++
 include/winbase.h                             |  1 +
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/dlls/api-ms-win-core-memory-l1-1-3/api-ms-win-core-memory-l1-1-3.spec b/dlls/api-ms-win-core-memory-l1-1-3/api-ms-win-core-memory-l1-1-3.spec
index b0d402b24c7..5b143ec1af3 100644
--- a/dlls/api-ms-win-core-memory-l1-1-3/api-ms-win-core-memory-l1-1-3.spec
+++ b/dlls/api-ms-win-core-memory-l1-1-3/api-ms-win-core-memory-l1-1-3.spec
@@ -19,7 +19,7 @@
 @ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile
 @ stub UnmapViewOfFileEx
 @ stdcall VirtualAlloc(ptr long long long) kernel32.VirtualAlloc
-@ stub VirtualAllocFromApp
+@ stdcall VirtualAllocFromApp(ptr long long long) kernelbase.VirtualAllocFromApp
 @ stdcall VirtualFree(ptr long long) kernel32.VirtualFree
 @ stdcall VirtualFreeEx(long ptr long long) kernel32.VirtualFreeEx
 @ stdcall VirtualLock(ptr long) kernel32.VirtualLock
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index e6d9e8621a9..4abaa5befd1 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -35,7 +35,7 @@
 #define NUM_THREADS 4
 #define MAPPING_SIZE 0x100000
 
-static HINSTANCE hkernel32, hntdll;
+static HINSTANCE hkernel32, hkernelbase, hntdll;
 static SYSTEM_INFO si;
 static UINT   (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
 static UINT   (WINAPI *pResetWriteWatch)(LPVOID,SIZE_T);
@@ -50,6 +50,7 @@ static ULONG  (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
 static BOOL   (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL);
 static BOOL   (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
 static NTSTATUS (WINAPI *pNtProtectVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG *);
+static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD);
 
 /* ############################### */
 
@@ -443,6 +444,39 @@ static void test_VirtualAlloc(void)
     ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
 }
 
+static void test_VirtualAllocFromApp(void)
+{
+    void *p;
+    BOOL ret;
+    if (!pVirtualAllocFromApp)
+    {
+        win_skip("VirtualAllocFromApp is not available.\n");
+        return;
+    }
+
+    p = GetProcAddress(hkernel32, "VirtualAllocFromApp");
+    ok(!p, "Found VirtualAllocFromApp in kernel32.dll.\n");
+
+    SetLastError(0xdeadbeef);
+    p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_READWRITE);
+    ok(p && GetLastError() == 0xdeadbeef, "Got unexpected mem %p, GetLastError() %u.\n", p, GetLastError());
+    ret = VirtualFree(p, 0, MEM_RELEASE);
+    ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+    SetLastError(0xdeadbeef);
+    p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE);
+    ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %u.\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() %u.\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() %u.\n",
+            p, GetLastError());
+}
+
 static void test_MapViewOfFile(void)
 {
     static const char testfile[] = "testfile.xxx";
@@ -4238,6 +4272,7 @@ START_TEST(virtual)
     }
 
     hkernel32 = GetModuleHandleA("kernel32.dll");
+    hkernelbase = GetModuleHandleA("kernelbase.dll");
     hntdll    = GetModuleHandleA("ntdll.dll");
 
     pGetWriteWatch = (void *) GetProcAddress(hkernel32, "GetWriteWatch");
@@ -4252,6 +4287,7 @@ START_TEST(virtual)
     pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" );
     pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" );
     pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" );
+    pVirtualAllocFromApp = (void *)GetProcAddress( hkernelbase, "VirtualAllocFromApp" );
 
     GetSystemInfo(&si);
     trace("system page size %#x\n", si.dwPageSize);
@@ -4266,6 +4302,7 @@ START_TEST(virtual)
     test_VirtualProtect();
     test_VirtualAllocEx();
     test_VirtualAlloc();
+    test_VirtualAllocFromApp();
     test_MapViewOfFile();
     test_NtAreMappedFilesTheSame();
     test_CreateFileMapping();
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 615b928bd22..28cfd842223 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -1678,7 +1678,7 @@
 @ stdcall VirtualAlloc(ptr long long long)
 @ stdcall VirtualAllocEx(long ptr long long long)
 @ stdcall VirtualAllocExNuma(long ptr long long long long)
-# @ stub VirtualAllocFromApp
+@ stdcall VirtualAllocFromApp(ptr long long long)
 @ stdcall VirtualFree(ptr long long)
 @ stdcall VirtualFreeEx(long ptr long long)
 @ stdcall VirtualLock(ptr long)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 60333db242f..4b71c0cc6ec 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -314,6 +314,28 @@ LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAlloc2( HANDLE process, void *addr, SIZE_
 }
 
 
+/***********************************************************************
+ *             VirtualAllocFromApp   (kernelbase.@)
+ */
+LPVOID WINAPI DECLSPEC_HOTPATCH VirtualAllocFromApp( void *addr, SIZE_T size,
+                                                DWORD type, DWORD protect )
+{
+    LPVOID ret = addr;
+
+    TRACE_(virtual)( "addr %p, size %p, type %#x, protect %#x.\n", addr, (void *)size, type, protect );
+
+    if (protect == PAGE_EXECUTE || protect == PAGE_EXECUTE_READ || protect == PAGE_EXECUTE_READWRITE
+            || protect == PAGE_EXECUTE_WRITECOPY)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+
+    if (!set_ntstatus( NtAllocateVirtualMemory( GetCurrentProcess(), &ret, 0, &size, type, protect ))) return NULL;
+    return ret;
+}
+
+
 /***********************************************************************
  *             VirtualFree   (kernelbase.@)
  */
diff --git a/include/winbase.h b/include/winbase.h
index beb91371bb6..11a92fa84d9 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2748,6 +2748,7 @@ 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 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);
 WINBASEAPI BOOL        WINAPI VirtualFree(LPVOID,SIZE_T,DWORD);
 WINBASEAPI BOOL        WINAPI VirtualFreeEx(HANDLE,LPVOID,SIZE_T,DWORD);
 WINBASEAPI BOOL        WINAPI VirtualLock(LPVOID,SIZE_T);
-- 
2.30.2




More information about the wine-devel mailing list