Author: tfaber Date: Sun Jun 18 08:00:29 2017 New Revision: 75084
URL: http://svn.reactos.org/svn/reactos?rev=75084&view=rev Log: [KMTESTS:MM] - Test unaligned address and addresses close to MmHighestUserAddress in MmMapLockedPagesSpecifyCache test CORE-13444
Modified: trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c
Modified: trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_mm/MmMapLocke... ============================================================================== --- trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h [iso-8859-1] Sun Jun 18 08:00:29 2017 @@ -14,6 +14,7 @@ USHORT Length; PVOID Buffer; BOOLEAN Cached; + NTSTATUS Status; } QUERY_BUFFER, *PQUERY_BUFFER;
typedef struct _READ_BUFFER @@ -25,6 +26,7 @@
#define IOCTL_QUERY_BUFFER 1 #define IOCTL_READ_BUFFER 2 +#define IOCTL_CLEAN 3
#define WRITE_PATTERN 0xA4A5A6A7
Modified: trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_mm/MmMapLocke... ============================================================================== --- trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c [iso-8859-1] Sun Jun 18 08:00:29 2017 @@ -121,7 +121,7 @@
TestCleanEverything();
- ok(ExGetPreviousMode() == UserMode, "Not comming from umode!\n"); + ok(ExGetPreviousMode() == UserMode, "Not coming from umode!\n"); if (!skip(Buffer && InLength >= sizeof(QUERY_BUFFER) && *OutLength >= sizeof(QUERY_BUFFER), "Cannot read/write from/to buffer!\n")) { PQUERY_BUFFER QueryBuffer; @@ -178,15 +178,26 @@ SehStatus = STATUS_SUCCESS; _SEH2_TRY { - CurrentUser = MmMapLockedPagesSpecifyCache(CurrentMdl, UserMode, CacheType, NULL, FALSE, NormalPagePriority); + CurrentUser = MmMapLockedPagesSpecifyCache(CurrentMdl, UserMode, CacheType, QueryBuffer->Buffer, FALSE, NormalPagePriority); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SehStatus = _SEH2_GetExceptionCode(); } _SEH2_END; - ok_eq_hex(SehStatus, STATUS_SUCCESS); - ok(CurrentUser != NULL, "MmMapLockedPagesSpecifyCache failed!\n"); + if (QueryBuffer->Status != -1) + { + ok_eq_hex(SehStatus, QueryBuffer->Status); + if (NT_SUCCESS(QueryBuffer->Status)) + { + ok(CurrentUser != NULL, "MmMapLockedPagesSpecifyCache failed!\n"); + } + else + { + ok(CurrentUser == NULL, "MmMapLockedPagesSpecifyCache succeeded!\n"); + } + } + QueryBuffer->Status = SehStatus; } else { @@ -208,7 +219,7 @@ 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")) + if (!skip(Buffer && InLength >= sizeof(READ_BUFFER), "Cannot read from buffer!\n")) { PREAD_BUFFER ReadBuffer;
@@ -237,6 +248,11 @@
break; } + case IOCTL_CLEAN: + { + 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);
Modified: trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_mm/MmMapLocke... ============================================================================== --- trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c [iso-8859-1] Sun Jun 18 08:00:29 2017 @@ -6,8 +6,12 @@ */
#include <kmt_test.h> +#include <ndk/exfuncs.h>
#include "MmMapLockedPagesSpecifyCache.h" + +#define ALIGN_DOWN_BY(size, align) \ + ((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1))
#define SET_BUFFER_LENGTH(Var, Length) \ { \ @@ -20,6 +24,7 @@ QueryBuffer.Length = BufferLength; \ QueryBuffer.Buffer = NULL; \ QueryBuffer.Cached = UseCache; \ + QueryBuffer.Status = STATUS_SUCCESS; \ }
#define FILL_READ_BUFFER(QueryBuffer, ReadBuffer) \ @@ -78,6 +83,9 @@ DWORD Length; USHORT i; USHORT BufferLength; + SYSTEM_BASIC_INFORMATION BasicInfo; + NTSTATUS Status; + ULONG_PTR HighestAddress;
KmtLoadDriver(L"MmMapLockedPagesSpecifyCache", FALSE); KmtOpenDriver(); @@ -180,31 +188,92 @@
// more than 2 pages SET_BUFFER_LENGTH(BufferLength, 2 * 4096 + 2048); - QueryBuffer.Length = BufferLength; - 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, BufferLength); - ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n"); - CHECK_ALLOC(QueryBuffer.Buffer, BufferLength); - - Length = 0; - FILL_READ_BUFFER(QueryBuffer, ReadBuffer); - ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n"); - - QueryBuffer.Length = BufferLength; - 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, BufferLength); - ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n"); - CHECK_ALLOC(QueryBuffer.Buffer, BufferLength); - - Length = 0; - FILL_READ_BUFFER(QueryBuffer, ReadBuffer); - ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE); + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n"); + CHECK_ALLOC(QueryBuffer.Buffer, BufferLength); + + Length = 0; + FILL_READ_BUFFER(QueryBuffer, ReadBuffer); + ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE); + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n"); + CHECK_ALLOC(QueryBuffer.Buffer, BufferLength); + + Length = 0; + FILL_READ_BUFFER(QueryBuffer, ReadBuffer); + ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + + // ask for a specific address (we know that ReadBuffer.Buffer is free) + SET_BUFFER_LENGTH(BufferLength, 4096); + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE); + QueryBuffer.Buffer = ReadBuffer.Buffer; + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Buffer == ReadBuffer.Buffer, "Buffer is NULL\n"); + CHECK_ALLOC(QueryBuffer.Buffer, BufferLength); + + Length = 0; + FILL_READ_BUFFER(QueryBuffer, ReadBuffer); + ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + + // ask for an unaligned address + SET_BUFFER_LENGTH(BufferLength, 4096); + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE); + QueryBuffer.Buffer = (PVOID)((ULONG_PTR)ReadBuffer.Buffer + 2048); + QueryBuffer.Status = STATUS_INVALID_ADDRESS; + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer); + + Length = 0; + ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n"); + + // get system info for MmHighestUserAddress + Status = NtQuerySystemInformation(SystemBasicInformation, + &BasicInfo, + sizeof(BasicInfo), + NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + trace("MaximumUserModeAddress: %lx\n", BasicInfo.MaximumUserModeAddress); + HighestAddress = ALIGN_DOWN_BY(BasicInfo.MaximumUserModeAddress, PAGE_SIZE); + + // near MmHighestUserAddress + SET_BUFFER_LENGTH(BufferLength, 4096); + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE); + QueryBuffer.Buffer = (PVOID)(HighestAddress - 15 * PAGE_SIZE); // 7ffe0000 + QueryBuffer.Status = STATUS_INVALID_ADDRESS; + trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer); + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer); + + Length = 0; + ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n"); + + // far enough away from MmHighestUserAddress + SET_BUFFER_LENGTH(BufferLength, 4096); + FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE); + QueryBuffer.Buffer = (PVOID)(HighestAddress - 16 * PAGE_SIZE); // 7ffdf000 + QueryBuffer.Status = -1; + trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer); + Length = sizeof(QUERY_BUFFER); + ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n"); + ok_eq_int(QueryBuffer.Length, BufferLength); + ok(QueryBuffer.Status == STATUS_SUCCESS || + QueryBuffer.Status == STATUS_CONFLICTING_ADDRESSES, "Status = %lx\n", QueryBuffer.Status); + + Length = 0; + ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n");
KmtCloseDriver(); KmtUnloadDriver();