Signed-off-by: Paul Gofman pgofman@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);