[NTOS:MM]
[reactos.git] / rostests / kmtests / ntos_mm / MmSection.c
index 7fdc12c..8cc5281 100644 (file)
     ok_eq_hex(Status, ExpectAtBase ? STATUS_SUCCESS : STATUS_IMAGE_NOT_AT_BASE);\
     if (!skip(NT_SUCCESS(Status), "Section not mapped\n"))                      \
     {                                                                           \
+        ok((LONG_PTR)BaseAddress > 0, "BaseAddress = %p\n", BaseAddress);       \
+        ok_eq_uint(*(PUCHAR)BaseAddress, ExpectM ? 'M' : 0);                    \
+        Status = MmUnmapViewOfSection(PsGetCurrentProcess(), BaseAddress);      \
+        ok_eq_hex(Status, STATUS_SUCCESS);                                      \
+    }                                                                           \
+    BaseAddress = NULL;                                                         \
+    ViewSize = 0;                                                               \
+    Status = MmMapViewOfSection(SectionObject, PsGetCurrentProcess(),           \
+                                &BaseAddress, 0, 1, &SectionOffset,             \
+                                &ViewSize, ViewUnmap, 0,                        \
+                                PAGE_READONLY | PAGE_NOCACHE);                  \
+    ok_eq_hex(Status, ExpectAtBase ? STATUS_SUCCESS : STATUS_IMAGE_NOT_AT_BASE);\
+    if (!skip(NT_SUCCESS(Status), "Section not mapped\n"))                      \
+    {                                                                           \
+        ok((LONG_PTR)BaseAddress > 0, "BaseAddress = %p\n", BaseAddress);       \
         ok_eq_uint(*(PUCHAR)BaseAddress, ExpectM ? 'M' : 0);                    \
         Status = MmUnmapViewOfSection(PsGetCurrentProcess(), BaseAddress);      \
         ok_eq_hex(Status, STATUS_SUCCESS);                                      \
@@ -381,6 +396,212 @@ TestCreateSection(
     }
 }
 
+static
+VOID
+TestPhysicalMemorySection(VOID)
+{
+    NTSTATUS Status;
+    UNICODE_STRING SectionName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE SectionHandle;
+    PVOID SectionObject;
+    PUCHAR MyPage;
+    PHYSICAL_ADDRESS MyPagePhysical;
+    PUCHAR ZeroPageContents;
+    PHYSICAL_ADDRESS ZeroPagePhysical;
+    PVOID Mapping;
+    PUCHAR MappingBytes;
+    SIZE_T ViewSize;
+    SIZE_T EqualBytes;
+
+    MyPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPmK');
+    if (skip(MyPage != NULL, "Out of memory\n"))
+        return;
+    MyPagePhysical = MmGetPhysicalAddress(MyPage);
+    RtlFillMemory(MyPage + 0 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x23);
+    RtlFillMemory(MyPage + 1 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x67);
+    RtlFillMemory(MyPage + 2 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xab);
+    RtlFillMemory(MyPage + 3 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xef);
+
+    ZeroPageContents = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'ZPmK');
+    if (skip(ZeroPageContents != NULL, "Out of memory\n"))
+    {
+        ExFreePoolWithTag(MyPage, 'MPmK');
+        return;
+    }
+    ZeroPagePhysical.QuadPart = 0;
+
+    Mapping = MmMapIoSpace(ZeroPagePhysical, PAGE_SIZE, MmCached);
+    if (skip(Mapping != NULL, "Failed to map zero page\n"))
+    {
+        ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
+        ExFreePoolWithTag(MyPage, 'MPmK');
+        return;
+    }
+
+    RtlCopyMemory(ZeroPageContents, Mapping, PAGE_SIZE);
+    MmUnmapIoSpace(Mapping, PAGE_SIZE);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SectionName,
+                               OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+    if (!skip(NT_SUCCESS(Status), "No section\n"))
+    {
+        /* Map zero page and compare */
+        Mapping = NULL;
+        ViewSize = PAGE_SIZE;
+        Status = ZwMapViewOfSection(SectionHandle,
+                                    ZwCurrentProcess(),
+                                    &Mapping,
+                                    0,
+                                    0,
+                                    &ZeroPagePhysical,
+                                    &ViewSize,
+                                    ViewUnmap,
+                                    0,
+                                    PAGE_READWRITE);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        if (!skip(NT_SUCCESS(Status), "No view\n"))
+        {
+            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
+            EqualBytes = RtlCompareMemory(Mapping,
+                                          ZeroPageContents,
+                                          PAGE_SIZE);
+            ok_eq_size(EqualBytes, PAGE_SIZE);
+            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
+            ok_eq_hex(Status, STATUS_SUCCESS);
+        }
+
+        /* Map the zero page non-cached */
+        Mapping = NULL;
+        ViewSize = PAGE_SIZE;
+        Status = ZwMapViewOfSection(SectionHandle,
+                                    ZwCurrentProcess(),
+                                    &Mapping,
+                                    0,
+                                    0,
+                                    &ZeroPagePhysical,
+                                    &ViewSize,
+                                    ViewUnmap,
+                                    0,
+                                    PAGE_READWRITE | PAGE_NOCACHE);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        if (!skip(NT_SUCCESS(Status), "No view\n"))
+        {
+            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
+            EqualBytes = RtlCompareMemory(Mapping,
+                                          ZeroPageContents,
+                                          PAGE_SIZE);
+            ok_eq_size(EqualBytes, PAGE_SIZE);
+            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
+            ok_eq_hex(Status, STATUS_SUCCESS);
+        }
+
+        /* Map our NP page, compare, and check that modifications are reflected */
+        Mapping = NULL;
+        ViewSize = PAGE_SIZE;
+        Status = ZwMapViewOfSection(SectionHandle,
+                                    ZwCurrentProcess(),
+                                    &Mapping,
+                                    0,
+                                    0,
+                                    &MyPagePhysical,
+                                    &ViewSize,
+                                    ViewUnmap,
+                                    0,
+                                    PAGE_READWRITE);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        if (!skip(NT_SUCCESS(Status), "No view\n"))
+        {
+            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
+            EqualBytes = RtlCompareMemory(Mapping,
+                                          MyPage,
+                                          PAGE_SIZE);
+            ok_eq_size(EqualBytes, PAGE_SIZE);
+
+            MappingBytes = Mapping;
+            ok(MappingBytes[5] == 0x23, "Mapping[5] = 0x%x\n", MappingBytes[5]);
+            ok(MyPage[5] == 0x23, "MyPage[5] = 0x%x\n", MyPage[5]);
+
+            MyPage[5] = 0x44;
+            ok(MappingBytes[5] == 0x44, "Mapping[5] = 0x%x\n", MappingBytes[5]);
+            ok(MyPage[5] == 0x44, "MyPage[5] = 0x%x\n", MyPage[5]);
+
+            MappingBytes[5] = 0x88;
+            ok(MappingBytes[5] == 0x88, "Mapping[5] = 0x%x\n", MappingBytes[5]);
+            ok(MyPage[5] == 0x88, "MyPage[5] = 0x%x\n", MyPage[5]);
+
+            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
+            ok_eq_hex(Status, STATUS_SUCCESS);
+        }
+
+        Status = ZwClose(SectionHandle);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+    }
+
+    /* Try flag 0x80000000, which ROS calls SEC_PHYSICALMEMORY */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwCreateSection(&SectionHandle,
+                             SECTION_ALL_ACCESS,
+                             &ObjectAttributes,
+                             NULL,
+                             PAGE_READWRITE,
+                             0x80000000,
+                             NULL);
+    ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
+    if (NT_SUCCESS(Status))
+        ZwClose(SectionHandle);
+
+    /* Assertion failure: AllocationAttributes & SEC_IMAGE | SEC_RESERVE | SEC_COMMIT */
+    if (!KmtIsCheckedBuild)
+    {
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = MmCreateSection(&SectionObject,
+                             SECTION_ALL_ACCESS,
+                             &ObjectAttributes,
+                             NULL,
+                             PAGE_READWRITE,
+                             0x80000000,
+                             NULL,
+                             NULL);
+    ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
+    if (NT_SUCCESS(Status))
+        ObDereferenceObject(SectionObject);
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = MmCreateSection(&SectionObject,
+                             SECTION_ALL_ACCESS,
+                             &ObjectAttributes,
+                             NULL,
+                             PAGE_READWRITE,
+                             SEC_RESERVE | 0x80000000,
+                             NULL,
+                             NULL);
+    ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
+    if (NT_SUCCESS(Status))
+        ObDereferenceObject(SectionObject);
+
+    ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
+    ExFreePoolWithTag(MyPage, 'MPmK');
+}
+
 START_TEST(MmSection)
 {
     NTSTATUS Status;
@@ -428,7 +649,7 @@ START_TEST(MmSection)
 
     if (!skip(Status == STATUS_SUCCESS && FileHandle1 != NULL, "Failed to open file 1\n"))
     {
-        Status = ObReferenceObjectByHandle(FileHandle1, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID *)&FileObject1, NULL);
+        Status = ObReferenceObjectByHandle(FileHandle1, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject1, NULL);
         ok_eq_hex(Status, STATUS_SUCCESS);
         ok(FileObject1 != NULL, "FileObject1 is NULL\n");
         CheckObject(FileHandle1, 3L, 1L);
@@ -436,7 +657,7 @@ START_TEST(MmSection)
 
     if (!skip(Status == STATUS_SUCCESS && FileHandle2 != NULL, "Failed to open file 2\n"))
     {
-        Status = ObReferenceObjectByHandle(FileHandle2, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID *)&FileObject2, NULL);
+        Status = ObReferenceObjectByHandle(FileHandle2, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject2, NULL);
         ok_eq_hex(Status, STATUS_SUCCESS);
         ok(FileObject2 != NULL, "FileObject2 is NULL\n");
     }
@@ -453,4 +674,6 @@ START_TEST(MmSection)
         ZwClose(FileHandle2);
     if (FileHandle1)
         ZwClose(FileHandle1);
+
+    TestPhysicalMemorySection();
 }