[KMTESTS:MM]

Add tests for MmMapLockedPagesSpecifyCache() functions, and more specifically for usermode mapping.
This was designed/tested under W2K3.

CORE-8204

svn path=/trunk/; revision=74751
This commit is contained in:
Pierre Schweitzer 2017-06-02 19:19:32 +00:00
parent 1611dc4086
commit 8679f001d9
6 changed files with 388 additions and 19 deletions

View file

@ -128,6 +128,7 @@ list(APPEND KMTEST_SOURCE
ntos_io/IoCreateFile_user.c
ntos_io/IoDeviceObject_user.c
ntos_io/IoReadWrite_user.c
ntos_mm/MmMapLockedPagesSpecifyCache_user.c
ntos_mm/NtCreateSection_user.c
ntos_po/PoIrp_user.c
tcpip/TcpIp_user.c
@ -157,6 +158,7 @@ add_dependencies(kmtest_drivers
iodeviceobject_drv
iohelper_drv
ioreadwrite_drv
mmmaplockedpagesspecifycache_drv
ntcreatesection_drv
poirp_drv
tcpip_drv

View file

@ -13,6 +13,7 @@ KMT_TESTFUNC Test_FindFile;
KMT_TESTFUNC Test_IoCreateFile;
KMT_TESTFUNC Test_IoDeviceObject;
KMT_TESTFUNC Test_IoReadWrite;
KMT_TESTFUNC Test_MmMapLockedPagesSpecifyCache;
KMT_TESTFUNC Test_NtCreateSection;
KMT_TESTFUNC Test_PoIrp;
KMT_TESTFUNC Test_RtlAvlTree;
@ -30,23 +31,24 @@ KMT_TESTFUNC Test_TcpIpConnect;
/* tests with a leading '-' will not be listed */
const KMT_TEST TestList[] =
{
{ "CcCopyRead", Test_CcCopyRead },
{ "-Example", Test_Example },
{ "FindFile", Test_FindFile },
{ "IoCreateFile", Test_IoCreateFile },
{ "IoDeviceObject", Test_IoDeviceObject },
{ "IoReadWrite", Test_IoReadWrite },
{ "NtCreateSection", Test_NtCreateSection },
{ "PoIrp", Test_PoIrp },
{ "RtlAvlTree", Test_RtlAvlTree },
{ "RtlException", Test_RtlException },
{ "RtlIntSafe", Test_RtlIntSafe },
{ "RtlMemory", Test_RtlMemory },
{ "RtlRegistry", Test_RtlRegistry },
{ "RtlSplayTree", Test_RtlSplayTree },
{ "RtlStack", Test_RtlStack },
{ "RtlUnicodeString", Test_RtlUnicodeString },
{ "TcpIpTdi", Test_TcpIpTdi },
{ "TcpIpConnect", Test_TcpIpConnect },
{ NULL, NULL },
{ "CcCopyRead", Test_CcCopyRead },
{ "-Example", Test_Example },
{ "FindFile", Test_FindFile },
{ "IoCreateFile", Test_IoCreateFile },
{ "IoDeviceObject", Test_IoDeviceObject },
{ "IoReadWrite", Test_IoReadWrite },
{ "MmMapLockedPagesSpecifyCache", Test_MmMapLockedPagesSpecifyCache },
{ "NtCreateSection", Test_NtCreateSection },
{ "PoIrp", Test_PoIrp },
{ "RtlAvlTree", Test_RtlAvlTree },
{ "RtlException", Test_RtlException },
{ "RtlIntSafe", Test_RtlIntSafe },
{ "RtlMemory", Test_RtlMemory },
{ "RtlRegistry", Test_RtlRegistry },
{ "RtlSplayTree", Test_RtlSplayTree },
{ "RtlStack", Test_RtlStack },
{ "RtlUnicodeString", Test_RtlUnicodeString },
{ "TcpIpTdi", Test_TcpIpTdi },
{ "TcpIpConnect", Test_TcpIpConnect },
{ NULL, NULL },
};

View file

@ -15,3 +15,18 @@ add_importlibs(ntcreatesection_drv ntoskrnl hal)
add_target_compile_definitions(ntcreatesection_drv KMT_STANDALONE_DRIVER)
#add_pch(ntcreatesection_drv ../include/kmt_test.h)
add_rostests_file(TARGET ntcreatesection_drv)
#
# MmMapLockedPagesSpecifyCache
#
list(APPEND MMMAPLOCKEDPAGESSPECIFYCACHE_DRV_SOURCE
../kmtest_drv/kmtest_standalone.c
MmMapLockedPagesSpecifyCache_drv.c)
add_library(mmmaplockedpagesspecifycache_drv SHARED ${MMMAPLOCKEDPAGESSPECIFYCACHE_DRV_SOURCE})
set_module_type(mmmaplockedpagesspecifycache_drv kernelmodedriver)
target_link_libraries(mmmaplockedpagesspecifycache_drv kmtest_printf ${PSEH_LIB})
add_importlibs(mmmaplockedpagesspecifycache_drv ntoskrnl hal)
add_target_compile_definitions(mmmaplockedpagesspecifycache_drv KMT_STANDALONE_DRIVER)
#add_pch(mmmaplockedpagesspecifycache_drv ../include/kmt_test.h)
add_rostests_file(TARGET mmmaplockedpagesspecifycache_drv)

View file

@ -0,0 +1,29 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Kernel-Mode Test Suite MmMapLockedPagesSpecifyCache test declarations
* PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
*/
#ifndef _KMTEST_MMMAPLOCKEDPAGESSPECIFYCACHE_H_
#define _KMTEST_MMMAPLOCKEDPAGESSPECIFYCACHE_H_
typedef struct _QUERY_BUFFER
{
USHORT Length;
PVOID Buffer;
BOOLEAN Cached;
} QUERY_BUFFER, *PQUERY_BUFFER;
typedef struct _READ_BUFFER
{
USHORT Length;
PVOID Buffer;
USHORT Pattern;
} READ_BUFFER, *PREAD_BUFFER;
#define IOCTL_QUERY_BUFFER 1
#define IOCTL_READ_BUFFER 2
#endif /* !defined _KMTEST_MMMAPLOCKEDPAGESSPECIFYCACHE_H_ */

View file

@ -0,0 +1,261 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Test driver for MmMapLockedPagesSpecifyCache function
* PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
*/
#include <kmt_test.h>
#define NDEBUG
#include <debug.h>
#include "MmMapLockedPagesSpecifyCache.h"
static KMT_IRP_HANDLER TestIrpHandler;
static KMT_MESSAGE_HANDLER TestMessageHandler;
static PVOID CurrentBuffer;
static PMDL CurrentMdl;
static PVOID CurrentUser;
NTSTATUS
TestEntry(
IN PDRIVER_OBJECT DriverObject,
IN PCUNICODE_STRING RegistryPath,
OUT PCWSTR *DeviceName,
IN OUT INT *Flags)
{
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
UNREFERENCED_PARAMETER(Flags);
*DeviceName = L"MmMapLockedPagesSpecifyCache";
KmtRegisterIrpHandler(IRP_MJ_CLEANUP, NULL, TestIrpHandler);
KmtRegisterMessageHandler(0, NULL, TestMessageHandler);
return Status;
}
VOID
TestUnload(
IN PDRIVER_OBJECT DriverObject)
{
PAGED_CODE();
}
VOID
TestCleanEverything(VOID)
{
NTSTATUS SehStatus;
if (CurrentMdl == NULL)
{
return;
}
if (CurrentUser != NULL)
{
SehStatus = STATUS_SUCCESS;
_SEH2_TRY
{
MmUnmapLockedPages(CurrentUser, CurrentMdl);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SehStatus = _SEH2_GetExceptionCode();
}
_SEH2_END;
ok_eq_hex(SehStatus, STATUS_SUCCESS);
CurrentUser = NULL;
}
SehStatus = STATUS_SUCCESS;
_SEH2_TRY
{
MmUnlockPages(CurrentMdl);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SehStatus = _SEH2_GetExceptionCode();
}
_SEH2_END;
ok_eq_hex(SehStatus, STATUS_SUCCESS);
IoFreeMdl(CurrentMdl);
ExFreePoolWithTag(CurrentBuffer, 'MLPC');
CurrentMdl = NULL;
}
static
NTSTATUS
TestMessageHandler(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG ControlCode,
IN PVOID Buffer OPTIONAL,
IN SIZE_T InLength,
IN OUT PSIZE_T OutLength)
{
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS SehStatus;
switch (ControlCode)
{
case IOCTL_QUERY_BUFFER:
{
ok(Buffer != NULL, "Buffer is NULL\n");
ok_eq_size(InLength, sizeof(QUERY_BUFFER));
ok_eq_size(*OutLength, sizeof(QUERY_BUFFER));
ok_eq_pointer(CurrentMdl, NULL);
ok(ExGetPreviousMode() == UserMode, "Not comming from umode!\n");
if (!skip(Buffer && InLength >= sizeof(QUERY_BUFFER) && *OutLength >= sizeof(QUERY_BUFFER), "Cannot read/write from/to buffer!\n"))
{
PQUERY_BUFFER QueryBuffer;
USHORT Length;
MEMORY_CACHING_TYPE CacheType;
QueryBuffer = Buffer;
CacheType = (QueryBuffer->Cached ? MmCached : MmNonCached);
Length = QueryBuffer->Length;
ok(Length > 0, "Null size!\n");
CurrentBuffer = ExAllocatePoolWithTag(NonPagedPool, Length + 0x8, 'MLPC');
ok(CurrentBuffer != NULL, "ExAllocatePool failed!\n");
CurrentUser = NULL;
if (!skip(CurrentBuffer != NULL, "ExAllocatePool failed!\n"))
{
CurrentMdl = IoAllocateMdl(CurrentBuffer, Length, FALSE, FALSE, NULL);
ok(CurrentMdl != NULL, "IoAllocateMdl failed!\n");
if (CurrentMdl)
{
KIRQL Irql;
SehStatus = STATUS_SUCCESS;
_SEH2_TRY
{
MmProbeAndLockPages(CurrentMdl, KernelMode, IoWriteAccess);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SehStatus = _SEH2_GetExceptionCode();
}
_SEH2_END;
ok_eq_hex(SehStatus, STATUS_SUCCESS);
Irql = KeGetCurrentIrql();
ok(Irql <= APC_LEVEL, "IRQL > APC_LEVEL: %d\n", Irql);
SehStatus = STATUS_SUCCESS;
_SEH2_TRY
{
CurrentUser = MmMapLockedPagesSpecifyCache(CurrentMdl, UserMode, CacheType, NULL, FALSE, NormalPagePriority);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SehStatus = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (QueryBuffer->Cached)
{
ok_eq_hex(SehStatus, STATUS_SUCCESS);
ok(CurrentUser != NULL, "MmMapLockedPagesSpecifyCache failed!\n");
}
else
{
ok_eq_hex(SehStatus, STATUS_INVALID_ADDRESS);
ok_eq_pointer(CurrentUser, NULL);
}
}
}
QueryBuffer->Buffer = CurrentUser;
*OutLength = sizeof(QUERY_BUFFER);
}
break;
}
case IOCTL_READ_BUFFER:
{
ok(Buffer != NULL, "Buffer is NULL\n");
ok_eq_size(InLength, sizeof(READ_BUFFER));
ok_eq_size(*OutLength, 0);
ok(CurrentMdl != NULL, "MDL is not in use!\n");
if (!skip(Buffer && InLength >= sizeof(QUERY_BUFFER), "Cannot read from buffer!\n"))
{
PREAD_BUFFER ReadBuffer;
ReadBuffer = Buffer;
if (!skip(ReadBuffer && ReadBuffer->Buffer == CurrentUser, "Cannot find matching MDL\n"))
{
if (ReadBuffer->Buffer != NULL)
{
USHORT i;
PUSHORT KBuffer = MmGetSystemAddressForMdlSafe(CurrentMdl, NormalPagePriority);
ok(KBuffer != NULL, "Failed to get kmode ptr\n");
if (!skip(Buffer != NULL, "Failed to get kmode ptr\n"))
{
for (i = 0; i < ReadBuffer->Length / sizeof(USHORT); ++i)
{
ok_eq_ulong((ULONG)KBuffer[i], (ULONG)ReadBuffer->Pattern);
}
}
}
}
TestCleanEverything();
}
break;
}
default:
ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n",
DeviceObject, ControlCode, Buffer, InLength, *OutLength);
break;
}
return Status;
}
static
NTSTATUS
TestIrpHandler(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
_In_ PIO_STACK_LOCATION IoStack)
{
NTSTATUS Status;
PAGED_CODE();
DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP);
Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
{
TestCleanEverything();
Status = STATUS_SUCCESS;
}
if (Status == STATUS_PENDING)
{
IoMarkIrpPending(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
Status = STATUS_PENDING;
}
else
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return Status;
}

View file

@ -0,0 +1,60 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Kernel-Mode Test Suite MmMapLockedPagesSpecifyCache test user-mode part
* PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
*/
#include <kmt_test.h>
#include "MmMapLockedPagesSpecifyCache.h"
START_TEST(MmMapLockedPagesSpecifyCache)
{
QUERY_BUFFER QueryBuffer;
READ_BUFFER ReadBuffer;
DWORD Length;
USHORT i;
PUSHORT Buffer;
KmtLoadDriver(L"MmMapLockedPagesSpecifyCache", FALSE);
KmtOpenDriver();
QueryBuffer.Length = 0x100;
QueryBuffer.Buffer = NULL;
QueryBuffer.Cached = FALSE;
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, 0x100);
ok_eq_pointer(QueryBuffer.Buffer, NULL);
ReadBuffer.Buffer = QueryBuffer.Buffer;
Length = 0;
ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
QueryBuffer.Length = 0x100;
QueryBuffer.Buffer = NULL;
QueryBuffer.Cached = TRUE;
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, 0x100);
ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
ReadBuffer.Buffer = QueryBuffer.Buffer;
if (!skip(QueryBuffer.Buffer != NULL, "Buffer is NULL\n"))
{
ReadBuffer.Pattern = 0xA7;
ReadBuffer.Length = QueryBuffer.Length;
Buffer = QueryBuffer.Buffer;
for (i = 0; i < ReadBuffer.Length / sizeof(USHORT); ++i)
{
Buffer[i] = ReadBuffer.Pattern;
}
}
Length = 0;
ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
KmtCloseDriver();
KmtUnloadDriver();
}