diff --git a/reactos/include/ddk/kedef.h b/reactos/include/ddk/kedef.h index 45503653b0a..507f1b3fc1a 100644 --- a/reactos/include/ddk/kedef.h +++ b/reactos/include/ddk/kedef.h @@ -47,6 +47,7 @@ typedef enum _KWAIT_REASON WrDelayExecution, WrSuspended, WrUserRequest, + WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index 9825017d9ab..d31f5705ee7 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -232,6 +232,13 @@ typedef struct _KEVENT DISPATCHER_HEADER Header; } KEVENT, *PKEVENT; +typedef struct _KEVENT_PAIR +{ + CSHORT Type; + CSHORT Size; + KEVENT LowEvent; + KEVENT HighEvent; +} KEVENT_PAIR, *PKEVENT_PAIR; typedef VOID (*PDRIVER_ADD_DEVICE)(VOID); diff --git a/reactos/include/ntos/synch.h b/reactos/include/ntos/synch.h index 2dab9eaf410..6dcc696d156 100644 --- a/reactos/include/ntos/synch.h +++ b/reactos/include/ntos/synch.h @@ -16,6 +16,7 @@ #define EVENT_ALL_ACCESS (0x1f0003L) #define EVENT_QUERY_STATE (1) #define EVENT_MODIFY_STATE (2) +#define EVENT_PAIR_ALL_ACCESS (0x1f0000L) #define MUTEX_ALL_ACCESS (0x1f0001L) #define MUTEX_MODIFY_STATE (1) #define SEMAPHORE_ALL_ACCESS (0x1f0003L) diff --git a/reactos/ntoskrnl/include/internal/nt.h b/reactos/ntoskrnl/include/internal/nt.h index 028429413d6..227fb096d9c 100644 --- a/reactos/ntoskrnl/include/internal/nt.h +++ b/reactos/ntoskrnl/include/internal/nt.h @@ -1,3 +1,4 @@ VOID NtInitializeEventImplementation(VOID); +VOID NtInitializeEventPairImplementation(VOID); VOID NtInitializeSemaphoreImplementation(VOID); NTSTATUS NiInitPort(VOID); diff --git a/reactos/ntoskrnl/nt/evtpair.c b/reactos/ntoskrnl/nt/evtpair.c index 1bf0b38ddd1..95d39a5cb73 100644 --- a/reactos/ntoskrnl/nt/evtpair.c +++ b/reactos/ntoskrnl/nt/evtpair.c @@ -1,4 +1,5 @@ -/* +/* $Id: evtpair.c,v 1.5 2000/10/22 11:30:00 ekohl Exp $ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/nt/evtpair.c @@ -11,92 +12,296 @@ /* INCLUDES *****************************************************************/ #include +#include +#include +#include +#define NDEBUG #include + +/* GLOBALS *******************************************************************/ + +POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL; + + /* FUNCTIONS *****************************************************************/ -NTSTATUS -STDCALL -NtCreateEventPair ( - OUT PHANDLE EventPairHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes - ) +NTSTATUS NtpCreateEventPair(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) { - UNIMPLEMENTED; + DPRINT("NtpCreateEventPair(ObjectBody %x, Parent %x, RemainingPath %S)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) + { + return(STATUS_UNSUCCESSFUL); + } + + if (Parent != NULL && RemainingPath != NULL) + { + ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1); + } + return(STATUS_SUCCESS); +} + +VOID NtInitializeEventPairImplementation(VOID) +{ + ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + + RtlCreateUnicodeString(&ExEventObjectType->TypeName, L"EventPair"); + + ExEventPairObjectType->MaxObjects = ULONG_MAX; + ExEventPairObjectType->MaxHandles = ULONG_MAX; + ExEventPairObjectType->TotalObjects = 0; + ExEventPairObjectType->TotalHandles = 0; + ExEventPairObjectType->PagedPoolCharge = 0; + ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR); + ExEventPairObjectType->Dump = NULL; + ExEventPairObjectType->Open = NULL; + ExEventPairObjectType->Close = NULL; + ExEventPairObjectType->Delete = NULL; + ExEventPairObjectType->Parse = NULL; + ExEventPairObjectType->Security = NULL; + ExEventPairObjectType->QueryName = NULL; + ExEventPairObjectType->OkayToClose = NULL; + ExEventPairObjectType->Create = NtpCreateEventPair; } -NTSTATUS -STDCALL -NtSetHighEventPair ( - IN HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtCreateEventPair(OUT PHANDLE EventPairHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + + DPRINT("NtCreateEventPair()\n"); + EventPair = ObCreateObject(EventPairHandle, + DesiredAccess, + ObjectAttributes, + ExEventPairObjectType); + KeInitializeEvent(&EventPair->LowEvent, + SynchronizationEvent, + FALSE); + KeInitializeEvent(&EventPair->HighEvent, + SynchronizationEvent, + FALSE); + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtSetHighWaitLowEventPair ( - IN HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtOpenEventPair(OUT PHANDLE EventPairHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtOpenEventPair()\n"); + Status = ObReferenceObjectByName(ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, + NULL, + DesiredAccess, + ExEventPairObjectType, + UserMode, + NULL, + (PVOID*)&EventPair); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = ObCreateHandle(PsGetCurrentProcess(), + EventPair, + DesiredAccess, + FALSE, + EventPairHandle); + ObDereferenceObject(EventPair); + + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtSetLowEventPair ( - HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtSetHighEventPair(IN HANDLE EventPairHandle) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtSetHighEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeSetEvent(&EventPair->HighEvent, + EVENT_INCREMENT, + FALSE); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtSetLowWaitHighEventPair ( - HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeSetEvent(&EventPair->HighEvent, + EVENT_INCREMENT, + FALSE); + + KeWaitForSingleObject(&EventPair->LowEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtWaitLowEventPair ( - IN HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtSetLowEventPair(IN HANDLE EventPairHandle) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtSetLowEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeSetEvent(&EventPair->LowEvent, + EVENT_INCREMENT, + FALSE); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtOpenEventPair ( - OUT PHANDLE EventPairHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes - ) +NTSTATUS STDCALL +NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeSetEvent(&EventPair->LowEvent, + EVENT_INCREMENT, + FALSE); + + KeWaitForSingleObject(&EventPair->HighEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtWaitHighEventPair ( - IN HANDLE EventPairHandle - ) +NTSTATUS STDCALL +NtWaitLowEventPair(IN HANDLE EventPairHandle) { - UNIMPLEMENTED; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeWaitForSingleObject(&EventPair->LowEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +NtWaitHighEventPair(IN HANDLE EventPairHandle) +{ + PKEVENT_PAIR EventPair; + NTSTATUS Status; + + DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n", + EventPairHandle); + + Status = ObReferenceObjectByHandle(EventPairHandle, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode, + (PVOID*)&EventPair, + NULL); + if (!NT_SUCCESS(Status)) + return(Status); + + KeWaitForSingleObject(&EventPair->HighEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/ntoskrnl/nt/nt.c b/reactos/ntoskrnl/nt/nt.c index 808e93c3099..85c14e8fae9 100644 --- a/reactos/ntoskrnl/nt/nt.c +++ b/reactos/ntoskrnl/nt/nt.c @@ -20,6 +20,7 @@ VOID NtInit(VOID) { NtInitializeEventImplementation(); + NtInitializeEventPairImplementation(); NtInitializeSemaphoreImplementation(); NiInitPort(); }