1 
2 #include <apitest.h>
3 
4 #define WIN32_NO_STATUS
5 #include <ndk/pstypes.h>
6 #include <ndk/mmfuncs.h>
7 
8 static void Test_NtFreeVirtualMemory(void)
9 {
10     PVOID Buffer = NULL, Buffer2;
11     SIZE_T Length = PAGE_SIZE;
12     NTSTATUS Status;
13 
14     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
15                                      &Buffer,
16                                      0,
17                                      &Length,
18                                      MEM_RESERVE,
19                                      PAGE_READWRITE);
20     ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
21     ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
22     ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
23 
24     Status = NtFreeVirtualMemory(NtCurrentProcess(),
25                                  &Buffer,
26                                  &Length,
27                                  MEM_DECOMMIT);
28     ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
29 
30     /* Now try to free more than we got */
31     Length++;
32     Status = NtFreeVirtualMemory(NtCurrentProcess(),
33                                  &Buffer,
34                                  &Length,
35                                  MEM_DECOMMIT);
36     ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
37 
38     Status = NtFreeVirtualMemory(NtCurrentProcess(),
39                                  &Buffer,
40                                  &Length,
41                                  MEM_RELEASE);
42     ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
43 
44     /* Free out of bounds from the wrong origin */
45     Length = PAGE_SIZE;
46     Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
47 
48     Status = NtFreeVirtualMemory(NtCurrentProcess(),
49                                  &Buffer2,
50                                  &Length,
51                                  MEM_DECOMMIT);
52     ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
53 
54     Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
55     Length = PAGE_SIZE;
56     Status = NtFreeVirtualMemory(NtCurrentProcess(),
57                                  &Buffer2,
58                                  &Length,
59                                  MEM_RELEASE);
60     ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
61 
62     /* Same but in bounds */
63     Length = PAGE_SIZE - 1;
64     Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
65 
66     Status = NtFreeVirtualMemory(NtCurrentProcess(),
67                                  &Buffer2,
68                                  &Length,
69                                  MEM_DECOMMIT);
70     ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
71     ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
72     ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
73 
74     Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
75     Length = PAGE_SIZE-1;
76     Status = NtFreeVirtualMemory(NtCurrentProcess(),
77                                  &Buffer2,
78                                  &Length,
79                                  MEM_RELEASE);
80     ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
81     ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
82     ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
83 
84     /* Now allocate two pages and try to free them one after the other */
85     Length = 2*PAGE_SIZE;
86     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
87                                      &Buffer,
88                                      0,
89                                      &Length,
90                                      MEM_RESERVE,
91                                      PAGE_READWRITE);
92     ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
93     ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
94     ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
95 
96     Buffer2 = Buffer;
97     Length = PAGE_SIZE;
98     Status = NtFreeVirtualMemory(NtCurrentProcess(),
99                                  &Buffer2,
100                                  &Length,
101                                  MEM_RELEASE);
102     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
103     ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
104     ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
105 
106     Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
107     Length = PAGE_SIZE;
108     Status = NtFreeVirtualMemory(NtCurrentProcess(),
109                                  &Buffer2,
110                                  &Length,
111                                  MEM_RELEASE);
112     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
113     ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
114     ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
115 
116     /* Same, but try to free the second page before the first one */
117     Length = 2*PAGE_SIZE;
118     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
119                                      &Buffer,
120                                      0,
121                                      &Length,
122                                      MEM_RESERVE,
123                                      PAGE_READWRITE);
124     ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
125     ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
126     ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
127 
128     Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
129     Length = PAGE_SIZE;
130     Status = NtFreeVirtualMemory(NtCurrentProcess(),
131                                  &Buffer2,
132                                  &Length,
133                                  MEM_RELEASE);
134     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
135     ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
136     ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
137 
138     Buffer2 = Buffer;
139     Length = PAGE_SIZE;
140     Status = NtFreeVirtualMemory(NtCurrentProcess(),
141                                  &Buffer2,
142                                  &Length,
143                                  MEM_RELEASE);
144     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
145     ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
146     ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
147 
148     /* Now allocate two pages and try to free them in the middle */
149     Length = 2*PAGE_SIZE;
150     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
151                                      &Buffer,
152                                      0,
153                                      &Length,
154                                      MEM_RESERVE,
155                                      PAGE_READWRITE);
156     ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
157     ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
158     ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
159 
160     Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
161     Length = PAGE_SIZE;
162     Status = NtFreeVirtualMemory(NtCurrentProcess(),
163                                  &Buffer2,
164                                  &Length,
165                                  MEM_RELEASE);
166     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
167     ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
168     ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
169 }
170 
171 START_TEST(NtFreeVirtualMemory)
172 {
173     Test_NtFreeVirtualMemory();
174 }