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 }