[NTDLL_APITEST] Create Test_NtFreeVirtualMemory_Parameters(). CORE-13126
[reactos.git] / modules / rostests / apitests / ntdll / NtFreeVirtualMemory.c
1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Test for NtFreeVirtualMemory
5 * COPYRIGHT: Copyright 2011 Jérôme Gardou <jerome.gardou@reactos.org>
6 * Copyright 2017 Serge Gautherie <reactos-git_serge_171003@gautherie.fr>
7 */
8
9 #include "precomp.h"
10
11 static void Test_NtFreeVirtualMemory(void)
12 {
13 PVOID Buffer = NULL, Buffer2;
14 SIZE_T Length = PAGE_SIZE;
15 NTSTATUS Status;
16
17 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
18 &Buffer,
19 0,
20 &Length,
21 MEM_RESERVE,
22 PAGE_READWRITE);
23 ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
24 ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
25 ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
26
27 Status = NtFreeVirtualMemory(NtCurrentProcess(),
28 &Buffer,
29 &Length,
30 MEM_DECOMMIT);
31 ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
32
33 /* Now try to free more than we got */
34 Length++;
35 Status = NtFreeVirtualMemory(NtCurrentProcess(),
36 &Buffer,
37 &Length,
38 MEM_DECOMMIT);
39 ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
40
41 Status = NtFreeVirtualMemory(NtCurrentProcess(),
42 &Buffer,
43 &Length,
44 MEM_RELEASE);
45 ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
46
47 /* Free out of bounds from the wrong origin */
48 Length = PAGE_SIZE;
49 Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
50
51 Status = NtFreeVirtualMemory(NtCurrentProcess(),
52 &Buffer2,
53 &Length,
54 MEM_DECOMMIT);
55 ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
56
57 Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
58 Length = PAGE_SIZE;
59 Status = NtFreeVirtualMemory(NtCurrentProcess(),
60 &Buffer2,
61 &Length,
62 MEM_RELEASE);
63 ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
64
65 /* Same but in bounds */
66 Length = PAGE_SIZE - 1;
67 Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
68
69 Status = NtFreeVirtualMemory(NtCurrentProcess(),
70 &Buffer2,
71 &Length,
72 MEM_DECOMMIT);
73 ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
74 ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
75 ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
76
77 Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
78 Length = PAGE_SIZE-1;
79 Status = NtFreeVirtualMemory(NtCurrentProcess(),
80 &Buffer2,
81 &Length,
82 MEM_RELEASE);
83 ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
84 ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
85 ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
86
87 /* Now allocate two pages and try to free them one after the other */
88 Length = 2*PAGE_SIZE;
89 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
90 &Buffer,
91 0,
92 &Length,
93 MEM_RESERVE,
94 PAGE_READWRITE);
95 ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
96 ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
97 ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
98
99 Buffer2 = Buffer;
100 Length = PAGE_SIZE;
101 Status = NtFreeVirtualMemory(NtCurrentProcess(),
102 &Buffer2,
103 &Length,
104 MEM_RELEASE);
105 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
106 ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
107 ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
108
109 Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
110 Length = PAGE_SIZE;
111 Status = NtFreeVirtualMemory(NtCurrentProcess(),
112 &Buffer2,
113 &Length,
114 MEM_RELEASE);
115 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
116 ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
117 ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
118
119 /* Same, but try to free the second page before the first one */
120 Length = 2*PAGE_SIZE;
121 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
122 &Buffer,
123 0,
124 &Length,
125 MEM_RESERVE,
126 PAGE_READWRITE);
127 ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
128 ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
129 ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
130
131 Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
132 Length = PAGE_SIZE;
133 Status = NtFreeVirtualMemory(NtCurrentProcess(),
134 &Buffer2,
135 &Length,
136 MEM_RELEASE);
137 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
138 ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
139 ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
140
141 Buffer2 = Buffer;
142 Length = PAGE_SIZE;
143 Status = NtFreeVirtualMemory(NtCurrentProcess(),
144 &Buffer2,
145 &Length,
146 MEM_RELEASE);
147 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
148 ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
149 ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
150
151 /* Now allocate two pages and try to free them in the middle */
152 Length = 2*PAGE_SIZE;
153 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
154 &Buffer,
155 0,
156 &Length,
157 MEM_RESERVE,
158 PAGE_READWRITE);
159 ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
160 ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
161 ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
162
163 Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
164 Length = PAGE_SIZE;
165 Status = NtFreeVirtualMemory(NtCurrentProcess(),
166 &Buffer2,
167 &Length,
168 MEM_RELEASE);
169 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
170 ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
171 ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
172 }
173
174 static void Test_NtFreeVirtualMemory_Parameters(void)
175 {
176 NTSTATUS Status;
177 ULONG FreeType;
178 int i;
179
180 // 4th parameter: "ULONG FreeType".
181
182 // A type is mandatory.
183 Status = NtFreeVirtualMemory(NULL, NULL, NULL, 0ul);
184 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
185
186 // All but MEM_DECOMMIT and MEM_RELEASE are unsupported.
187 // Each bit one by one.
188 for (i = 0; i < 32; ++i)
189 {
190 FreeType = 1 << i;
191 if (FreeType == MEM_DECOMMIT || FreeType == MEM_RELEASE)
192 continue;
193
194 Status = NtFreeVirtualMemory(NULL, NULL, NULL, FreeType);
195 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
196 }
197 // All bits at once.
198 // Not testing all other values.
199 Status = NtFreeVirtualMemory(NULL, NULL, NULL, ~(MEM_DECOMMIT | MEM_RELEASE));
200 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
201 Status = NtFreeVirtualMemory(NULL, NULL, NULL, ~MEM_DECOMMIT);
202 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
203 Status = NtFreeVirtualMemory(NULL, NULL, NULL, ~MEM_RELEASE);
204 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
205 Status = NtFreeVirtualMemory(NULL, NULL, NULL, ~0ul);
206 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
207
208 // MEM_DECOMMIT and MEM_RELEASE are exclusive.
209 Status = NtFreeVirtualMemory(NULL, NULL, NULL, MEM_DECOMMIT | MEM_RELEASE);
210 ok(Status == STATUS_INVALID_PARAMETER_4, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
211 }
212
213 START_TEST(NtFreeVirtualMemory)
214 {
215 Test_NtFreeVirtualMemory();
216 Test_NtFreeVirtualMemory_Parameters();
217 }