diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index 57b05a1fd91..61264795e49 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -36,6 +36,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_ex/ExTimer.c ntos_fsrtl/FsRtlExpression.c ntos_io/IoDeviceInterface.c + ntos_io/IoEvent.c ntos_io/IoInterrupt.c ntos_io/IoIrp.c ntos_io/IoMdl.c diff --git a/rostests/kmtests/kmtest_drv/testlist.c b/rostests/kmtests/kmtest_drv/testlist.c index 4170778396d..406f8ab845d 100644 --- a/rostests/kmtests/kmtest_drv/testlist.c +++ b/rostests/kmtests/kmtest_drv/testlist.c @@ -21,6 +21,7 @@ KMT_TESTFUNC Test_ExSingleList; KMT_TESTFUNC Test_ExTimer; KMT_TESTFUNC Test_FsRtlExpression; KMT_TESTFUNC Test_IoDeviceInterface; +KMT_TESTFUNC Test_IoEvent; KMT_TESTFUNC Test_IoInterrupt; KMT_TESTFUNC Test_IoIrp; KMT_TESTFUNC Test_IoMdl; @@ -60,6 +61,7 @@ const KMT_TEST TestList[] = { "Example", Test_Example }, { "FsRtlExpression", Test_FsRtlExpression }, { "IoDeviceInterface", Test_IoDeviceInterface }, + { "IoEvent", Test_IoEvent }, { "IoInterrupt", Test_IoInterrupt }, { "IoIrp", Test_IoIrp }, { "IoMdl", Test_IoMdl }, diff --git a/rostests/kmtests/ntos_io/IoEvent.c b/rostests/kmtests/ntos_io/IoEvent.c new file mode 100644 index 00000000000..3da36478dc9 --- /dev/null +++ b/rostests/kmtests/ntos_io/IoEvent.c @@ -0,0 +1,118 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite Event creation test + * PROGRAMMER: Thomas Faber + */ + +#include + +#ifdef _WIN64 +#define KERNEL_HANDLE_FLAG 0xFFFFFFFF80000000ULL +#else +#define KERNEL_HANDLE_FLAG 0x80000000 +#endif + +#define CheckEventObject(Handle, Pointers, Handles) do \ +{ \ + PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \ + Status = ZwQueryObject(Handle, ObjectBasicInformation, \ + &ObjectInfo, sizeof ObjectInfo, NULL); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \ + ok_eq_ulong(ObjectInfo.HandleCount, Handles); \ + ok_eq_ulong(ObjectInfo.Attributes, 0); \ + ok_eq_ulong(ObjectInfo.GrantedAccess, EVENT_ALL_ACCESS); \ + ok(((ULONG_PTR)Handle & KERNEL_HANDLE_FLAG) == KERNEL_HANDLE_FLAG, \ + "Handle %p is not a kernel handle\n", Handle); \ +} while (0) + +static +VOID +TestCreateEvent( + PRKEVENT (NTAPI *CreateEvent)(PUNICODE_STRING, PHANDLE), + PUNICODE_STRING EventName, + EVENT_TYPE Type) +{ + NTSTATUS Status; + NTSTATUS ExceptionStatus; + PKEVENT Event, Event2; + HANDLE EventHandle, EventHandle2; + LONG State; + + /* Nameless event */ + KmtStartSeh() + Event = CreateEvent(NULL, &EventHandle); + ok(Event != NULL, "Event is NULL\n"); + ok(EventHandle != NULL, "EventHandle is NULL\n"); + if (!skip(EventHandle != NULL, "No event\n")) + { + ok_eq_uint(Event->Header.Type, Type); + State = KeReadStateEvent(Event); + ok_eq_long(State, 1L); + CheckEventObject(EventHandle, 2UL, 1UL); + Status = ZwClose(EventHandle); + ok_eq_hex(Status, STATUS_SUCCESS); + } + KmtEndSeh(STATUS_SUCCESS); + + /* Named event */ + EventHandle = NULL; + Event = CreateEvent(EventName, &EventHandle); + ok(Event != NULL, "Event is NULL\n"); + ok(EventHandle != NULL, "EventHandle is NULL\n"); + if (!skip(EventHandle != NULL, "No event\n")) + { + ok_eq_uint(Event->Header.Type, Type); + State = KeReadStateEvent(Event); + ok_eq_long(State, 1L); + CheckEventObject(EventHandle, 3UL, 1UL); + + /* Open the existing one */ + EventHandle2 = NULL; + Event2 = CreateEvent(EventName, &EventHandle2); + CheckEventObject(EventHandle, 4UL, 2UL); + ok(Event2 != NULL, "Event is NULL\n"); + ok(EventHandle2 != NULL, "EventHandle is NULL\n"); + if (!skip(EventHandle2 != NULL, "No event\n")) + { + CheckEventObject(EventHandle2, 4UL, 2UL); + ZwClose(EventHandle2); + } + + CheckEventObject(EventHandle, 3UL, 1UL); + Status = ZwClose(EventHandle); + ok_eq_hex(Status, STATUS_SUCCESS); + } +} + +START_TEST(IoEvent) +{ + PKEVENT Event, Event2; + HANDLE EventHandle = NULL, EventHandle2 = NULL; + UNICODE_STRING NotificationEventName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\KmTestIoEventNotificationEvent"); + UNICODE_STRING SynchronizationEventName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\KmTestIoEventSynchronizationEvent"); + + TestCreateEvent(IoCreateNotificationEvent, &NotificationEventName, NotificationEvent); + TestCreateEvent(IoCreateSynchronizationEvent, &SynchronizationEventName, SynchronizationEvent); + + /* Create different types with the same name */ + Event = IoCreateNotificationEvent(&NotificationEventName, &EventHandle); + ok(Event != NULL, "Event is NULL\n"); + ok(EventHandle != NULL, "EventHandle is NULL\n"); + if (!skip(EventHandle != NULL, "No event\n")) + { + ok_eq_uint(Event->Header.Type, NotificationEvent); + Event2 = IoCreateSynchronizationEvent(&NotificationEventName, &EventHandle2); + ok(Event2 != NULL, "Event is NULL\n"); + ok(EventHandle2 != NULL, "EventHandle is NULL\n"); + if (!skip(EventHandle2 != NULL, "No event\n")) + { + ok_eq_uint(Event2->Header.Type, NotificationEvent); + ZwClose(EventHandle2); + } + ZwClose(EventHandle); + } + +} +