1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for the NtProtectVirtualMemory API
5 * PROGRAMMERS: Jérôme Gardou <jerome.gardou@reactos.org>
6 * Thomas Faber <thomas.faber@reactos.org>
7 */
8
9 #include "precomp.h"
10
11 static
12 void
TestReadWrite(void)13 TestReadWrite(void)
14 {
15 ULONG* allocationStart = NULL;
16 NTSTATUS status;
17 SIZE_T allocationSize;
18 ULONG oldProtection;
19
20 /* Reserve a page */
21 allocationSize = PAGE_SIZE;
22 status = NtAllocateVirtualMemory(NtCurrentProcess(),
23 (void**)&allocationStart,
24 0,
25 &allocationSize,
26 MEM_RESERVE,
27 PAGE_NOACCESS);
28 ok(NT_SUCCESS(status), "Reserving memory failed\n");
29
30 /* Commit the page (RW) */
31 status = NtAllocateVirtualMemory(NtCurrentProcess(),
32 (void**)&allocationStart,
33 0,
34 &allocationSize,
35 MEM_COMMIT,
36 PAGE_READWRITE);
37 ok(NT_SUCCESS(status), "Commiting memory failed\n");
38
39 /* Try writing it */
40 StartSeh()
41 {
42 *allocationStart = 0xFF;
43 } EndSeh(STATUS_SUCCESS);
44
45 /* Try reading it */
46 StartSeh()
47 {
48 ok(*allocationStart == 0xFF, "Memory was not written\n");
49 } EndSeh(STATUS_SUCCESS);
50
51 /* Set it as read only */
52 status = NtProtectVirtualMemory(NtCurrentProcess(),
53 (void**)&allocationStart,
54 &allocationSize,
55 PAGE_READONLY,
56 &oldProtection);
57 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n");
58 ok(oldProtection == PAGE_READWRITE, "Expected PAGE_READWRITE, got %08lx.\n", oldProtection);
59
60 /* Try writing it */
61 StartSeh()
62 {
63 *allocationStart = 0xAA;
64 } EndSeh(STATUS_ACCESS_VIOLATION);
65
66 /* Try reading it */
67 StartSeh()
68 {
69 ok(*allocationStart == 0xFF, "read-only memory were changed.\n");
70 } EndSeh(STATUS_SUCCESS);
71
72 /* Set it as no access */
73 status = NtProtectVirtualMemory(NtCurrentProcess(),
74 (void**)&allocationStart,
75 &allocationSize,
76 PAGE_NOACCESS,
77 &oldProtection);
78 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n");
79 ok(oldProtection == PAGE_READONLY, "Expected PAGE_READONLY, got %08lx.\n", oldProtection);
80
81 /* Try writing it */
82 StartSeh()
83 {
84 *allocationStart = 0xAA;
85 } EndSeh(STATUS_ACCESS_VIOLATION);
86
87 /* Try reading it */
88 StartSeh()
89 {
90 ok(*allocationStart == 0, "Test should not go as far as this.\n");
91 } EndSeh(STATUS_ACCESS_VIOLATION);
92
93 /* Set it as readable again */
94 status = NtProtectVirtualMemory(NtCurrentProcess(),
95 (void**)&allocationStart,
96 &allocationSize,
97 PAGE_READONLY,
98 &oldProtection);
99 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n");
100 ok(oldProtection == PAGE_NOACCESS, "Expected PAGE_READONLY, got %08lx.\n", oldProtection);
101
102 /* Try writing it */
103 StartSeh()
104 {
105 *allocationStart = 0xAA;
106 } EndSeh(STATUS_ACCESS_VIOLATION);
107
108 /* Try reading it */
109 StartSeh()
110 {
111 ok(*allocationStart == 0xFF, "Memory content was not preserved.\n");
112 } EndSeh(STATUS_SUCCESS);
113
114 /* Free memory */
115 status = NtFreeVirtualMemory(NtCurrentProcess(),
116 (void**)&allocationStart,
117 &allocationSize,
118 MEM_RELEASE);
119 ok(NT_SUCCESS(status), "Failed freeing memory.\n");
120 }
121
122 /* Regression test for CORE-13311 */
123 static
124 void
TestFreeNoAccess(void)125 TestFreeNoAccess(void)
126 {
127 PVOID Mem;
128 SIZE_T Size;
129 NTSTATUS Status;
130 ULONG Iteration, PageNumber;
131 PUCHAR Page;
132 ULONG OldProtection;
133
134 for (Iteration = 0; Iteration < 50000; Iteration++)
135 {
136 Mem = NULL;
137 Size = 16 * PAGE_SIZE;
138 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
139 &Mem,
140 0,
141 &Size,
142 MEM_COMMIT,
143 PAGE_READWRITE);
144 ok_ntstatus(Status, STATUS_SUCCESS);
145 if (!NT_SUCCESS(Status))
146 {
147 break;
148 }
149
150 for (PageNumber = 0; PageNumber < 16; PageNumber++)
151 {
152 Page = Mem;
153 Page += PageNumber * PAGE_SIZE;
154 ok(*Page == 0,
155 "[%lu, %lu] Got non-zero memory. %x at %p\n",
156 Iteration, PageNumber, *Page, Page);
157 *Page = 123;
158 }
159
160 Status = NtProtectVirtualMemory(NtCurrentProcess(),
161 &Mem,
162 &Size,
163 PAGE_NOACCESS,
164 &OldProtection);
165 ok_ntstatus(Status, STATUS_SUCCESS);
166 ok_hex(OldProtection, PAGE_READWRITE);
167
168 Size = 0;
169 Status = NtFreeVirtualMemory(NtCurrentProcess(),
170 &Mem,
171 &Size,
172 MEM_RELEASE);
173 ok_ntstatus(Status, STATUS_SUCCESS);
174 }
175 }
176
START_TEST(NtProtectVirtualMemory)177 START_TEST(NtProtectVirtualMemory)
178 {
179 TestReadWrite();
180 TestFreeNoAccess();
181 }
182