[KMTESTS:CC] Add a test that shows that our CC implementation duplicates BCB

It should instead reuse BCBs when mapping something already mapped.
This commit is contained in:
Pierre Schweitzer 2018-08-31 23:01:06 +02:00
parent f0eb39084e
commit ad0c93b001
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
2 changed files with 91 additions and 10 deletions

View file

@ -20,6 +20,13 @@ typedef struct _TEST_FCB
FAST_MUTEX HeaderMutex; FAST_MUTEX HeaderMutex;
} TEST_FCB, *PTEST_FCB; } 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 ULONG TestTestId = -1;
static PFILE_OBJECT TestFileObject; static PFILE_OBJECT TestFileObject;
static PDEVICE_OBJECT TestDeviceObject; static PDEVICE_OBJECT TestDeviceObject;
@ -137,6 +144,44 @@ MapAndLockUserBuffer(
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); 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 static
VOID VOID
PerformTest( PerformTest(
@ -174,17 +219,50 @@ PerformTest(
if (!skip(CcIsFileCached(TestFileObject) == TRUE, "CcInitializeCacheMap failed\n")) if (!skip(CcIsFileCached(TestFileObject) == TRUE, "CcInitializeCacheMap failed\n"))
{ {
Ret = FALSE; if (TestId < 3)
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); Ret = FALSE;
Offset.QuadPart = TestId * 0x1000;
KmtStartSeh();
Ret = CcMapData(TestFileObject, &Offset, FileSizes.FileSize.QuadPart - Offset.QuadPart, MAP_WAIT, &Bcb, (PVOID *)&Buffer);
KmtEndSeh(STATUS_SUCCESS);
CcUnpinData(Bcb); 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);
}
} }
} }
} }

View file

@ -18,7 +18,10 @@ START_TEST(CcMapData)
KmtLoadDriver(L"CcMapData", FALSE); KmtLoadDriver(L"CcMapData", FALSE);
KmtOpenDriver(); 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); Ret = KmtSendUlongToDriver(IOCTL_START_TEST, TestId);
ok(Ret == ERROR_SUCCESS, "KmtSendUlongToDriver failed: %lx\n", Ret); ok(Ret == ERROR_SUCCESS, "KmtSendUlongToDriver failed: %lx\n", Ret);