mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[KMTESTS]
- Add minimal ExCallback and PsNotify tests See issue #7120 for more details. svn path=/trunk/; revision=56734
This commit is contained in:
parent
3acf3b9507
commit
4cef479813
4 changed files with 336 additions and 0 deletions
|
@ -24,6 +24,7 @@ list(APPEND KMTEST_DRV_SOURCE
|
|||
|
||||
example/Example.c
|
||||
example/KernelType.c
|
||||
ntos_ex/ExCallback.c
|
||||
ntos_ex/ExDoubleList.c
|
||||
ntos_ex/ExFastMutex.c
|
||||
ntos_ex/ExHardError.c
|
||||
|
@ -50,6 +51,7 @@ list(APPEND KMTEST_DRV_SOURCE
|
|||
ntos_ob/ObReference.c
|
||||
ntos_ob/ObType.c
|
||||
ntos_ob/ObTypes.c
|
||||
ntos_ps/PsNotify.c
|
||||
${COMMON_SOURCE}
|
||||
|
||||
kmtest_drv/kmtest_drv.rc)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <kmt_test.h>
|
||||
|
||||
KMT_TESTFUNC Test_Example;
|
||||
KMT_TESTFUNC Test_ExCallback;
|
||||
KMT_TESTFUNC Test_ExDoubleList;
|
||||
KMT_TESTFUNC Test_ExFastMutex;
|
||||
KMT_TESTFUNC Test_ExHardError;
|
||||
|
@ -37,6 +38,7 @@ KMT_TESTFUNC Test_ObType;
|
|||
KMT_TESTFUNC Test_ObTypeClean;
|
||||
KMT_TESTFUNC Test_ObTypeNoClean;
|
||||
KMT_TESTFUNC Test_ObTypes;
|
||||
KMT_TESTFUNC Test_PsNotify;
|
||||
KMT_TESTFUNC Test_RtlAvlTree;
|
||||
KMT_TESTFUNC Test_RtlException;
|
||||
KMT_TESTFUNC Test_RtlMemory;
|
||||
|
@ -44,6 +46,7 @@ KMT_TESTFUNC Test_RtlSplayTree;
|
|||
|
||||
const KMT_TEST TestList[] =
|
||||
{
|
||||
{ "ExCallback", Test_ExCallback },
|
||||
{ "ExDoubleList", Test_ExDoubleList },
|
||||
{ "ExFastMutex", Test_ExFastMutex },
|
||||
{ "ExHardError", Test_ExHardError },
|
||||
|
@ -74,6 +77,7 @@ const KMT_TEST TestList[] =
|
|||
{ "-ObTypeClean", Test_ObTypeClean },
|
||||
{ "-ObTypeNoClean", Test_ObTypeNoClean },
|
||||
{ "ObTypes", Test_ObTypes },
|
||||
{ "PsNotify", Test_PsNotify },
|
||||
{ "RtlAvlTreeKM", Test_RtlAvlTree },
|
||||
{ "RtlExceptionKM", Test_RtlException },
|
||||
{ "RtlMemoryKM", Test_RtlMemory },
|
||||
|
|
153
rostests/kmtests/ntos_ex/ExCallback.c
Normal file
153
rostests/kmtests/ntos_ex/ExCallback.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite Executive Callback test
|
||||
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
static
|
||||
PEX_CALLBACK_ROUTINE_BLOCK
|
||||
(NTAPI
|
||||
*ExAllocateCallBack)(
|
||||
IN PEX_CALLBACK_FUNCTION Function,
|
||||
IN PVOID Context
|
||||
)
|
||||
//= (PVOID)0x809af1f4 // 2003 sp1 x86
|
||||
//= (PVOID)0x80a7f04a // 2003 sp1 x86 checked
|
||||
;
|
||||
|
||||
static
|
||||
VOID
|
||||
(NTAPI
|
||||
*ExFreeCallBack)(
|
||||
IN PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock
|
||||
)
|
||||
//= (PVOID)0x80918bb5 // 2003 sp1 x86
|
||||
//= (PVOID)0x80a355f0 // 2003 sp1 x86 checked
|
||||
;
|
||||
|
||||
static INT CallbackArgument1;
|
||||
static INT CallbackArgument2;
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ExCallbackFunction(
|
||||
IN PVOID CallbackContext,
|
||||
IN PVOID Argument1 OPTIONAL,
|
||||
IN PVOID Argument2 OPTIONAL)
|
||||
{
|
||||
ok(0, "Callback function unexpectedly called\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
TestPrivateFunctions(VOID)
|
||||
{
|
||||
UNICODE_STRING ExAllocateCallBackName = RTL_CONSTANT_STRING(L"ExAllocateCallBack");
|
||||
UNICODE_STRING ExFreeCallBackName = RTL_CONSTANT_STRING(L"ExFreeCallBack");
|
||||
PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
|
||||
INT CallbackContext;
|
||||
|
||||
if (!ExAllocateCallBack)
|
||||
ExAllocateCallBack = MmGetSystemRoutineAddress(&ExAllocateCallBackName);
|
||||
if (!ExFreeCallBack)
|
||||
ExFreeCallBack = MmGetSystemRoutineAddress(&ExFreeCallBackName);
|
||||
|
||||
if (skip(ExAllocateCallBack && ExFreeCallBack,
|
||||
"ExAllocateCallBack and/or ExFreeCallBack unavailable\n"))
|
||||
return;
|
||||
|
||||
CallbackBlock = ExAllocateCallBack(ExCallbackFunction, &CallbackContext);
|
||||
ok(CallbackBlock != NULL, "CallbackBlock = NULL\n");
|
||||
|
||||
if (skip(CallbackBlock != NULL, "Allocating callback failed\n"))
|
||||
return;
|
||||
|
||||
ok_eq_pointer(CallbackBlock->Function, ExCallbackFunction);
|
||||
ok_eq_pointer(CallbackBlock->Context, &CallbackContext);
|
||||
ok_eq_hex(KmtGetPoolTag(CallbackBlock), 'brbC');
|
||||
|
||||
ExFreeCallBack(CallbackBlock);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
CallbackFunction(
|
||||
IN PVOID CallbackContext,
|
||||
IN PVOID Argument1,
|
||||
IN PVOID Argument2)
|
||||
{
|
||||
INT *InvocationCount = CallbackContext;
|
||||
|
||||
ok_irql(PASSIVE_LEVEL);
|
||||
|
||||
(*InvocationCount)++;
|
||||
ok_eq_pointer(Argument1, &CallbackArgument1);
|
||||
ok_eq_pointer(Argument2, &CallbackArgument2);
|
||||
}
|
||||
|
||||
START_TEST(ExCallback)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCALLBACK_OBJECT CallbackObject;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING CallbackName = RTL_CONSTANT_STRING(L"\\Callback\\KmtestExCallbackTestCallback");
|
||||
PVOID CallbackRegistration;
|
||||
INT InvocationCount = 0;
|
||||
|
||||
TestPrivateFunctions();
|
||||
|
||||
/* TODO: Parameter tests */
|
||||
/* TODO: Test the three predefined callbacks */
|
||||
/* TODO: Test opening an existing callback */
|
||||
/* TODO: Test AllowMultipleCallbacks */
|
||||
/* TODO: Test calling multiple callbacks */
|
||||
/* TODO: Test registering the same function twice */
|
||||
/* TODO: Test callback object fields */
|
||||
/* TODO: Test callback registration fields */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&CallbackName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
CallbackObject = KmtInvalidPointer;
|
||||
Status = ExCreateCallback(&CallbackObject,
|
||||
&ObjectAttributes,
|
||||
TRUE,
|
||||
TRUE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok(CallbackObject != NULL && CallbackObject != KmtInvalidPointer,
|
||||
"CallbackObject = %p", CallbackObject);
|
||||
|
||||
if (skip(NT_SUCCESS(Status), "Creating callback failed\n"))
|
||||
return;
|
||||
|
||||
CallbackRegistration = ExRegisterCallback(CallbackObject,
|
||||
CallbackFunction,
|
||||
&InvocationCount);
|
||||
ok(CallbackRegistration != NULL, "CallbackRegistration = NULL\n");
|
||||
|
||||
if (!skip(CallbackRegistration != NULL, "Registering callback failed\n"))
|
||||
{
|
||||
ok_eq_hex(KmtGetPoolTag(CallbackRegistration), 'eRBC');
|
||||
ok_eq_int(InvocationCount, 0);
|
||||
ExNotifyCallback(CallbackObject,
|
||||
&CallbackArgument1,
|
||||
&CallbackArgument2);
|
||||
ok_eq_int(InvocationCount, 1);
|
||||
ExNotifyCallback(CallbackObject,
|
||||
&CallbackArgument1,
|
||||
&CallbackArgument2);
|
||||
ok_eq_int(InvocationCount, 2);
|
||||
|
||||
ExUnregisterCallback(CallbackRegistration);
|
||||
}
|
||||
|
||||
ObDereferenceObject(CallbackObject);
|
||||
}
|
177
rostests/kmtests/ntos_ps/PsNotify.c
Normal file
177
rostests/kmtests/ntos_ps/PsNotify.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite Process Notification Routines test
|
||||
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
CreateProcessNotifyRoutine(
|
||||
IN HANDLE ParentId,
|
||||
IN HANDLE ProcessId,
|
||||
IN BOOLEAN Create)
|
||||
{
|
||||
ok_irql(PASSIVE_LEVEL);
|
||||
if (!Create)
|
||||
ok_eq_pointer(ProcessId, PsGetCurrentProcessId());
|
||||
else
|
||||
ok(ProcessId != PsGetCurrentProcessId(),
|
||||
"ProcessId %p equals current\n", ProcessId);
|
||||
DPRINT("%s(%p, %p, %d)\n", __FUNCTION__, ParentId, ProcessId, Create);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
TestCreateProcessNotify(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(NULL, FALSE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* TODO: test whether the callback is notified on process creation */
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
/* TODO: register the same routine twice */
|
||||
/* TODO: register more than the maximum number of notifications */
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
CreateThreadNotifyRoutine(
|
||||
IN HANDLE ProcessId,
|
||||
IN HANDLE ThreadId,
|
||||
IN BOOLEAN Create)
|
||||
{
|
||||
ok_irql(PASSIVE_LEVEL);
|
||||
if (!Create)
|
||||
{
|
||||
ok_eq_pointer(ProcessId, PsGetCurrentProcessId());
|
||||
ok_eq_pointer(ThreadId, PsGetCurrentThreadId());
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(ThreadId != PsGetCurrentThreadId(),
|
||||
"ThreadId %p equals current\n", ThreadId);
|
||||
}
|
||||
DPRINT("%s(%p, %p, %d)\n", __FUNCTION__, ProcessId, ThreadId, Create);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
TestCreateThreadNotify(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetCreateThreadNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* TODO: test whether the callback is notified on thread creation */
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
/* TODO: register the same routine twice */
|
||||
/* TODO: register more than the maximum number of notifications */
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
LoadImageNotifyRoutine(
|
||||
IN PUNICODE_STRING FullImageName OPTIONAL,
|
||||
IN HANDLE ProcessId,
|
||||
IN PIMAGE_INFO ImageInfo)
|
||||
{
|
||||
ok_irql(PASSIVE_LEVEL);
|
||||
DPRINT("%s('%wZ', %p, %p)\n", __FUNCTION__, FullImageName, ProcessId, ImageInfo);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
TestLoadImageNotify(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetLoadImageNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(NULL);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
Status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* TODO: test whether the callback is notified on image load */
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
|
||||
ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
|
||||
|
||||
/* TODO: register the same routine twice */
|
||||
/* TODO: register more than the maximum number of notifications */
|
||||
}
|
||||
|
||||
START_TEST(PsNotify)
|
||||
{
|
||||
TestCreateProcessNotify();
|
||||
TestCreateThreadNotify();
|
||||
TestLoadImageNotify();
|
||||
}
|
Loading…
Reference in a new issue