https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7f208124c9f83084a992e…
commit 7f208124c9f83084a992ee09cd38a524ebaebdf6
Author: Serge Gautherie <32623169+SergeGautherie(a)users.noreply.github.com>
AuthorDate: Sat Mar 17 17:30:01 2018 +0100
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sat Mar 17 17:30:01 2018 +0100
[NTDLL_APITEST] Fix/Extend ApiTest NtAllocateVirtualMemory (#207)
* Fix 1 failure on both WS03 and ReactOS.
* Create CheckSomeDefaultAddresses(), with additional checks.
* Update license header.
* ROSTESTS-297
---
.../apitests/ntdll/NtAllocateVirtualMemory.c | 204 ++++++++++++++++++---
1 file changed, 181 insertions(+), 23 deletions(-)
diff --git a/modules/rostests/apitests/ntdll/NtAllocateVirtualMemory.c
b/modules/rostests/apitests/ntdll/NtAllocateVirtualMemory.c
index d1a73cc9a5..aae94052e6 100644
--- a/modules/rostests/apitests/ntdll/NtAllocateVirtualMemory.c
+++ b/modules/rostests/apitests/ntdll/NtAllocateVirtualMemory.c
@@ -1,8 +1,11 @@
/*
- * PROJECT: ReactOS API Tests
- * LICENSE: GPLv2+ - See COPYING in the top level directory
- * PURPOSE: Stress Test for virtual memory allocation
- * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org>
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Test for NtAllocateVirtualMemory
+ * COPYRIGHT: Copyright 2011 Thomas Faber <thomas.faber(a)reactos.org>
+ * Copyright 2013 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ * Copyright 2015 J�r�me Gardou <jerome.gardou(a)reactos.org>
+ * Copyright 2018 Serge Gautherie
<reactos-git_serge_171003(a)gautherie.fr>
*/
#include "precomp.h"
@@ -562,39 +565,194 @@ CheckAdjacentVADs()
}
-#define RUNS 32
-
-START_TEST(NtAllocateVirtualMemory)
+static
+VOID
+CheckSomeDefaultAddresses(VOID)
{
- PVOID Mem1, Mem2;
- SIZE_T Size1, Size2;
- ULONG i;
NTSTATUS Status;
+ PVOID BaseAddress;
+ SIZE_T Size;
- CheckAlignment();
- CheckAdjacentVADs();
+ // NULL.
+
+ /* Reserve memory dynamically, not at 0x00000000 */
+ BaseAddress = NULL;
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ ok(BaseAddress != 0x00000000, "Unexpected BaseAddress = 0x00000000\n");
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ // 0x00000000, 64k: Free.
+
+ /* Reserve and commit memory at 0x00000000, after round down */
+ BaseAddress = UlongToPtr(0x00000000 + 0x0FFF);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ ok_ptr(BaseAddress, 0x00000000);
+
+ // Double-check that it is not forbidden "in order to catch null pointer
accesses".
+ StartSeh()
+ *(int*)UlongToPtr(0x00000000) = 1;
+ EndSeh(STATUS_SUCCESS)
+
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ /* Reserve memory above 0x00000000 */
+ BaseAddress = UlongToPtr(0x00000000 + 0x1000);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ /* The following checks assume very default addresses,
+ * no address space layout randomization (ASLR). */
+#ifdef _WIN64
+ ok(FALSE, "ToDo, 64-bit: Check/Adapt 32-bit results\n");
+#endif
- /* Reserve memory below 0x10000 */
- Mem1 = UlongToPtr(0xf000);
- Size1 = 0x1000;
+ // 0x00010000, 4k: Private Data.
+ // 0x00011000, 60k: Unusable.
+
+ /* Reserve memory below 0x00010000 */
+ BaseAddress = UlongToPtr(0x00010000 - 0x1000);
+ Size = 0x1000;
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
- &Mem1,
+ &BaseAddress,
0,
- &Size1,
+ &Size,
MEM_RESERVE,
PAGE_READWRITE);
- ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
- /* Reserve memory at 0x10000 */
- Mem1 = UlongToPtr(0x10000);
- Size1 = 0x1000;
+ /* Reserve memory at 0x00010000:
+ * Windows NT legacy default executable image base */
+ BaseAddress = UlongToPtr(0x00010000);
+ Size = 0x1000;
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
- &Mem1,
+ &BaseAddress,
0,
- &Size1,
+ &Size,
MEM_RESERVE,
PAGE_READWRITE);
ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
+ if (NT_SUCCESS(Status))
+ { // Unexpected, cleanup.
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ }
+
+ // 0x00400000: Image base.
+
+ /* Reserve memory below 0x00400000 */
+ BaseAddress = UlongToPtr(0x00400000 - 0x1000);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ if (NT_SUCCESS(Status))
+ {
+ trace("Below 0x00400000 is available, as on ReactOS and Windows
S03\n");
+ // 0x003F0000, 64k: Free.
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ }
+ else
+ {
+ trace("Below 0x00400000 is not available, as on Windows XP\n");
+ // 0x003F0000, 4k: Shareable.
+ // 0x003F1000, 60k: Unusable.
+ ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
+ }
+
+ /* Reserve memory at 0x00400000:
+ * Windows NT legacy default DLL image base,
+ * (ReactOS and) Windows 95 new default executable image base */
+ BaseAddress = UlongToPtr(0x00400000);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
+ if (NT_SUCCESS(Status))
+ { // Unexpected, cleanup.
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ }
+
+ // 0x10000000: Free.
+
+ /* Reserve memory below 0x10000000 */
+ BaseAddress = UlongToPtr(0x10000000 - 0x1000);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ /* Reserve memory at 0x10000000:
+ * Windows new default non-OS DLL image base */
+ BaseAddress = UlongToPtr(0x10000000);
+ Size = 0x1000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &Size,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size,
MEM_RELEASE);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+#ifdef _WIN64
+ skip("ToDo, 64-bit: Add 0x140000000/Exe and 0x180000000/DLL checks\n");
+#endif
+}
+
+#define RUNS 32
+
+START_TEST(NtAllocateVirtualMemory)
+{
+ PVOID Mem1, Mem2;
+ SIZE_T Size1, Size2;
+ ULONG i;
+
+ CheckAlignment();
+ CheckAdjacentVADs();
+ CheckSomeDefaultAddresses();
Size1 = 32;
Mem1 = Allocate(Size1);