- Fix some formatting.
[reactos.git] / reactos / ntoskrnl / ex / evtpair.c
index 15b05e6..2378610 100644 (file)
@@ -1,12 +1,10 @@
-/* $Id: evtpair.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ex/evtpair.c
  * PURPOSE:         Support for event pairs
- *
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Skywing (skywing@valhallalegends.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Thomas Weidenmueller
  */
 
 /* INCLUDES *****************************************************************/
 #define NDEBUG
 #include <internal/debug.h>
 
-#ifndef NTSYSAPI
-#define NTSYSAPI
-#endif
-
-#ifndef NTAPI
-#define NTAPI STDCALL
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ExpInitializeEventPairImplementation)
 #endif
 
-
 /* GLOBALS *******************************************************************/
 
-POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL;
-
-static GENERIC_MAPPING ExEventPairMapping = {
-       STANDARD_RIGHTS_READ,
-       STANDARD_RIGHTS_WRITE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
-       EVENT_PAIR_ALL_ACCESS};
-
-static KSPIN_LOCK ExThreadEventPairSpinLock;
+POBJECT_TYPE ExEventPairObjectType = NULL;
 
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-ExpCreateEventPair(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
+GENERIC_MAPPING ExEventPairMapping =
 {
-  DPRINT("ExpCreateEventPair(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
+    STANDARD_RIGHTS_READ,
+    STANDARD_RIGHTS_WRITE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
+    EVENT_PAIR_ALL_ACCESS
+};
 
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-  
-  return(STATUS_SUCCESS);
-}
+/* FUNCTIONS *****************************************************************/
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 ExpInitializeEventPairImplementation(VOID)
 {
-   ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair", NonPagedPool);
-   ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
-   ExEventPairObjectType->PeakObjects = 0;
-   ExEventPairObjectType->PeakHandles = 0;
-   ExEventPairObjectType->TotalObjects = 0;
-   ExEventPairObjectType->TotalHandles = 0;
-   ExEventPairObjectType->PagedPoolCharge = 0;
-   ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
-   ExEventPairObjectType->Mapping = &ExEventPairMapping;
-   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 = ExpCreateEventPair;
-   ExEventPairObjectType->DuplicationNotify = NULL;
-
-   KeInitializeSpinLock(&ExThreadEventPairSpinLock);
-   ObpCreateTypeObject(ExEventPairObjectType);
+    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+    UNICODE_STRING Name;
+    DPRINT("Creating Event Pair Object Type\n");
+
+    /* Create the Event Pair Object Type */
+    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+    RtlInitUnicodeString(&Name, L"EventPair");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT_PAIR);
+    ObjectTypeInitializer.GenericMapping = ExEventPairMapping;
+    ObjectTypeInitializer.PoolType = NonPagedPool;
+    ObjectTypeInitializer.ValidAccessMask = EVENT_PAIR_ALL_ACCESS;
+    ObjectTypeInitializer.UseDefaultObject = TRUE;
+    ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExEventPairObjectType);
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 NtCreateEventPair(OUT PHANDLE EventPairHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes)
-{
-   PKEVENT_PAIR EventPair;
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObCreateObject(PreviousMode,
-                          ExEventPairObjectType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(KEVENT_PAIR),
-                          0,
-                          0,
-                          (PVOID*)&EventPair);
-   if(NT_SUCCESS(Status))
-   {
-     KeInitializeEvent(&EventPair->LowEvent,
-                      SynchronizationEvent,
-                      FALSE);
-     KeInitializeEvent(&EventPair->HighEvent,
-                      SynchronizationEvent,
-                      FALSE);
-
-     Status = ObInsertObject ((PVOID)EventPair,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hEventPair);
-     ObDereferenceObject(EventPair);
-     
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *EventPairHandle = hEventPair;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
-   return Status;
-}
-
-
-NTSTATUS STDCALL
-NtOpenEventPair(OUT PHANDLE EventPairHandle,
-               IN ACCESS_MASK DesiredAccess,
-               IN POBJECT_ATTRIBUTES ObjectAttributes)
+                  IN ACCESS_MASK DesiredAccess,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExEventPairObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hEventPair);
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *EventPairHandle = hEventPair;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
-   
-   return Status;
-}
+    PKEVENT_PAIR EventPair;
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PAGED_CODE();
+    DPRINT("NtCreateEventPair: 0x%p\n", EventPairHandle);
+
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(EventPairHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        /* Bail out if pointer was invalid */
+        if(!NT_SUCCESS(Status)) return Status;
+    }
 
+    /* Create the Object */
+    DPRINT("Creating EventPair\n");
+    Status = ObCreateObject(PreviousMode,
+                            ExEventPairObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KEVENT_PAIR),
+                            0,
+                            0,
+                            (PVOID*)&EventPair);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Initalize the Event */
+        DPRINT("Initializing EventPair\n");
+        KeInitializeEventPair(EventPair);
+
+        /* Insert it */
+        Status = ObInsertObject((PVOID)EventPair,
+                                 NULL,
+                                 DesiredAccess,
+                                 0,
+                                 NULL,
+                                 &hEventPair);
+        ObDereferenceObject(EventPair);
+
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status))
+        {
+            _SEH_TRY
+            {
+                *EventPairHandle = hEventPair;
+            }
+            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+        }
+    }
 
-NTSTATUS STDCALL
-NtSetHighEventPair(IN HANDLE EventPairHandle)
-{
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
-NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
+NTSTATUS
+NTAPI
+NtOpenEventPair(OUT PHANDLE EventPairHandle,
+                IN ACCESS_MASK DesiredAccess,
+                IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
-}
-
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PAGED_CODE();
 
-NTSTATUS STDCALL
-NtSetLowEventPair(IN HANDLE EventPairHandle)
-{
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
-}
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(EventPairHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        /* Bail out if pointer was invalid */
+        if(!NT_SUCCESS(Status)) return Status;
+    }
 
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExEventPairObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hEventPair);
+
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status))
+    {
+        _SEH_TRY
+        {
+            *EventPairHandle = hEventPair;
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+    }
 
-NTSTATUS STDCALL
-NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
-{
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
-NtWaitLowEventPair(IN HANDLE EventPairHandle)
+NTSTATUS
+NTAPI
+NtSetHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
-}
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    PAGED_CODE();
+    DPRINT("NtSetHighEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
 
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
 
-NTSTATUS STDCALL
-NtWaitHighEventPair(IN HANDLE EventPairHandle)
-{
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-#ifdef _ENABLE_THRDEVTPAIR
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
 NTSTATUS
-NTSYSAPI
 NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
+NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-       
-       PreviousMode = ExGetPreviousMode();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = Thread->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->HighEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
-
-       ObDereferenceObject(EventPair);
-
-       return Status;
-}
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(Handle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
+
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
 
+    /* Return status */
+    return Status;
+}
 
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
 NTSTATUS
-NTSYSAPI
 NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
+NtSetLowEventPair(IN HANDLE EventPairHandle)
 {
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-
-       Thread = PsGetCurrentThread();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = PsGetCurrentThread()->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->LowEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    PAGED_CODE();
+    DPRINT1("NtSetHighEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
 
-       ObDereferenceObject(EventPair);
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
 
-       return Status;
+    /* Return status */
+    return Status;
 }
 
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when waiting on the
- * eventpair via NtSetLow/HighWaitHigh/LowThread.  Additionally, when
- * deleting a thread object, NtpSwapThreadEventPair(Thread, NULL) should
- * be called to release any preexisting eventpair object associated with
- * the thread.  The Microsoft name for this function is not known.
- */
-VOID
-ExpSwapThreadEventPair(
-       IN PETHREAD Thread,
-       IN PKEVENT_PAIR EventPair
-       )
+NTSTATUS
+NTAPI
+NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-       PKEVENT_PAIR OriginalEventPair;
-       KIRQL Irql;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       OriginalEventPair = Thread->EventPair;
-       Thread->EventPair = EventPair;
-
-       if(OriginalEventPair)
-               ObDereferenceObject(OriginalEventPair);
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(Handle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
+
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
 
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
+    /* Return status */
+    return Status;
 }
 
-#else /* !_ENABLE_THRDEVTPAIR */
 
 NTSTATUS
-NTSYSAPI
 NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
+NtWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-        DPRINT1("NtSetLowWaitHighThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(Handle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
+
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
-NTSYSAPI
 NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
+NtWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-        DPRINT1("NtSetHighWaitLowThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
-}
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(Handle 0x%p)\n", EventPairHandle);
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
 
-#endif /* _ENABLE_THRDEVTPAIR */
+    /* Return status */
+    return Status;
+}
 
 /* EOF */