mirror of
https://github.com/reactos/reactos.git
synced 2024-08-21 19:03:01 +00:00
244 lines
11 KiB
C
244 lines
11 KiB
C
/*
|
|
* PROJECT: ReactOS kernel-mode tests
|
|
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
|
* PURPOSE: Kernel-Mode Test Suite MDL test
|
|
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
|
*/
|
|
|
|
#include <kmt_test.h>
|
|
|
|
static
|
|
VOID
|
|
TestMmAllocatePagesForMdl(VOID)
|
|
{
|
|
PMDL Mdl;
|
|
PHYSICAL_ADDRESS LowAddress;
|
|
PHYSICAL_ADDRESS HighAddress;
|
|
PHYSICAL_ADDRESS SkipBytes;
|
|
PVOID SystemVa;
|
|
PMDL Mdls[32];
|
|
PVOID SystemVas[32];
|
|
ULONG i;
|
|
PPFN_NUMBER MdlPages;
|
|
ULONG MdlPageCount;
|
|
|
|
LowAddress.QuadPart = 0;
|
|
HighAddress.QuadPart = -1;
|
|
SkipBytes.QuadPart = 0;
|
|
/* simple allocate/free */
|
|
Mdl = MmAllocatePagesForMdl(LowAddress,
|
|
HighAddress,
|
|
SkipBytes,
|
|
2 * 1024 * 1024);
|
|
ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
|
|
if (skip(Mdl != NULL, "No Mdl\n"))
|
|
return;
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MdlPages = MmGetMdlPfnArray(Mdl);
|
|
MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
|
|
ok(MdlPageCount == 2 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
|
|
for (i = 0; i < MdlPageCount; i++)
|
|
{
|
|
ok(MdlPages[i] != 0 && MdlPages[i] != (PFN_NUMBER)-1,
|
|
"MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
|
|
}
|
|
MmFreePagesFromMdl(Mdl);
|
|
ExFreePoolWithTag(Mdl, 0);
|
|
|
|
/* Now map/unmap it */
|
|
Mdl = MmAllocatePagesForMdl(LowAddress,
|
|
HighAddress,
|
|
SkipBytes,
|
|
2 * 1024 * 1024);
|
|
ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
|
|
if (skip(Mdl != NULL, "No Mdl\n"))
|
|
return;
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
|
|
KernelMode,
|
|
MmCached,
|
|
NULL,
|
|
FALSE,
|
|
NormalPagePriority);
|
|
ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
|
|
if (!skip(SystemVa != NULL, "No system VA\n"))
|
|
{
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
|
|
ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
|
|
ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MmUnmapLockedPages(SystemVa, Mdl);
|
|
}
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MmFreePagesFromMdl(Mdl);
|
|
ExFreePoolWithTag(Mdl, 0);
|
|
|
|
/* Now map it, and free without unmapping */
|
|
Mdl = MmAllocatePagesForMdl(LowAddress,
|
|
HighAddress,
|
|
SkipBytes,
|
|
2 * 1024 * 1024);
|
|
ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
|
|
if (skip(Mdl != NULL, "No Mdl\n"))
|
|
return;
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
|
|
KernelMode,
|
|
MmCached,
|
|
NULL,
|
|
FALSE,
|
|
NormalPagePriority);
|
|
ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
|
|
ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
|
|
ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
|
|
ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MmFreePagesFromMdl(Mdl);
|
|
ExFreePoolWithTag(Mdl, 0);
|
|
|
|
/* try to allocate 2 GB -- should succeed but not map */
|
|
Mdl = MmAllocatePagesForMdl(LowAddress,
|
|
HighAddress,
|
|
SkipBytes,
|
|
2UL * 1024 * 1024 * 1024);
|
|
ok(Mdl != NULL, "MmAllocatePagesForMdl failed for 2 GB\n");
|
|
if (Mdl != NULL)
|
|
{
|
|
ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MdlPages = MmGetMdlPfnArray(Mdl);
|
|
MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
|
|
ok(MdlPageCount < 2UL * 1024 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
|
|
for (i = 0; i < MdlPageCount; i++)
|
|
{
|
|
if (MdlPages[i] == 0 ||
|
|
MdlPages[i] == (PFN_NUMBER)-1)
|
|
{
|
|
ok(0, "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
|
|
}
|
|
}
|
|
SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
|
|
KernelMode,
|
|
MmCached,
|
|
NULL,
|
|
FALSE,
|
|
NormalPagePriority);
|
|
ok(SystemVa == NULL, "MmMapLockedPagesSpecifyCache succeeded for 2 GB\n");
|
|
if (SystemVa != NULL)
|
|
MmUnmapLockedPages(SystemVa, Mdl);
|
|
ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
|
|
ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
|
|
ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
|
|
MmFreePagesFromMdl(Mdl);
|
|
ExFreePoolWithTag(Mdl, 0);
|
|
}
|
|
|
|
/* now allocate and map 32 MB Mdls until we fail */
|
|
for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
|
|
{
|
|
Mdls[i] = MmAllocatePagesForMdl(LowAddress,
|
|
HighAddress,
|
|
SkipBytes,
|
|
32 * 1024 * 1024);
|
|
if (Mdls[i] == NULL)
|
|
{
|
|
trace("MmAllocatePagesForMdl failed with i = %lu\n", i);
|
|
break;
|
|
}
|
|
ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
|
|
ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
|
|
SystemVas[i] = MmMapLockedPagesSpecifyCache(Mdls[i],
|
|
KernelMode,
|
|
MmCached,
|
|
NULL,
|
|
FALSE,
|
|
NormalPagePriority);
|
|
if (SystemVas[i] == NULL)
|
|
{
|
|
ok(MmGetMdlByteCount(Mdls[i]) <= 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
|
|
ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
|
|
ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
|
|
trace("MmMapLockedPagesSpecifyCache failed with i = %lu\n", i);
|
|
break;
|
|
}
|
|
ok(MmGetMdlByteCount(Mdls[i]) == 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
|
|
ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdls[i]), SystemVas[i]);
|
|
ok(Mdls[i]->MappedSystemVa == SystemVas[i], "MappedSystemVa: %p\n", Mdls[i]->MappedSystemVa, SystemVas[i]);
|
|
ok((Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
|
|
}
|
|
for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
|
|
{
|
|
if (Mdls[i] == NULL)
|
|
break;
|
|
if (SystemVas[i] != NULL)
|
|
MmUnmapLockedPages(SystemVas[i], Mdls[i]);
|
|
MmFreePagesFromMdl(Mdls[i]);
|
|
ExFreePoolWithTag(Mdls[i], 0);
|
|
if (SystemVas[i] == NULL)
|
|
break;
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
TestMmBuildMdlForNonPagedPool(VOID)
|
|
{
|
|
PVOID Page;
|
|
PMDL Mdl;
|
|
|
|
Page = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'Test');
|
|
ok(Page != NULL, "ExAllocatePoolWithTag failed\n");
|
|
if (skip(Page != NULL, "No buffer\n"))
|
|
return;
|
|
|
|
Mdl = IoAllocateMdl(Page, PAGE_SIZE, FALSE, FALSE, NULL);
|
|
ok(Mdl != NULL, "IoAllocateMdl failed\n");
|
|
if (skip(Mdl != NULL, "No MDL\n"))
|
|
return;
|
|
|
|
ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
|
|
ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
|
|
|
|
MmBuildMdlForNonPagedPool(Mdl);
|
|
ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
|
|
ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) != 0, "MDL from paged\n");
|
|
|
|
IoFreeMdl(Mdl);
|
|
ExFreePoolWithTag(Page, 'Test');
|
|
|
|
Page = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'Test');
|
|
ok(Page != NULL, "ExAllocatePoolWithTag failed\n");
|
|
if (skip(Page != NULL, "No buffer\n"))
|
|
return;
|
|
|
|
Mdl = IoAllocateMdl(Page, PAGE_SIZE, FALSE, FALSE, NULL);
|
|
ok(Mdl != NULL, "IoAllocateMdl failed\n");
|
|
if (skip(Mdl != NULL, "No MDL\n"))
|
|
return;
|
|
|
|
ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
|
|
ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
|
|
|
|
MmBuildMdlForNonPagedPool(Mdl);
|
|
ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
|
|
ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) != 0, "MDL from paged\n");
|
|
|
|
IoFreeMdl(Mdl);
|
|
ExFreePoolWithTag(Page, 'Test');
|
|
}
|
|
|
|
START_TEST(MmMdl)
|
|
{
|
|
TestMmAllocatePagesForMdl();
|
|
TestMmBuildMdlForNonPagedPool();
|
|
}
|