1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Kernel-Mode Test Suite Section Object test 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include <kmt_test.h> 9 10 #define CheckObject(Handle, Pointers, Handles) do \ 11 { \ 12 PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \ 13 Status = ZwQueryObject(Handle, ObjectBasicInformation, \ 14 &ObjectInfo, sizeof ObjectInfo, NULL); \ 15 ok_eq_hex(Status, STATUS_SUCCESS); \ 16 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \ 17 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \ 18 } while (0) 19 20 #define CheckSection(SectionObject, SectionFlag) do \ 21 { \ 22 SECTION_BASIC_INFORMATION Sbi; \ 23 HANDLE SectionHandle = NULL; \ 24 NTSTATUS Status; \ 25 if (skip(SectionObject != NULL && \ 26 SectionObject != (PVOID)0x5555555555555555ULL, \ 27 "No section object\n")) \ 28 break; \ 29 Status = ObOpenObjectByPointer(SectionObject, OBJ_KERNEL_HANDLE, \ 30 NULL, 0, MmSectionObjectType, \ 31 KernelMode, &SectionHandle); \ 32 ok_eq_hex(Status, STATUS_SUCCESS); \ 33 ok(SectionHandle != NULL, "Section handle null\n"); \ 34 if (!skip(NT_SUCCESS(Status) && SectionHandle, \ 35 "No section handle\n")) \ 36 { \ 37 Status = ZwQuerySection(SectionHandle, SectionBasicInformation, \ 38 &Sbi, sizeof Sbi, NULL); \ 39 ok_eq_hex(Status, STATUS_SUCCESS); \ 40 ok_eq_pointer(Sbi.BaseAddress, NULL); \ 41 ok_eq_longlong(Sbi.Size.QuadPart, 1LL); \ 42 ok_eq_hex(Sbi.Attributes, SectionFlag | SEC_FILE); \ 43 ZwClose(SectionHandle); \ 44 } \ 45 } while (0) 46 47 #define TestMapView(SectionObject, ExpectAtBase, ExpectM) do \ 48 { \ 49 NTSTATUS Status; \ 50 PVOID BaseAddress = NULL; \ 51 SIZE_T ViewSize = 0; \ 52 LARGE_INTEGER SectionOffset; \ 53 if (skip(SectionObject != NULL && \ 54 SectionObject != (PVOID)0x5555555555555555ULL, \ 55 "No section object\n")) \ 56 break; \ 57 \ 58 SectionOffset.QuadPart = 0; \ 59 Status = MmMapViewOfSection(SectionObject, PsGetCurrentProcess(), \ 60 &BaseAddress, 0, 1, &SectionOffset, \ 61 &ViewSize, ViewUnmap, 0, PAGE_READONLY); \ 62 ok_eq_hex(Status, ExpectAtBase ? STATUS_SUCCESS : STATUS_IMAGE_NOT_AT_BASE);\ 63 if (!skip(NT_SUCCESS(Status), "Section not mapped\n")) \ 64 { \ 65 ok((LONG_PTR)BaseAddress > 0, "BaseAddress = %p\n", BaseAddress); \ 66 ok_eq_uint(*(PUCHAR)BaseAddress, ExpectM ? 'M' : 0); \ 67 Status = MmUnmapViewOfSection(PsGetCurrentProcess(), BaseAddress); \ 68 ok_eq_hex(Status, STATUS_SUCCESS); \ 69 } \ 70 BaseAddress = NULL; \ 71 ViewSize = 0; \ 72 Status = MmMapViewOfSection(SectionObject, PsGetCurrentProcess(), \ 73 &BaseAddress, 0, 1, &SectionOffset, \ 74 &ViewSize, ViewUnmap, 0, \ 75 PAGE_READONLY | PAGE_NOCACHE); \ 76 ok_eq_hex(Status, ExpectAtBase ? STATUS_SUCCESS : STATUS_IMAGE_NOT_AT_BASE);\ 77 if (!skip(NT_SUCCESS(Status), "Section not mapped\n")) \ 78 { \ 79 ok((LONG_PTR)BaseAddress > 0, "BaseAddress = %p\n", BaseAddress); \ 80 ok_eq_uint(*(PUCHAR)BaseAddress, ExpectM ? 'M' : 0); \ 81 Status = MmUnmapViewOfSection(PsGetCurrentProcess(), BaseAddress); \ 82 ok_eq_hex(Status, STATUS_SUCCESS); \ 83 } \ 84 } while (0) 85 86 static 87 VOID 88 TestCreateSection( 89 IN HANDLE FileHandle1, 90 IN PFILE_OBJECT FileObject1, 91 IN HANDLE FileHandle2, 92 IN PFILE_OBJECT FileObject2) 93 { 94 NTSTATUS Status = STATUS_SUCCESS; 95 PVOID SectionObject; 96 LARGE_INTEGER MaximumSize; 97 ULONG PointerCount1, PointerCount2; 98 99 KmtStartSeh() 100 Status = MmCreateSection(NULL, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); 101 KmtEndSeh(STATUS_SUCCESS); 102 ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); 103 104 if (!KmtIsCheckedBuild) 105 { 106 /* PAGE_NOACCESS and missing SEC_RESERVE/SEC_COMMIT/SEC_IMAGE assert */ 107 KmtStartSeh() 108 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, SEC_RESERVE, NULL, NULL); 109 KmtEndSeh(STATUS_ACCESS_VIOLATION); 110 111 KmtStartSeh() 112 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, 0, NULL, NULL); 113 KmtEndSeh(STATUS_ACCESS_VIOLATION); 114 } 115 116 SectionObject = KmtInvalidPointer; 117 KmtStartSeh() 118 Status = MmCreateSection(&SectionObject, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); 119 KmtEndSeh(STATUS_SUCCESS); 120 ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); 121 ok_eq_pointer(SectionObject, KmtInvalidPointer); 122 123 if (SectionObject && SectionObject != KmtInvalidPointer) 124 ObDereferenceObject(SectionObject); 125 126 KmtStartSeh() 127 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 128 KmtEndSeh(STATUS_ACCESS_VIOLATION); 129 130 SectionObject = KmtInvalidPointer; 131 KmtStartSeh() 132 Status = MmCreateSection(&SectionObject, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 133 KmtEndSeh(STATUS_ACCESS_VIOLATION); 134 ok_eq_pointer(SectionObject, KmtInvalidPointer); 135 136 if (SectionObject && SectionObject != KmtInvalidPointer) 137 ObDereferenceObject(SectionObject); 138 139 SectionObject = KmtInvalidPointer; 140 MaximumSize.QuadPart = 0; 141 KmtStartSeh() 142 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, NULL); 143 KmtEndSeh(STATUS_SUCCESS); 144 ok_eq_hex(Status, STATUS_INVALID_FILE_FOR_SECTION); 145 ok_eq_longlong(MaximumSize.QuadPart, 0LL); 146 ok_eq_pointer(SectionObject, KmtInvalidPointer); 147 148 if (SectionObject && SectionObject != KmtInvalidPointer) 149 ObDereferenceObject(SectionObject); 150 151 MaximumSize.QuadPart = 0; 152 KmtStartSeh() 153 Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 154 KmtEndSeh(STATUS_SUCCESS); 155 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); 156 ok_eq_longlong(MaximumSize.QuadPart, 0LL); 157 158 if (SectionObject && SectionObject != KmtInvalidPointer) 159 ObDereferenceObject(SectionObject); 160 161 MaximumSize.QuadPart = 1; 162 KmtStartSeh() 163 Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 164 KmtEndSeh(STATUS_ACCESS_VIOLATION); 165 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 166 167 if (SectionObject && SectionObject != KmtInvalidPointer) 168 ObDereferenceObject(SectionObject); 169 170 SectionObject = KmtInvalidPointer; 171 MaximumSize.QuadPart = 0; 172 KmtStartSeh() 173 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 174 KmtEndSeh(STATUS_SUCCESS); 175 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); 176 ok_eq_longlong(MaximumSize.QuadPart, 0LL); 177 ok_eq_pointer(SectionObject, KmtInvalidPointer); 178 179 if (SectionObject && SectionObject != KmtInvalidPointer) 180 ObDereferenceObject(SectionObject); 181 182 /* page file section */ 183 SectionObject = KmtInvalidPointer; 184 MaximumSize.QuadPart = 1; 185 KmtStartSeh() 186 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); 187 KmtEndSeh(STATUS_SUCCESS); 188 ok_eq_hex(Status, STATUS_SUCCESS); 189 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 190 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 191 ok(SectionObject != NULL, "Section object pointer NULL\n"); 192 193 if (SectionObject && SectionObject != KmtInvalidPointer) 194 ObDereferenceObject(SectionObject); 195 196 if (!skip(FileHandle1 != NULL && FileObject1 != NULL && 197 FileHandle2 != NULL && FileObject2 != NULL, "No file handle or object\n")) 198 { 199 PointerCount1 = 3; 200 PointerCount2 = 3; 201 /* image section */ 202 CheckObject(FileHandle2, PointerCount2, 1L); 203 SectionObject = KmtInvalidPointer; 204 MaximumSize.QuadPart = 1; 205 KmtStartSeh() 206 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, NULL); 207 KmtEndSeh(STATUS_SUCCESS); 208 ok_eq_hex(Status, STATUS_SUCCESS); 209 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 210 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 211 ok(SectionObject != NULL, "Section object pointer NULL\n"); 212 CheckObject(FileHandle2, PointerCount2, 1L); 213 CheckSection(SectionObject, SEC_IMAGE); 214 TestMapView(SectionObject, FALSE, TRUE); 215 216 if (SectionObject && SectionObject != KmtInvalidPointer) 217 ObDereferenceObject(SectionObject); 218 219 CheckObject(FileHandle2, PointerCount2, 1L); 220 SectionObject = KmtInvalidPointer; 221 MaximumSize.QuadPart = 1; 222 KmtStartSeh() 223 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject2); 224 KmtEndSeh(STATUS_SUCCESS); 225 ok_eq_hex(Status, STATUS_SUCCESS); 226 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 227 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 228 ok(SectionObject != NULL, "Section object pointer NULL\n"); 229 ++PointerCount2; 230 CheckObject(FileHandle2, PointerCount2, 1L); 231 CheckSection(SectionObject, 0); 232 TestMapView(SectionObject, TRUE, TRUE); 233 234 if (SectionObject && SectionObject != KmtInvalidPointer) 235 ObDereferenceObject(SectionObject); 236 //--PointerCount2; // ???? 237 238 CheckObject(FileHandle2, PointerCount2, 1L); 239 SectionObject = KmtInvalidPointer; 240 MaximumSize.QuadPart = 1; 241 KmtStartSeh() 242 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject2); 243 KmtEndSeh(STATUS_SUCCESS); 244 ok_eq_hex(Status, STATUS_SUCCESS); 245 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 246 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 247 ok(SectionObject != NULL, "Section object pointer NULL\n"); 248 CheckObject(FileHandle2, PointerCount2, 1L); 249 CheckSection(SectionObject, 0); 250 TestMapView(SectionObject, TRUE, TRUE); 251 252 if (SectionObject && SectionObject != KmtInvalidPointer) 253 ObDereferenceObject(SectionObject); 254 255 /* image section with inappropriate file */ 256 CheckObject(FileHandle1, PointerCount1, 1L); 257 SectionObject = KmtInvalidPointer; 258 MaximumSize.QuadPart = 1; 259 KmtStartSeh() 260 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, NULL); 261 KmtEndSeh(STATUS_SUCCESS); 262 ok_eq_hex(Status, STATUS_INVALID_IMAGE_NOT_MZ); 263 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 264 ok_eq_pointer(SectionObject, KmtInvalidPointer); 265 CheckObject(FileHandle1, PointerCount1, 1L); 266 267 if (SectionObject && SectionObject != KmtInvalidPointer) 268 ObDereferenceObject(SectionObject); 269 270 CheckObject(FileHandle1, PointerCount1, 1L); 271 SectionObject = KmtInvalidPointer; 272 MaximumSize.QuadPart = 1; 273 KmtStartSeh() 274 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject1); 275 KmtEndSeh(STATUS_SUCCESS); 276 ok_eq_hex(Status, STATUS_SUCCESS); 277 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 278 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 279 ok(SectionObject != NULL, "Section object pointer NULL\n"); 280 ++PointerCount1; 281 CheckObject(FileHandle1, PointerCount1, 1L); 282 CheckSection(SectionObject, 0); 283 TestMapView(SectionObject, TRUE, FALSE); 284 285 if (SectionObject && SectionObject != KmtInvalidPointer) 286 ObDereferenceObject(SectionObject); 287 //--PointerCount1; // ???? 288 289 CheckObject(FileHandle1, PointerCount1, 1L); 290 SectionObject = KmtInvalidPointer; 291 MaximumSize.QuadPart = 1; 292 KmtStartSeh() 293 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject1); 294 KmtEndSeh(STATUS_SUCCESS); 295 ok_eq_hex(Status, STATUS_SUCCESS); 296 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 297 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 298 ok(SectionObject != NULL, "Section object pointer NULL\n"); 299 CheckObject(FileHandle1, PointerCount1, 1L); 300 CheckSection(SectionObject, 0); 301 TestMapView(SectionObject, TRUE, FALSE); 302 303 if (SectionObject && SectionObject != KmtInvalidPointer) 304 ObDereferenceObject(SectionObject); 305 306 /* image section with two different files */ 307 CheckObject(FileHandle1, PointerCount1, 1L); 308 SectionObject = KmtInvalidPointer; 309 MaximumSize.QuadPart = 1; 310 KmtStartSeh() 311 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject2); 312 KmtEndSeh(STATUS_SUCCESS); 313 ok_eq_hex(Status, STATUS_SUCCESS); 314 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 315 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 316 ok(SectionObject != NULL, "Section object pointer NULL\n"); 317 CheckObject(FileHandle1, PointerCount1, 1L); 318 CheckObject(FileHandle2, PointerCount2, 1L); 319 CheckSection(SectionObject, 0); 320 TestMapView(SectionObject, TRUE, TRUE); 321 322 if (SectionObject && SectionObject != KmtInvalidPointer) 323 ObDereferenceObject(SectionObject); 324 325 CheckObject(FileHandle1, PointerCount1, 1L); 326 SectionObject = KmtInvalidPointer; 327 MaximumSize.QuadPart = 1; 328 KmtStartSeh() 329 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject1); 330 KmtEndSeh(STATUS_SUCCESS); 331 ok_eq_hex(Status, STATUS_SUCCESS); 332 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 333 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 334 ok(SectionObject != NULL, "Section object pointer NULL\n"); 335 CheckObject(FileHandle1, PointerCount1, 1L); 336 CheckObject(FileHandle2, PointerCount2, 1L); 337 CheckSection(SectionObject, 0); 338 TestMapView(SectionObject, TRUE, FALSE); 339 340 if (SectionObject && SectionObject != KmtInvalidPointer) 341 ObDereferenceObject(SectionObject); 342 343 /* data file section */ 344 CheckObject(FileHandle1, PointerCount1, 1L); 345 SectionObject = KmtInvalidPointer; 346 MaximumSize.QuadPart = 1; 347 KmtStartSeh() 348 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, NULL); 349 KmtEndSeh(STATUS_SUCCESS); 350 ok_eq_hex(Status, STATUS_SUCCESS); 351 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 352 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 353 ok(SectionObject != NULL, "Section object pointer NULL\n"); 354 CheckObject(FileHandle1, PointerCount1, 1L); 355 CheckSection(SectionObject, 0); 356 TestMapView(SectionObject, TRUE, FALSE); 357 358 if (SectionObject && SectionObject != KmtInvalidPointer) 359 ObDereferenceObject(SectionObject); 360 361 CheckObject(FileHandle1, PointerCount1, 1L); 362 SectionObject = KmtInvalidPointer; 363 MaximumSize.QuadPart = 1; 364 KmtStartSeh() 365 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, FileObject1); 366 KmtEndSeh(STATUS_SUCCESS); 367 ok_eq_hex(Status, STATUS_SUCCESS); 368 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 369 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 370 ok(SectionObject != NULL, "Section object pointer NULL\n"); 371 CheckObject(FileHandle1, PointerCount1, 1L); 372 CheckSection(SectionObject, 0); 373 TestMapView(SectionObject, TRUE, FALSE); 374 375 if (SectionObject && SectionObject != KmtInvalidPointer) 376 ObDereferenceObject(SectionObject); 377 378 CheckObject(FileHandle1, PointerCount1, 1L); 379 SectionObject = KmtInvalidPointer; 380 MaximumSize.QuadPart = 1; 381 KmtStartSeh() 382 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, FileObject1); 383 KmtEndSeh(STATUS_SUCCESS); 384 ok_eq_hex(Status, STATUS_SUCCESS); 385 ok_eq_longlong(MaximumSize.QuadPart, 1LL); 386 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); 387 ok(SectionObject != NULL, "Section object pointer NULL\n"); 388 CheckObject(FileHandle1, PointerCount1, 1L); 389 CheckSection(SectionObject, 0); 390 TestMapView(SectionObject, TRUE, FALSE); 391 392 if (SectionObject && SectionObject != KmtInvalidPointer) 393 ObDereferenceObject(SectionObject); 394 395 CheckObject(FileHandle1, PointerCount1, 1L); 396 } 397 } 398 399 static 400 VOID 401 TestPhysicalMemorySection(VOID) 402 { 403 NTSTATUS Status; 404 UNICODE_STRING SectionName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); 405 OBJECT_ATTRIBUTES ObjectAttributes; 406 HANDLE SectionHandle; 407 PVOID SectionObject; 408 PUCHAR MyPage; 409 PHYSICAL_ADDRESS MyPagePhysical; 410 PUCHAR ZeroPageContents; 411 PHYSICAL_ADDRESS ZeroPagePhysical; 412 PHYSICAL_ADDRESS PhysicalAddress; 413 PVOID Mapping; 414 SYSTEM_BASIC_INFORMATION BasicInfo; 415 PUCHAR MappingBytes; 416 SIZE_T ViewSize; 417 SIZE_T EqualBytes; 418 struct 419 { 420 PVOID Mapping; 421 PHYSICAL_ADDRESS PhysicalAddress; 422 SIZE_T ViewSize; 423 } *UserStruct; 424 PVOID UserMem; 425 SIZE_T UserSize; 426 427 MyPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPmK'); 428 if (skip(MyPage != NULL, "Out of memory\n")) 429 return; 430 MyPagePhysical = MmGetPhysicalAddress(MyPage); 431 RtlFillMemory(MyPage + 0 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x23); 432 RtlFillMemory(MyPage + 1 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x67); 433 RtlFillMemory(MyPage + 2 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xab); 434 RtlFillMemory(MyPage + 3 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xef); 435 436 ZeroPageContents = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'ZPmK'); 437 if (skip(ZeroPageContents != NULL, "Out of memory\n")) 438 { 439 ExFreePoolWithTag(MyPage, 'MPmK'); 440 return; 441 } 442 ZeroPagePhysical.QuadPart = 0; 443 444 Mapping = MmMapIoSpace(ZeroPagePhysical, PAGE_SIZE, MmCached); 445 if (skip(Mapping != NULL, "Failed to map zero page\n")) 446 { 447 ExFreePoolWithTag(ZeroPageContents, 'ZPmK'); 448 ExFreePoolWithTag(MyPage, 'MPmK'); 449 return; 450 } 451 452 RtlCopyMemory(ZeroPageContents, Mapping, PAGE_SIZE); 453 MmUnmapIoSpace(Mapping, PAGE_SIZE); 454 455 InitializeObjectAttributes(&ObjectAttributes, 456 &SectionName, 457 0, 458 NULL, 459 NULL); 460 Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes); 461 ok_eq_hex(Status, STATUS_SUCCESS); 462 if (!skip(NT_SUCCESS(Status), "No section\n")) 463 { 464 /* Map zero page and compare */ 465 Mapping = NULL; 466 ViewSize = PAGE_SIZE; 467 Status = ZwMapViewOfSection(SectionHandle, 468 ZwCurrentProcess(), 469 &Mapping, 470 0, 471 0, 472 &ZeroPagePhysical, 473 &ViewSize, 474 ViewUnmap, 475 0, 476 PAGE_READWRITE); 477 ok_eq_hex(Status, STATUS_SUCCESS); 478 if (!skip(NT_SUCCESS(Status), "No view\n")) 479 { 480 ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); 481 EqualBytes = RtlCompareMemory(Mapping, 482 ZeroPageContents, 483 PAGE_SIZE); 484 ok_eq_size(EqualBytes, PAGE_SIZE); 485 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 486 ok_eq_hex(Status, STATUS_SUCCESS); 487 } 488 489 /* Map the zero page non-cached */ 490 Mapping = NULL; 491 ViewSize = PAGE_SIZE; 492 Status = ZwMapViewOfSection(SectionHandle, 493 ZwCurrentProcess(), 494 &Mapping, 495 0, 496 0, 497 &ZeroPagePhysical, 498 &ViewSize, 499 ViewUnmap, 500 0, 501 PAGE_READWRITE | PAGE_NOCACHE); 502 ok_eq_hex(Status, STATUS_SUCCESS); 503 if (!skip(NT_SUCCESS(Status), "No view\n")) 504 { 505 ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); 506 EqualBytes = RtlCompareMemory(Mapping, 507 ZeroPageContents, 508 PAGE_SIZE); 509 ok_eq_size(EqualBytes, PAGE_SIZE); 510 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 511 ok_eq_hex(Status, STATUS_SUCCESS); 512 } 513 514 /* Map our NP page, compare, and check that modifications are reflected */ 515 Mapping = NULL; 516 ViewSize = PAGE_SIZE; 517 Status = ZwMapViewOfSection(SectionHandle, 518 ZwCurrentProcess(), 519 &Mapping, 520 0, 521 0, 522 &MyPagePhysical, 523 &ViewSize, 524 ViewUnmap, 525 0, 526 PAGE_READWRITE); 527 ok_eq_hex(Status, STATUS_SUCCESS); 528 if (!skip(NT_SUCCESS(Status), "No view\n")) 529 { 530 ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); 531 EqualBytes = RtlCompareMemory(Mapping, 532 MyPage, 533 PAGE_SIZE); 534 ok_eq_size(EqualBytes, PAGE_SIZE); 535 536 MappingBytes = Mapping; 537 ok(MappingBytes[5] == 0x23, "Mapping[5] = 0x%x\n", MappingBytes[5]); 538 ok(MyPage[5] == 0x23, "MyPage[5] = 0x%x\n", MyPage[5]); 539 540 MyPage[5] = 0x44; 541 ok(MappingBytes[5] == 0x44, "Mapping[5] = 0x%x\n", MappingBytes[5]); 542 ok(MyPage[5] == 0x44, "MyPage[5] = 0x%x\n", MyPage[5]); 543 544 MappingBytes[5] = 0x88; 545 ok(MappingBytes[5] == 0x88, "Mapping[5] = 0x%x\n", MappingBytes[5]); 546 ok(MyPage[5] == 0x88, "MyPage[5] = 0x%x\n", MyPage[5]); 547 548 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 549 ok_eq_hex(Status, STATUS_SUCCESS); 550 } 551 552 /* Unaligned mapping will get aligned automatically */ 553 Mapping = NULL; 554 ViewSize = PAGE_SIZE - 4; 555 PhysicalAddress.QuadPart = MyPagePhysical.QuadPart + 4; 556 Status = ZwMapViewOfSection(SectionHandle, 557 ZwCurrentProcess(), 558 &Mapping, 559 0, 560 0, 561 &PhysicalAddress, 562 &ViewSize, 563 ViewUnmap, 564 0, 565 PAGE_READWRITE); 566 ok_eq_hex(Status, STATUS_SUCCESS); 567 if (!skip(NT_SUCCESS(Status), "No view\n")) 568 { 569 ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); 570 ok(((ULONG_PTR)Mapping % PAGE_SIZE) == 0, "Mapping = %p\n", Mapping); 571 ok_eq_ulong(ViewSize, PAGE_SIZE); 572 573 EqualBytes = RtlCompareMemory(Mapping, 574 MyPage, 575 PAGE_SIZE); 576 ok_eq_size(EqualBytes, PAGE_SIZE); 577 578 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 579 ok_eq_hex(Status, STATUS_SUCCESS); 580 } 581 582 /* The following tests need to pass parameters in user mode */ 583 UserStruct = NULL; 584 UserMem = NULL; 585 UserSize = PAGE_SIZE; 586 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), 587 &UserMem, 588 0, 589 &UserSize, 590 MEM_COMMIT, 591 PAGE_READWRITE); 592 ok_eq_hex(Status, STATUS_SUCCESS); 593 if (NT_SUCCESS(Status)) 594 UserStruct = UserMem; 595 596 /* Find highest physical page -- only kernel can map beyond this */ 597 Status = ZwQuerySystemInformation(SystemBasicInformation, 598 &BasicInfo, 599 sizeof(BasicInfo), 600 NULL); 601 ok_eq_hex(Status, STATUS_SUCCESS); 602 trace("HighestPhysicalPageNumber: %lx\n", BasicInfo.HighestPhysicalPageNumber); 603 604 /* Start one page before highest physical -- succeeds for user/kernel */ 605 Mapping = NULL; 606 ViewSize = PAGE_SIZE; 607 PhysicalAddress.QuadPart = (ULONGLONG)(BasicInfo.HighestPhysicalPageNumber - 1) << PAGE_SHIFT; 608 Status = ZwMapViewOfSection(SectionHandle, 609 ZwCurrentProcess(), 610 &Mapping, 611 0, 612 0, 613 &PhysicalAddress, 614 &ViewSize, 615 ViewUnmap, 616 0, 617 PAGE_READWRITE); 618 ok_eq_hex(Status, STATUS_SUCCESS); 619 if (NT_SUCCESS(Status)) 620 ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 621 622 /* Repeat from user mode */ 623 if (!skip(UserStruct != NULL, "No user memory\n")) 624 { 625 KmtStartSeh() 626 UserStruct->Mapping = NULL; 627 UserStruct->PhysicalAddress.QuadPart = PhysicalAddress.QuadPart; 628 UserStruct->ViewSize = PAGE_SIZE; 629 KmtEndSeh(STATUS_SUCCESS); 630 631 Status = NtMapViewOfSection(SectionHandle, 632 NtCurrentProcess(), 633 &UserStruct->Mapping, 634 0, 635 0, 636 &UserStruct->PhysicalAddress, 637 &UserStruct->ViewSize, 638 ViewUnmap, 639 0, 640 PAGE_READWRITE); 641 ok_eq_hex(Status, STATUS_SUCCESS); 642 if (NT_SUCCESS(Status)) 643 { 644 KmtStartSeh() 645 ZwUnmapViewOfSection(ZwCurrentProcess(), UserStruct->Mapping); 646 KmtEndSeh(STATUS_SUCCESS); 647 } 648 } 649 650 /* Now start at highest physical -- fails for user */ 651 Mapping = NULL; 652 ViewSize = PAGE_SIZE; 653 PhysicalAddress.QuadPart = (ULONGLONG)BasicInfo.HighestPhysicalPageNumber << PAGE_SHIFT; 654 Status = ZwMapViewOfSection(SectionHandle, 655 ZwCurrentProcess(), 656 &Mapping, 657 0, 658 0, 659 &PhysicalAddress, 660 &ViewSize, 661 ViewUnmap, 662 0, 663 PAGE_READWRITE); 664 ok_eq_hex(Status, STATUS_SUCCESS); 665 if (NT_SUCCESS(Status)) 666 ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 667 668 /* Repeat from user mode */ 669 if (!skip(UserStruct != NULL, "No user memory\n")) 670 { 671 KmtStartSeh() 672 UserStruct->Mapping = NULL; 673 UserStruct->PhysicalAddress.QuadPart = PhysicalAddress.QuadPart; 674 UserStruct->ViewSize = PAGE_SIZE; 675 KmtEndSeh(STATUS_SUCCESS); 676 677 Status = NtMapViewOfSection(SectionHandle, 678 NtCurrentProcess(), 679 &UserStruct->Mapping, 680 0, 681 0, 682 &UserStruct->PhysicalAddress, 683 &UserStruct->ViewSize, 684 ViewUnmap, 685 0, 686 PAGE_READWRITE); 687 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); 688 if (NT_SUCCESS(Status)) 689 { 690 KmtStartSeh() 691 ZwUnmapViewOfSection(ZwCurrentProcess(), UserStruct->Mapping); 692 KmtEndSeh(STATUS_SUCCESS); 693 } 694 } 695 696 /* End of view crosses highest physical -- fails for user */ 697 Mapping = NULL; 698 ViewSize = 2 * PAGE_SIZE; 699 PhysicalAddress.QuadPart = (ULONGLONG)(BasicInfo.HighestPhysicalPageNumber - 1) << PAGE_SHIFT; 700 Status = ZwMapViewOfSection(SectionHandle, 701 ZwCurrentProcess(), 702 &Mapping, 703 0, 704 0, 705 &PhysicalAddress, 706 &ViewSize, 707 ViewUnmap, 708 0, 709 PAGE_READWRITE); 710 ok_eq_hex(Status, STATUS_SUCCESS); 711 if (NT_SUCCESS(Status)) 712 ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); 713 714 /* Repeat from user mode */ 715 if (!skip(UserStruct != NULL, "No user memory\n")) 716 { 717 KmtStartSeh() 718 UserStruct->Mapping = NULL; 719 UserStruct->PhysicalAddress.QuadPart = PhysicalAddress.QuadPart; 720 UserStruct->ViewSize = 2 * PAGE_SIZE; 721 KmtEndSeh(STATUS_SUCCESS); 722 723 Status = NtMapViewOfSection(SectionHandle, 724 NtCurrentProcess(), 725 &UserStruct->Mapping, 726 0, 727 0, 728 &UserStruct->PhysicalAddress, 729 &UserStruct->ViewSize, 730 ViewUnmap, 731 0, 732 PAGE_READWRITE); 733 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); 734 if (NT_SUCCESS(Status)) 735 { 736 KmtStartSeh() 737 ZwUnmapViewOfSection(ZwCurrentProcess(), UserStruct->Mapping); 738 KmtEndSeh(STATUS_SUCCESS); 739 } 740 } 741 742 /* Free user memory and close section */ 743 if (!skip(UserStruct != NULL, "No user memory\n")) 744 { 745 UserSize = 0; 746 Status = ZwFreeVirtualMemory(ZwCurrentProcess(), 747 &UserMem, 748 &UserSize, 749 MEM_RELEASE); 750 ok_eq_hex(Status, STATUS_SUCCESS); 751 } 752 753 Status = ObCloseHandle(SectionHandle, UserMode); 754 ok_eq_hex(Status, STATUS_SUCCESS); 755 } 756 757 /* Try flag 0x80000000, which ROS calls SEC_PHYSICALMEMORY */ 758 InitializeObjectAttributes(&ObjectAttributes, 759 NULL, 760 OBJ_KERNEL_HANDLE, 761 NULL, 762 NULL); 763 Status = ZwCreateSection(&SectionHandle, 764 SECTION_ALL_ACCESS, 765 &ObjectAttributes, 766 NULL, 767 PAGE_READWRITE, 768 0x80000000, 769 NULL); 770 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); 771 if (NT_SUCCESS(Status)) 772 ZwClose(SectionHandle); 773 774 /* Assertion failure: AllocationAttributes & SEC_IMAGE | SEC_RESERVE | SEC_COMMIT */ 775 if (!KmtIsCheckedBuild) 776 { 777 InitializeObjectAttributes(&ObjectAttributes, 778 NULL, 779 OBJ_KERNEL_HANDLE, 780 NULL, 781 NULL); 782 Status = MmCreateSection(&SectionObject, 783 SECTION_ALL_ACCESS, 784 &ObjectAttributes, 785 NULL, 786 PAGE_READWRITE, 787 0x80000000, 788 NULL, 789 NULL); 790 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); 791 if (NT_SUCCESS(Status)) 792 ObDereferenceObject(SectionObject); 793 } 794 795 InitializeObjectAttributes(&ObjectAttributes, 796 NULL, 797 OBJ_KERNEL_HANDLE, 798 NULL, 799 NULL); 800 Status = MmCreateSection(&SectionObject, 801 SECTION_ALL_ACCESS, 802 &ObjectAttributes, 803 NULL, 804 PAGE_READWRITE, 805 SEC_RESERVE | 0x80000000, 806 NULL, 807 NULL); 808 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); 809 if (NT_SUCCESS(Status)) 810 ObDereferenceObject(SectionObject); 811 812 ExFreePoolWithTag(ZeroPageContents, 'ZPmK'); 813 ExFreePoolWithTag(MyPage, 'MPmK'); 814 } 815 816 START_TEST(MmSection) 817 { 818 NTSTATUS Status; 819 HANDLE FileHandle1 = NULL, FileHandle2 = NULL; 820 PFILE_OBJECT FileObject1 = NULL, FileObject2 = NULL; 821 OBJECT_ATTRIBUTES ObjectAttributes; 822 IO_STATUS_BLOCK IoStatusBlock; 823 UNICODE_STRING FileName1 = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt"); 824 UNICODE_STRING FileName2 = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); 825 LARGE_INTEGER FileOffset; 826 UCHAR FileData = 0; 827 828 ok(ExGetPreviousMode() == UserMode, "Previous mode is kernel mode\n"); 829 /* create a one-byte file that we can use */ 830 InitializeObjectAttributes(&ObjectAttributes, &FileName1, OBJ_CASE_INSENSITIVE, NULL, NULL); 831 Status = ZwCreateFile(&FileHandle1, GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE, NULL, 0); 832 ok_eq_hex(Status, STATUS_SUCCESS); 833 ok_eq_ulongptr(IoStatusBlock.Information, FILE_CREATED); 834 ok(FileHandle1 != NULL, "FileHandle1 is NULL\n"); 835 if (FileHandle1) 836 { 837 FileOffset.QuadPart = 0; 838 Status = ZwWriteFile(FileHandle1, NULL, NULL, NULL, &IoStatusBlock, &FileData, sizeof FileData, &FileOffset, NULL); 839 ok(Status == STATUS_SUCCESS || Status == STATUS_PENDING, "Status = 0x%08lx\n", Status); 840 Status = ZwWaitForSingleObject(FileHandle1, FALSE, NULL); 841 ok_eq_hex(Status, STATUS_SUCCESS); 842 ok_eq_ulongptr(IoStatusBlock.Information, 1); 843 Status = ZwClose(FileHandle1); 844 ok_eq_hex(Status, STATUS_SUCCESS); 845 FileHandle1 = NULL; 846 } 847 848 InitializeObjectAttributes(&ObjectAttributes, &FileName1, OBJ_CASE_INSENSITIVE, NULL, NULL); 849 Status = ZwCreateFile(&FileHandle1, GENERIC_ALL, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0); 850 ok_eq_hex(Status, STATUS_SUCCESS); 851 ok_eq_ulongptr(IoStatusBlock.Information, FILE_OPENED); 852 ok(FileHandle1 != NULL, "FileHandle1 is NULL\n"); 853 CheckObject(FileHandle1, 2L, 1L); 854 855 InitializeObjectAttributes(&ObjectAttributes, &FileName2, OBJ_CASE_INSENSITIVE, NULL, NULL); 856 Status = ZwCreateFile(&FileHandle2, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); 857 ok_eq_hex(Status, STATUS_SUCCESS); 858 ok_eq_ulongptr(IoStatusBlock.Information, FILE_OPENED); 859 ok(FileHandle2 != NULL, "FileHandle2 is NULL\n"); 860 861 if (!skip(Status == STATUS_SUCCESS && FileHandle1 != NULL, "Failed to open file 1\n")) 862 { 863 Status = ObReferenceObjectByHandle(FileHandle1, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject1, NULL); 864 ok_eq_hex(Status, STATUS_SUCCESS); 865 ok(FileObject1 != NULL, "FileObject1 is NULL\n"); 866 CheckObject(FileHandle1, 3L, 1L); 867 } 868 869 if (!skip(Status == STATUS_SUCCESS && FileHandle2 != NULL, "Failed to open file 2\n")) 870 { 871 Status = ObReferenceObjectByHandle(FileHandle2, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject2, NULL); 872 ok_eq_hex(Status, STATUS_SUCCESS); 873 ok(FileObject2 != NULL, "FileObject2 is NULL\n"); 874 } 875 876 trace("FileHandle1=%p, FileObject1=%p\n", FileHandle1, FileObject1); 877 trace("FileHandle2=%p, FileObject2=%p\n", FileHandle2, FileObject2); 878 TestCreateSection(FileHandle1, FileObject1, FileHandle2, FileObject2); 879 880 if (FileObject2) 881 ObDereferenceObject(FileObject2); 882 if (FileObject1) 883 ObDereferenceObject(FileObject1); 884 if (FileHandle2) 885 ZwClose(FileHandle2); 886 if (FileHandle1) 887 ZwClose(FileHandle1); 888 889 TestPhysicalMemorySection(); 890 } 891