* 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
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
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);
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);
#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")
#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;