[KMTESTS:CC] Add a test that shows that our CC implementation duplicates BCB
authorPierre Schweitzer <pierre@reactos.org>
Fri, 31 Aug 2018 21:01:06 +0000 (23:01 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Fri, 31 Aug 2018 21:01:06 +0000 (23:01 +0200)
It should instead reuse BCBs when mapping something already mapped.

modules/rostests/kmtests/ntos_cc/CcMapData_drv.c
modules/rostests/kmtests/ntos_cc/CcMapData_user.c

index b4e632e..7cf442e 100644 (file)
@@ -20,6 +20,13 @@ typedef struct _TEST_FCB
     FAST_MUTEX HeaderMutex;
 } TEST_FCB, *PTEST_FCB;
 
+typedef struct _TEST_CONTEXT
+{
+    PVOID Bcb;
+    PVOID Buffer;
+} TEST_CONTEXT, *PTEST_CONTEXT;
+
+static BOOLEAN TestMap = FALSE;
 static ULONG TestTestId = -1;
 static PFILE_OBJECT TestFileObject;
 static PDEVICE_OBJECT TestDeviceObject;
@@ -137,6 +144,44 @@ MapAndLockUserBuffer(
     return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
 }
 
+static
+VOID
+NTAPI
+MapInAnotherThread(IN PVOID Context)
+{
+    BOOLEAN Ret;
+    PULONG Buffer;
+    PVOID Bcb;
+    LARGE_INTEGER Offset;
+    PTEST_CONTEXT TestContext;
+
+    ok(TestFileObject != NULL, "Called in invalid context!\n");
+    ok_eq_ulong(TestTestId, 3);
+
+    TestContext = Context;
+    ok(TestContext != NULL, "Called in invalid context!\n");
+    ok(TestContext->Bcb != NULL, "Called in invalid context!\n");
+    ok(TestContext->Buffer != NULL, "Called in invalid context!\n");
+
+    Ret = FALSE;
+    Offset.QuadPart = 0x1000;
+    KmtStartSeh();
+    TestMap = TRUE;
+    Ret = CcMapData(TestFileObject, &Offset, FileSizes.FileSize.QuadPart - Offset.QuadPart, MAP_WAIT, &Bcb, (PVOID *)&Buffer);
+    TestMap = FALSE;
+    KmtEndSeh(STATUS_SUCCESS);
+
+    if (!skip(Ret == TRUE, "CcMapData failed\n"))
+    {
+        ok_eq_pointer(Bcb, TestContext->Bcb);
+        ok_eq_pointer(Buffer, TestContext->Buffer);
+
+        CcUnpinData(Bcb);
+    }
+
+    return;
+}
+
 static
 VOID
 PerformTest(
@@ -174,17 +219,50 @@ PerformTest(
 
             if (!skip(CcIsFileCached(TestFileObject) == TRUE, "CcInitializeCacheMap failed\n"))
             {
-                Ret = FALSE;
-                Offset.QuadPart = TestId * 0x1000;
-                KmtStartSeh();
-                Ret = CcMapData(TestFileObject, &Offset, FileSizes.FileSize.QuadPart - Offset.QuadPart, MAP_WAIT, &Bcb, (PVOID *)&Buffer);
-                KmtEndSeh(STATUS_SUCCESS);
-
-                if (!skip(Ret == TRUE, "CcMapData failed\n"))
+                if (TestId < 3)
                 {
-                    ok_eq_ulong(Buffer[(0x3000 - TestId * 0x1000) / sizeof(ULONG)], 0xDEADBABE);
-
-                    CcUnpinData(Bcb);
+                    Ret = FALSE;
+                    Offset.QuadPart = TestId * 0x1000;
+                    KmtStartSeh();
+                    Ret = CcMapData(TestFileObject, &Offset, FileSizes.FileSize.QuadPart - Offset.QuadPart, MAP_WAIT, &Bcb, (PVOID *)&Buffer);
+                    KmtEndSeh(STATUS_SUCCESS);
+
+                    if (!skip(Ret == TRUE, "CcMapData failed\n"))
+                    {
+                        ok_eq_ulong(Buffer[(0x3000 - TestId * 0x1000) / sizeof(ULONG)], 0xDEADBABE);
+
+                        CcUnpinData(Bcb);
+                    }
+                }
+                else if (TestId == 3)
+                {
+                    PTEST_CONTEXT TestContext;
+
+                    TestContext = ExAllocatePool(NonPagedPool, sizeof(TEST_CONTEXT));
+                    if (!skip(Fcb != NULL, "ExAllocatePool failed\n"))
+                    {
+                        Ret = FALSE;
+                        Offset.QuadPart = 0x1000;
+                        KmtStartSeh();
+                        TestMap = TRUE;
+                        Ret = CcMapData(TestFileObject, &Offset, FileSizes.FileSize.QuadPart - Offset.QuadPart, MAP_WAIT, &TestContext->Bcb, &TestContext->Buffer);
+                        TestMap = FALSE;
+                        KmtEndSeh(STATUS_SUCCESS);
+
+                        if (!skip(Ret == TRUE, "CcMapData failed\n"))
+                        {
+                            PKTHREAD ThreadHandle;
+
+                            ThreadHandle = KmtStartThread(MapInAnotherThread, TestContext);
+                            KmtFinishThread(ThreadHandle, NULL);
+
+                            TestTestId = -1;
+                            CcUnpinData(TestContext->Bcb);
+                            TestTestId = 3;
+                        }
+
+                        ExFreePool(TestContext);
+                    }
                 }
             }
         }
index 31847c0..b1d2685 100644 (file)
@@ -18,7 +18,10 @@ START_TEST(CcMapData)
     KmtLoadDriver(L"CcMapData", FALSE);
     KmtOpenDriver();
 
-    for (TestId = 0; TestId < 3; ++TestId)
+    /* 3 tests for offset
+     * 1 test for BCB
+     */
+    for (TestId = 0; TestId < 4; ++TestId)
     {
         Ret = KmtSendUlongToDriver(IOCTL_START_TEST, TestId);
         ok(Ret == ERROR_SUCCESS, "KmtSendUlongToDriver failed: %lx\n", Ret);