[KMTESTS:MM]
authorThomas Faber <thomas.faber@reactos.org>
Sun, 18 Jun 2017 08:00:29 +0000 (08:00 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 18 Jun 2017 08:00:29 +0000 (08:00 +0000)
- Test unaligned address and addresses close to MmHighestUserAddress in MmMapLockedPagesSpecifyCache test
CORE-13444

svn path=/trunk/; revision=75084

rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache.h
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_drv.c
rostests/kmtests/ntos_mm/MmMapLockedPagesSpecifyCache_user.c

index 6b4ecd6..fcc0abf 100644 (file)
@@ -14,6 +14,7 @@ typedef struct _QUERY_BUFFER
     USHORT Length;
     PVOID Buffer;
     BOOLEAN Cached;
+    NTSTATUS Status;
 } QUERY_BUFFER, *PQUERY_BUFFER;
 
 typedef struct _READ_BUFFER
@@ -25,6 +26,7 @@ typedef struct _READ_BUFFER
 
 #define IOCTL_QUERY_BUFFER 1
 #define IOCTL_READ_BUFFER  2
+#define IOCTL_CLEAN        3
 
 #define WRITE_PATTERN 0xA4A5A6A7
 
index 95d1eec..78f250b 100644 (file)
@@ -121,7 +121,7 @@ TestMessageHandler(
 
             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 @@ TestMessageHandler(
                             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 @@ TestMessageHandler(
             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 @@ TestMessageHandler(
 
             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);
index 01ab3b4..0fe781f 100644 (file)
@@ -6,9 +6,13 @@
  */
 
 #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)         \
 {                                              \
     C_ASSERT(((Length) % sizeof(ULONG)) == 0); \
@@ -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 @@ START_TEST(MmMapLockedPagesSpecifyCache)
     DWORD Length;
     USHORT i;
     USHORT BufferLength;
+    SYSTEM_BASIC_INFORMATION BasicInfo;
+    NTSTATUS Status;
+    ULONG_PTR HighestAddress;
 
     KmtLoadDriver(L"MmMapLockedPagesSpecifyCache", FALSE);
     KmtOpenDriver();
@@ -180,9 +188,7 @@ START_TEST(MmMapLockedPagesSpecifyCache)
 
     // more than 2 pages
     SET_BUFFER_LENGTH(BufferLength, 2 * 4096 + 2048);
-    QueryBuffer.Length = BufferLength;
-    QueryBuffer.Buffer = NULL;
-    QueryBuffer.Cached = FALSE;
+    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);
@@ -193,9 +199,7 @@ START_TEST(MmMapLockedPagesSpecifyCache)
     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;
+    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);
@@ -206,6 +210,71 @@ START_TEST(MmMapLockedPagesSpecifyCache)
     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();
 }