mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[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:
parent
1611dc4086
commit
8679f001d9
6 changed files with 388 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
29
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h
Normal file
29
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h
Normal 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_ */
|
261
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c
Normal file
261
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c
Normal 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;
|
||||
}
|
60
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c
Normal file
60
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c
Normal 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();
|
||||
}
|
Loading…
Reference in a new issue