Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / ntoskrnl / ex / keyedevt.c
diff --git a/reactos/ntoskrnl/ex/keyedevt.c b/reactos/ntoskrnl/ex/keyedevt.c
deleted file mode 100644 (file)
index 6bb2769..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS Kernel
- * FILE:            ntoskrnl/ex/keyedevt.c
- * PURPOSE:         Support for keyed events
- * PROGRAMMERS:     Timo Kreuzer (timo.kreuzer@reactos.org)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* INTERNAL TYPES *************************************************************/
-
-#define NUM_KEY_HASH_BUCKETS 23
-typedef struct _EX_KEYED_EVENT
-{
-    struct
-    {
-        EX_PUSH_LOCK Lock;
-        LIST_ENTRY WaitListHead;
-        LIST_ENTRY ReleaseListHead;
-    } HashTable[NUM_KEY_HASH_BUCKETS];
-} EX_KEYED_EVENT, *PEX_KEYED_EVENT;
-
-/* GLOBALS *******************************************************************/
-
-PEX_KEYED_EVENT ExpCritSecOutOfMemoryEvent;
-POBJECT_TYPE ExKeyedEventObjectType;
-
-static
-GENERIC_MAPPING ExpKeyedEventMapping =
-{
-    STANDARD_RIGHTS_READ | KEYEDEVENT_WAIT,
-    STANDARD_RIGHTS_WRITE | KEYEDEVENT_WAKE,
-    STANDARD_RIGHTS_EXECUTE,
-    KEYEDEVENT_ALL_ACCESS
-};
-
-/* FUNCTIONS *****************************************************************/
-
-_IRQL_requires_max_(APC_LEVEL)
-BOOLEAN
-INIT_FUNCTION
-NTAPI
-ExpInitializeKeyedEventImplementation(VOID)
-{
-    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer = {0};
-    UNICODE_STRING TypeName = RTL_CONSTANT_STRING(L"KeyedEvent");
-    UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\KernelObjects\\CritSecOutOfMemoryEvent");
-    NTSTATUS Status;
-    HANDLE EventHandle;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-
-    /* Set up the object type initializer */
-    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
-    ObjectTypeInitializer.GenericMapping = ExpKeyedEventMapping;
-    ObjectTypeInitializer.PoolType = PagedPool;
-    ObjectTypeInitializer.ValidAccessMask = KEYEDEVENT_ALL_ACCESS;
-    ObjectTypeInitializer.UseDefaultObject = TRUE;
-
-    /* Create the keyed event object type */
-    Status = ObCreateObjectType(&TypeName,
-                                &ObjectTypeInitializer,
-                                NULL,
-                                &ExKeyedEventObjectType);
-    if (!NT_SUCCESS(Status)) return FALSE;
-
-    /* Create the out of memory event for critical sections */
-    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_PERMANENT, NULL, NULL);
-    Status = ZwCreateKeyedEvent(&EventHandle,
-                                KEYEDEVENT_ALL_ACCESS,
-                                &ObjectAttributes,
-                                0);
-    if (NT_SUCCESS(Status))
-    {
-        /* Take a reference so we can get rid of the handle */
-        Status = ObReferenceObjectByHandle(EventHandle,
-                                           KEYEDEVENT_ALL_ACCESS,
-                                           ExKeyedEventObjectType,
-                                           KernelMode,
-                                           (PVOID*)&ExpCritSecOutOfMemoryEvent,
-                                           NULL);
-        ZwClose(EventHandle);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-VOID
-NTAPI
-ExpInitializeKeyedEvent(
-    _Out_ PEX_KEYED_EVENT KeyedEvent)
-{
-    ULONG i;
-
-    /* Loop all hash buckets */
-    for (i = 0; i < NUM_KEY_HASH_BUCKETS; i++)
-    {
-        /* Initialize the mutex and the wait lists */
-        ExInitializePushLock(&KeyedEvent->HashTable[i].Lock);
-        InitializeListHead(&KeyedEvent->HashTable[i].WaitListHead);
-        InitializeListHead(&KeyedEvent->HashTable[i].ReleaseListHead);
-    }
-}
-
-_IRQL_requires_max_(APC_LEVEL)
-NTSTATUS
-NTAPI
-ExpReleaseOrWaitForKeyedEvent(
-    _Inout_ PEX_KEYED_EVENT KeyedEvent,
-    _In_ PVOID KeyedWaitValue,
-    _In_ BOOLEAN Alertable,
-    _In_ PLARGE_INTEGER Timeout,
-    _In_ BOOLEAN Release)
-{
-    PETHREAD Thread, CurrentThread;
-    PEPROCESS CurrentProcess;
-    PLIST_ENTRY ListEntry, WaitListHead1, WaitListHead2;
-    NTSTATUS Status;
-    ULONG_PTR HashIndex;
-    PVOID PreviousKeyedWaitValue;
-
-    /* Get the current process */
-    CurrentProcess = PsGetCurrentProcess();
-
-    /* Calculate the hash index */
-    HashIndex = (ULONG_PTR)KeyedWaitValue >> 5;
-    HashIndex ^= (ULONG_PTR)CurrentProcess >> 6;
-    HashIndex %= NUM_KEY_HASH_BUCKETS;
-
-    /* Lock the lists */
-    KeEnterCriticalRegion();
-    ExAcquirePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
-
-    /* Get the lists for search and wait, depending on whether
-       we want to wait for the event or signal it */
-    if (Release)
-    {
-        WaitListHead1 = &KeyedEvent->HashTable[HashIndex].WaitListHead;
-        WaitListHead2 = &KeyedEvent->HashTable[HashIndex].ReleaseListHead;
-    }
-    else
-    {
-        WaitListHead1 = &KeyedEvent->HashTable[HashIndex].ReleaseListHead;
-        WaitListHead2 = &KeyedEvent->HashTable[HashIndex].WaitListHead;
-    }
-
-    /* loop the first wait list */
-    ListEntry = WaitListHead1->Flink;
-    while (ListEntry != WaitListHead1)
-    {
-        /* Get the waiting thread. Note that this thread cannot be terminated
-           as long as we hold the list lock, since it either needs to wait to
-           be signaled by this thread or, when the wait is aborted due to thread
-           termination, then it first needs to acquire the list lock. */
-        Thread = CONTAINING_RECORD(ListEntry, ETHREAD, KeyedWaitChain);
-        ListEntry = ListEntry->Flink;
-
-        /* Check if this thread is a correct waiter */
-        if ((Thread->Tcb.Process == &CurrentProcess->Pcb) &&
-            (Thread->KeyedWaitValue == KeyedWaitValue))
-        {
-            /* Remove the thread from the list */
-            RemoveEntryList(&Thread->KeyedWaitChain);
-
-            /* Initialize the list entry to show that it was removed */
-            InitializeListHead(&Thread->KeyedWaitChain);
-
-            /* Wake the thread */
-            KeReleaseSemaphore(&Thread->KeyedWaitSemaphore,
-                               IO_NO_INCREMENT,
-                               1,
-                               FALSE);
-            Thread = NULL;
-
-            /* Unlock the list. After this it is not safe to access Thread */
-            ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
-            KeLeaveCriticalRegion();
-
-            return STATUS_SUCCESS;
-        }
-    }
-
-    /* Get the current thread */
-    CurrentThread = PsGetCurrentThread();
-
-    /* Set the wait key and remember the old value */
-    PreviousKeyedWaitValue = CurrentThread->KeyedWaitValue;
-    CurrentThread->KeyedWaitValue = KeyedWaitValue;
-
-    /* Initialize the wait semaphore */
-    KeInitializeSemaphore(&CurrentThread->KeyedWaitSemaphore, 0, 1);
-
-    /* Insert the current thread into the secondary wait list */
-    InsertTailList(WaitListHead2, &CurrentThread->KeyedWaitChain);
-
-    /* Unlock the list */
-    ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
-    KeLeaveCriticalRegion();
-
-    /* Wait for the keyed wait semaphore */
-    Status = KeWaitForSingleObject(&CurrentThread->KeyedWaitSemaphore,
-                                   WrKeyedEvent,
-                                   KernelMode,
-                                   Alertable,
-                                   Timeout);
-
-    /* Check if the wait was aborted or timed out */
-    if (Status != STATUS_SUCCESS)
-    {
-        /* Lock the lists to make sure no one else messes with the entry */
-        KeEnterCriticalRegion();
-        ExAcquirePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
-
-        /* Check if the wait list entry is still in the list */
-        if (!IsListEmpty(&CurrentThread->KeyedWaitChain))
-        {
-            /* Remove the thread from the list */
-            RemoveEntryList(&CurrentThread->KeyedWaitChain);
-            InitializeListHead(&CurrentThread->KeyedWaitChain);
-        }
-
-        /* Unlock the list */
-        ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
-        KeLeaveCriticalRegion();
-    }
-
-    /* Restore the previous KeyedWaitValue, since this is a union member */
-    CurrentThread->KeyedWaitValue = PreviousKeyedWaitValue;
-
-    return Status;
-}
-
-_IRQL_requires_max_(APC_LEVEL)
-NTSTATUS
-NTAPI
-ExpWaitForKeyedEvent(
-    _Inout_ PEX_KEYED_EVENT KeyedEvent,
-    _In_ PVOID KeyedWaitValue,
-    _In_ BOOLEAN Alertable,
-    _In_ PLARGE_INTEGER Timeout)
-{
-    /* Call the generic internal function */
-    return ExpReleaseOrWaitForKeyedEvent(KeyedEvent,
-                                         KeyedWaitValue,
-                                         Alertable,
-                                         Timeout,
-                                         FALSE);
-}
-
-_IRQL_requires_max_(APC_LEVEL)
-NTSTATUS
-NTAPI
-ExpReleaseKeyedEvent(
-    _Inout_ PEX_KEYED_EVENT KeyedEvent,
-    _In_ PVOID KeyedWaitValue,
-    _In_ BOOLEAN Alertable,
-    _In_ PLARGE_INTEGER Timeout)
-{
-    /* Call the generic internal function */
-    return ExpReleaseOrWaitForKeyedEvent(KeyedEvent,
-                                         KeyedWaitValue,
-                                         Alertable,
-                                         Timeout,
-                                         TRUE);
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-NTSTATUS
-NTAPI
-NtCreateKeyedEvent(
-    _Out_ PHANDLE OutHandle,
-    _In_ ACCESS_MASK AccessMask,
-    _In_ POBJECT_ATTRIBUTES ObjectAttributes,
-    _In_ ULONG Flags)
-{
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    PEX_KEYED_EVENT KeyedEvent;
-    HANDLE KeyedEventHandle;
-    NTSTATUS Status;
-
-    /* Check flags */
-    if (Flags != 0)
-    {
-        /* We don't support any flags yet */
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Create the object */
-    Status = ObCreateObject(PreviousMode,
-                            ExKeyedEventObjectType,
-                            ObjectAttributes,
-                            PreviousMode,
-                            NULL,
-                            sizeof(EX_KEYED_EVENT),
-                            0,
-                            0,
-                            (PVOID*)&KeyedEvent);
-
-    /* Check for success */
-    if (!NT_SUCCESS(Status)) return Status;
-
-    /* Initialize the keyed event */
-    ExpInitializeKeyedEvent(KeyedEvent);
-
-    /* Insert it */
-    Status = ObInsertObject(KeyedEvent,
-                            NULL,
-                            AccessMask,
-                            0,
-                            NULL,
-                            &KeyedEventHandle);
-
-    /* Check for success (ObInsertObject dereferences!) */
-    if (!NT_SUCCESS(Status)) return Status;
-
-    if (PreviousMode != KernelMode)
-    {
-        /* Enter SEH for return */
-        _SEH2_TRY
-        {
-            /* Return the handle to the caller */
-            ProbeForWrite(OutHandle, sizeof(HANDLE), sizeof(HANDLE));
-            *OutHandle = KeyedEventHandle;
-        }
-        _SEH2_EXCEPT(ExSystemExceptionFilter())
-        {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
-
-            /* Cleanup */
-            ObCloseHandle(KeyedEventHandle, PreviousMode);
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        *OutHandle = KeyedEventHandle;
-    }
-
-    /* Return Status */
-    return Status;
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-NTSTATUS
-NTAPI
-NtOpenKeyedEvent(
-    _Out_ PHANDLE OutHandle,
-    _In_ ACCESS_MASK AccessMask,
-    _In_ POBJECT_ATTRIBUTES ObjectAttributes)
-{
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    HANDLE KeyedEventHandle;
-    NTSTATUS Status;
-
-    /* Open the object */
-    Status = ObOpenObjectByName(ObjectAttributes,
-                                ExKeyedEventObjectType,
-                                PreviousMode,
-                                NULL,
-                                AccessMask,
-                                NULL,
-                                &KeyedEventHandle);
-
-    /* Check for success */
-    if (!NT_SUCCESS(Status)) return Status;
-
-    /* Enter SEH for return */
-    if (PreviousMode != KernelMode)
-    {
-        _SEH2_TRY
-        {
-            /* Return the handle to the caller */
-            ProbeForWrite(OutHandle, sizeof(HANDLE), sizeof(HANDLE));
-            *OutHandle = KeyedEventHandle;
-        }
-        _SEH2_EXCEPT(ExSystemExceptionFilter())
-        {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
-
-            /* Cleanup */
-            ObCloseHandle(KeyedEventHandle, PreviousMode);
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        *OutHandle = KeyedEventHandle;
-    }
-
-    /* Return status */
-    return Status;
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-NTSTATUS
-NTAPI
-NtWaitForKeyedEvent(
-    _In_opt_ HANDLE Handle,
-    _In_ PVOID Key,
-    _In_ BOOLEAN Alertable,
-    _In_opt_ PLARGE_INTEGER Timeout)
-{
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    PEX_KEYED_EVENT KeyedEvent;
-    NTSTATUS Status;
-    LARGE_INTEGER TimeoutCopy;
-
-    /* Key must always be two-byte aligned */
-    if ((ULONG_PTR)Key & 1)
-    {
-        return STATUS_INVALID_PARAMETER_1;
-    }
-
-    /* Check if the caller passed a timeout value and this is from user mode */
-    if ((Timeout != NULL) && (PreviousMode != KernelMode))
-    {
-        _SEH2_TRY
-        {
-            ProbeForRead(Timeout, sizeof(*Timeout), 1);
-            TimeoutCopy = *Timeout;
-            Timeout = &TimeoutCopy;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-
-    /* Check if the caller provided a handle */
-    if (Handle != NULL)
-    {
-        /* Get the keyed event object */
-        Status = ObReferenceObjectByHandle(Handle,
-                                           KEYEDEVENT_WAIT,
-                                           ExKeyedEventObjectType,
-                                           PreviousMode,
-                                           (PVOID*)&KeyedEvent,
-                                           NULL);
-
-        /* Check for success */
-        if (!NT_SUCCESS(Status)) return Status;
-    }
-    else
-    {
-        /* Use the default keyed event for low memory critical sections */
-        KeyedEvent = ExpCritSecOutOfMemoryEvent;
-    }
-
-    /* Do the wait */
-    Status = ExpWaitForKeyedEvent(KeyedEvent, Key, Alertable, Timeout);
-
-    /* Dereference the keyed event */
-    ObDereferenceObject(KeyedEvent);
-
-    /* Return the status */
-    return Status;
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-NTSTATUS
-NTAPI
-NtReleaseKeyedEvent(
-    _In_opt_ HANDLE Handle,
-    _In_ PVOID Key,
-    _In_ BOOLEAN Alertable,
-    _In_opt_ PLARGE_INTEGER Timeout)
-{
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    PEX_KEYED_EVENT KeyedEvent;
-    NTSTATUS Status;
-    LARGE_INTEGER TimeoutCopy;
-
-    /* Key must always be two-byte aligned */
-    if ((ULONG_PTR)Key & 1)
-    {
-        return STATUS_INVALID_PARAMETER_1;
-    }
-
-    /* Check if the caller passed a timeout value and this is from user mode */
-    if ((Timeout != NULL) && (PreviousMode != KernelMode))
-    {
-        _SEH2_TRY
-        {
-            ProbeForRead(Timeout, sizeof(*Timeout), 1);
-            TimeoutCopy = *Timeout;
-            Timeout = &TimeoutCopy;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-
-    /* Check if the caller provided a handle */
-    if (Handle != NULL)
-    {
-        /* Get the keyed event object */
-        Status = ObReferenceObjectByHandle(Handle,
-                                           KEYEDEVENT_WAKE,
-                                           ExKeyedEventObjectType,
-                                           PreviousMode,
-                                           (PVOID*)&KeyedEvent,
-                                           NULL);
-
-        /* Check for success */
-        if (!NT_SUCCESS(Status)) return Status;
-    }
-    else
-    {
-        /* Use the default keyed event for low memory critical sections */
-        KeyedEvent = ExpCritSecOutOfMemoryEvent;
-    }
-
-    /* Do the wait */
-    Status = ExpReleaseKeyedEvent(KeyedEvent, Key, Alertable, Timeout);
-
-    /* Dereference the keyed event */
-    ObDereferenceObject(KeyedEvent);
-
-    /* Return the status */
-    return Status;
-}
-
-/* EOF */