[KMTESTS:FSRTL]
[reactos.git] / rostests / kmtests / include / kmt_test.h
index d9ed2d8..5560891 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:         ReactOS kernel-mode tests
  * LICENSE:         GPLv2+ - See COPYING in the top level directory
  * PURPOSE:         Kernel-Mode Test Suite test framework declarations
- * PROGRAMMER:      Thomas Faber <thfabba@gmx.de>
+ * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
  */
 
 /* Inspired by Wine C unit tests, Copyright (C) 2002 Alexandre Julliard
@@ -38,6 +38,48 @@ typedef struct
     CHAR LogBuffer[ANYSIZE_ARRAY];
 } KMT_RESULTBUFFER, *PKMT_RESULTBUFFER;
 
+#ifndef KMT_STANDALONE_DRIVER
+
+/* usermode call-back mechanism */
+
+/* list of supported operations */
+typedef enum _KMT_CALLBACK_INFORMATION_CLASS
+{
+    QueryVirtualMemory
+} KMT_CALLBACK_INFORMATION_CLASS, *PKMT_CALLBACK_INFORMATION_CLASS;
+
+/* TODO: "response" is a little generic */
+typedef union _KMT_RESPONSE
+{
+    MEMORY_BASIC_INFORMATION MemInfo;
+} KMT_RESPONSE, *PKMT_RESPONSE;
+
+/* this struct is sent from driver to usermode */
+typedef struct _KMT_CALLBACK_REQUEST_PACKET
+{
+    ULONG RequestId;
+    KMT_CALLBACK_INFORMATION_CLASS OperationClass;
+    PVOID Parameters;
+} KMT_CALLBACK_REQUEST_PACKET, *PKMT_CALLBACK_REQUEST_PACKET;
+
+PKMT_RESPONSE KmtUserModeCallback(KMT_CALLBACK_INFORMATION_CLASS Operation, PVOID Parameters);
+VOID KmtFreeCallbackResponse(PKMT_RESPONSE Response);
+
+//macro to simplify using the mechanism
+#define Test_NtQueryVirtualMemory(BaseAddress, Size, AllocationType, ProtectionType)            \
+    do {                                                                                        \
+    PKMT_RESPONSE NtQueryTest = KmtUserModeCallback(QueryVirtualMemory, BaseAddress);           \
+    if (NtQueryTest != NULL)                                                                    \
+    {                                                                                           \
+        ok_eq_hex(NtQueryTest->MemInfo.Protect, ProtectionType);                                \
+        ok_eq_hex(NtQueryTest->MemInfo.State, AllocationType);                                  \
+        ok_eq_size(NtQueryTest->MemInfo.RegionSize, Size);                                      \
+        KmtFreeCallbackResponse(NtQueryTest);                                                   \
+    }                                                                                           \
+    } while (0)                                                                                 \
+
+#endif
+
 #ifdef KMT_STANDALONE_DRIVER
 #define KMT_KERNEL_MODE
 
@@ -67,6 +109,8 @@ typedef enum
     TESTENTRY_NO_REGISTER_DISPATCH = 2,
     TESTENTRY_NO_REGISTER_UNLOAD = 4,
     TESTENTRY_NO_EXCLUSIVE_DEVICE = 8,
+    TESTENTRY_NO_READONLY_DEVICE = 16,
+    TESTENTRY_BUFFERED_IO_DEVICE = 32,
 } KMT_TESTENTRY_FLAGS;
 
 NTSTATUS TestEntry(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath, OUT PCWSTR *DeviceName, IN OUT INT *Flags);
@@ -89,6 +133,10 @@ extern PDRIVER_OBJECT KmtDriverObject;
 VOID KmtSetIrql(IN KIRQL NewIrql);
 BOOLEAN KmtAreInterruptsEnabled(VOID);
 ULONG KmtGetPoolTag(PVOID Memory);
+USHORT KmtGetPoolType(PVOID Memory);
+PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName);
+PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL);
+VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL);
 #elif defined KMT_USER_MODE
 DWORD KmtRunKernelTest(IN PCSTR TestName);
 
@@ -147,6 +195,8 @@ VOID KmtFreeGuarded(PVOID Pointer);
 #define ok_eq_ulong(value, expected)        ok_eq_print(value, expected, "%lu")
 #define ok_eq_longlong(value, expected)     ok_eq_print(value, expected, "%I64d")
 #define ok_eq_ulonglong(value, expected)    ok_eq_print(value, expected, "%I64u")
+#define ok_eq_char(value, expected)         ok_eq_print(value, expected, "%c")
+#define ok_eq_wchar(value, expected)        ok_eq_print(value, expected, "%C")
 #ifndef _WIN64
 #define ok_eq_size(value, expected)         ok_eq_print(value, (SIZE_T)(expected), "%lu")
 #define ok_eq_longptr(value, expected)      ok_eq_print(value, (LONG_PTR)(expected), "%ld")
@@ -175,146 +225,41 @@ VOID KmtFreeGuarded(PVOID Pointer);
 #define MILLISECOND     (1000 * MICROSECOND)
 #define SECOND          (1000 * MILLISECOND)
 
+/* See apitests/include/apitest.h */
 #define KmtInvalidPointer ((PVOID)0x5555555555555555ULL)
 
 #define KmtStartSeh()                               \
-    ExceptionStatus = STATUS_SUCCESS;               \
+{                                                   \
+    NTSTATUS ExceptionStatus = STATUS_SUCCESS;      \
     _SEH2_TRY                                       \
     {
+
 #define KmtEndSeh(ExpectedStatus)                   \
     }                                               \
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)         \
     {                                               \
         ExceptionStatus = _SEH2_GetExceptionCode(); \
-    } _SEH2_END;                                    \
-    ok_eq_hex(ExceptionStatus, ExpectedStatus)
-
-#if defined KMT_DEFINE_TEST_FUNCTIONS
-
-#if defined KMT_KERNEL_MODE
-BOOLEAN KmtIsCheckedBuild;
-BOOLEAN KmtIsMultiProcessorBuild;
-PCSTR KmtMajorFunctionNames[] =
-{
-    "Create",
-    "CreateNamedPipe",
-    "Close",
-    "Read",
-    "Write",
-    "QueryInformation",
-    "SetInformation",
-    "QueryEa",
-    "SetEa",
-    "FlushBuffers",
-    "QueryVolumeInformation",
-    "SetVolumeInformation",
-    "DirectoryControl",
-    "FileSystemControl",
-    "DeviceControl",
-    "InternalDeviceControl/Scsi",
-    "Shutdown",
-    "LockControl",
-    "Cleanup",
-    "CreateMailslot",
-    "QuerySecurity",
-    "SetSecurity",
-    "Power",
-    "SystemControl",
-    "DeviceChange",
-    "QueryQuota",
-    "SetQuota",
-    "Pnp/PnpPower"
-};
-
-VOID KmtSetIrql(IN KIRQL NewIrql)
-{
-    KIRQL Irql = KeGetCurrentIrql();
-    if (Irql > NewIrql)
-        KeLowerIrql(NewIrql);
-    else if (Irql < NewIrql)
-        KeRaiseIrql(NewIrql, &Irql);
-}
-
-BOOLEAN KmtAreInterruptsEnabled(VOID)
-{
-    return (__readeflags() & (1 << 9)) != 0;
+    }                                               \
+    _SEH2_END;                                      \
+    ok_eq_hex(ExceptionStatus, (ExpectedStatus));   \
 }
 
-typedef struct _POOL_HEADER
-{
-    union
-    {
-        struct
-        {
-#ifdef _M_AMD64
-            USHORT PreviousSize:8;
-            USHORT PoolIndex:8;
-            USHORT BlockSize:8;
-            USHORT PoolType:8;
-#else
-            USHORT PreviousSize:9;
-            USHORT PoolIndex:7;
-            USHORT BlockSize:9;
-            USHORT PoolType:7;
-#endif
-        };
-        ULONG Ulong1;
-    };
-#ifdef _M_AMD64
-    ULONG PoolTag;
-#endif
-    union
-    {
-#ifdef _M_AMD64
-        PEPROCESS ProcessBilled;
-#else
-        ULONG PoolTag;
-#endif
-        struct
-        {
-            USHORT AllocatorBackTraceIndex;
-            USHORT PoolTagHash;
-        };
-    };
-} POOL_HEADER, *PPOOL_HEADER;
-
-ULONG KmtGetPoolTag(PVOID Memory)
-{
-    PPOOL_HEADER Header;
-
-    /* it's not so easy for allocations of PAGE_SIZE */
-    if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0)
-        return 'TooL';
+#define KmtGetSystemOrEmbeddedRoutineAddress(RoutineName)           \
+    p##RoutineName = KmtGetSystemRoutineAddress(L ## #RoutineName); \
+    if (!p##RoutineName)                                            \
+    {                                                               \
+        p##RoutineName = RoutineName;                               \
+        trace("Using embedded routine for " #RoutineName "\n");     \
+    }                                                               \
+    else                                                            \
+        trace("Using system routine for " #RoutineName "\n");
 
-    Header = Memory;
-    Header--;
-
-    return Header->PoolTag;
-}
+#if defined KMT_DEFINE_TEST_FUNCTIONS
 
-INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0);
+#if defined KMT_KERNEL_MODE
+#include "kmt_test_kernel.h"
 #elif defined KMT_USER_MODE
-static PKMT_RESULTBUFFER KmtAllocateResultBuffer(SIZE_T ResultBufferSize)
-{
-    PKMT_RESULTBUFFER Buffer = HeapAlloc(GetProcessHeap(), 0, ResultBufferSize);
-    if (!Buffer)
-        return NULL;
-
-    Buffer->Successes = 0;
-    Buffer->Failures = 0;
-    Buffer->Skipped = 0;
-    Buffer->LogBufferLength = 0;
-    Buffer->LogBufferMaxLength = (ULONG)ResultBufferSize - FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer);
-
-    return Buffer;
-}
-
-static VOID KmtFreeResultBuffer(PKMT_RESULTBUFFER Buffer)
-{
-    HeapFree(GetProcessHeap(), 0, Buffer);
-}
-
-#define KmtVSNPrintF vsnprintf
+#include "kmt_test_user.h"
 #endif /* defined KMT_USER_MODE */
 
 PKMT_RESULTBUFFER ResultBuffer = NULL;