[NTDLL_VISTA]
authorPierre Schweitzer <pierre@reactos.org>
Tue, 30 May 2017 21:35:05 +0000 (21:35 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Tue, 30 May 2017 21:35:05 +0000 (21:35 +0000)
Create a new NTDLL library that exports some of the NTDLL Vista+ functions.
This new NTDLL includes at the time of commit:
- SRW locks implementation that was originally built in RTL but never used ;
- Condition variables implementation which is a new code in ReactOS trunk.

Condition variables is an implementation of Stephan Röger, with minor formatting
changes by Timo Kreuzer and various changes by myself.

CORE-7546
CORE-8204

svn path=/trunk/; revision=74703

reactos/dll/win32/CMakeLists.txt
reactos/dll/win32/ntdll_vista/CMakeLists.txt [new file with mode: 0644]
reactos/dll/win32/ntdll_vista/DllMain.c [new file with mode: 0644]
reactos/dll/win32/ntdll_vista/condvar.c [new file with mode: 0644]
reactos/dll/win32/ntdll_vista/ntdll_vista.spec [new file with mode: 0644]
reactos/dll/win32/ntdll_vista/rtl_vista.h [new file with mode: 0644]
reactos/dll/win32/ntdll_vista/srw.c [moved from reactos/sdk/lib/rtl/srw.c with 99% similarity]
reactos/sdk/lib/rtl/CMakeLists.txt

index 54621f9..291f5ab 100644 (file)
@@ -134,6 +134,7 @@ add_subdirectory(netevent)
 add_subdirectory(netid)
 add_subdirectory(newdev)
 add_subdirectory(npptools)
+add_subdirectory(ntdll_vista)
 add_subdirectory(ntdsapi)
 add_subdirectory(ntlanman)
 add_subdirectory(ntmarta)
diff --git a/reactos/dll/win32/ntdll_vista/CMakeLists.txt b/reactos/dll/win32/ntdll_vista/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6557a51
--- /dev/null
@@ -0,0 +1,17 @@
+
+remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
+add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
+
+spec2def(ntdll_vista.dll ntdll_vista.spec ADD_IMPORTLIB)
+
+list(APPEND SOURCE
+    DllMain.c
+    condvar.c
+    srw.c
+    ${CMAKE_CURRENT_BINARY_DIR}/ntdll_vista.def)
+
+add_library(ntdll_vista SHARED ${SOURCE})
+set_module_type(ntdll_vista win32dll ENTRYPOINT DllMain 12)
+add_importlibs(ntdll_vista ntdll kernel32)
+add_dependencies(ntdll_vista psdk)
+add_cd_file(TARGET ntdll_vista DESTINATION reactos/system32 FOR all)
diff --git a/reactos/dll/win32/ntdll_vista/DllMain.c b/reactos/dll/win32/ntdll_vista/DllMain.c
new file mode 100644 (file)
index 0000000..a7d5a08
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stdarg.h>
+
+#define WIN32_NO_STATUS
+
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winuser.h>
+#include <winwlx.h>
+
+#define NDEBUG
+#include <debug.h>
+
+VOID
+RtlpInitializeKeyedEvent(VOID);
+
+VOID
+RtlpCloseKeyedEvent(VOID);
+
+BOOL
+WINAPI
+DllMain(HANDLE hDll,
+        DWORD dwReason,
+        LPVOID lpReserved)
+{
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        DisableThreadLibraryCalls(hDll);
+        RtlpInitializeKeyedEvent();
+    }
+    else if (dwReason == DLL_PROCESS_DETACH)
+    {
+        RtlpCloseKeyedEvent();
+    }
+    return TRUE;
+}
diff --git a/reactos/dll/win32/ntdll_vista/condvar.c b/reactos/dll/win32/ntdll_vista/condvar.c
new file mode 100644 (file)
index 0000000..bd033af
--- /dev/null
@@ -0,0 +1,525 @@
+/*
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS system libraries
+ * PURPOSE:           Condition Variable Routines
+ * PROGRAMMERS:       Thomas Weidenmueller <w3seek@reactos.com>
+ *                    Stephan A. R�ger
+ */
+
+/* NOTE: This functionality can be optimized for releasing single
+   threads or for releasing all waiting threads at once. This
+   implementation is optimized for releasing a single thread at a time.
+   It wakes up sleeping threads in FIFO order. */
+
+/* INCLUDES ******************************************************************/
+
+#include <rtl_vista.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* INTERNAL TYPES ************************************************************/
+
+#define COND_VAR_UNUSED_FLAG         ((ULONG_PTR)1)
+#define COND_VAR_LOCKED_FLAG         ((ULONG_PTR)2)
+#define COND_VAR_FLAGS_MASK          ((ULONG_PTR)3)
+#define COND_VAR_ADDRESS_MASK        (~COND_VAR_FLAGS_MASK)
+
+typedef struct _COND_VAR_WAIT_ENTRY
+{
+    /* ListEntry must have an alignment of at least 32-bits, since we
+       want COND_VAR_ADDRESS_MASK to cover all of the address. */
+    LIST_ENTRY ListEntry;
+    PVOID WaitKey;
+    BOOLEAN ListRemovalHandled;
+} COND_VAR_WAIT_ENTRY, * PCOND_VAR_WAIT_ENTRY;
+
+#define CONTAINING_COND_VAR_WAIT_ENTRY(address, field) \
+    CONTAINING_RECORD(address, COND_VAR_WAIT_ENTRY, field)
+
+/* GLOBALS *******************************************************************/
+
+static HANDLE CondVarKeyedEventHandle = NULL;
+
+/* INTERNAL FUNCTIONS ********************************************************/
+
+FORCEINLINE
+ULONG_PTR
+InternalCmpXChgCondVarAcq(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                          IN ULONG_PTR Exchange,
+                          IN ULONG_PTR Comperand)
+{
+    return (ULONG_PTR)InterlockedCompareExchangePointerAcquire(&ConditionVariable->Ptr,
+                                                               (PVOID)Exchange,
+                                                               (PVOID)Comperand);
+}
+
+FORCEINLINE
+ULONG_PTR
+InternalCmpXChgCondVarRel(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                          IN ULONG_PTR Exchange,
+                          IN ULONG_PTR Comperand)
+{
+    return (ULONG_PTR)InterlockedCompareExchangePointerRelease(&ConditionVariable->Ptr,
+                                                               (PVOID)Exchange,
+                                                               (PVOID)Comperand);
+}
+
+FORCEINLINE
+BOOLEAN *
+InternalGetListRemovalHandledFlag(IN PCOND_VAR_WAIT_ENTRY Entry)
+{
+    return (BOOLEAN *)&Entry->ListRemovalHandled;
+}
+
+static
+PCOND_VAR_WAIT_ENTRY
+InternalLockCondVar(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                    IN PCOND_VAR_WAIT_ENTRY InsertEntry OPTIONAL,
+                    IN BOOLEAN * AbortIfLocked OPTIONAL)
+{
+    /* InsertEntry and AbortIfLocked may be NULL on entry. This routine
+       will return NULL if the lock was not acquired. Otherwise it has
+       successfully acquired the lock and the return value is a valid
+       reference to the list head associated with ConditionVariable.
+       The caller must in this case call InternalUnlockCondVar later
+       in order to unlock the condition variable.
+
+       If InsertEntry is NULL and there are no entries on the list, this
+       routine will not acquire the lock and return NULL. If InsertEntry
+       is not NULL this routine ensures that InsertEntry will be on the
+       list when it returns successfully.
+
+       If the lock is owned by another thread and AbortIfLocked is NULL,
+       this routine will block until it acquires the lock. If AbortIfLocked
+       is not NULL and the lock is owned by another thread, this routine
+       will periodically check if *AbortIfLocked is nonzero and if so, will
+       return NULL instead of continuing the wait. */
+
+    ULONG_PTR OldVal = (ULONG_PTR)ConditionVariable->Ptr;
+
+    for (;;)
+    {
+        ULONG_PTR NewVal, LockRes;
+        PLIST_ENTRY OldListHead;
+
+        if (OldVal & COND_VAR_LOCKED_FLAG)
+        {
+            /* The locked flag is set, indicating someone else currently
+               holds the lock. We'll spin until this flag becomes
+               clear or we're asked to abort. */
+            YieldProcessor();
+
+            if ((AbortIfLocked != NULL) && *AbortIfLocked)
+            {
+                /* The caller wants us to abort in this case. */
+                return NULL;
+            }
+
+            /* Refresh OldVal and try again. */
+            OldVal = *(ULONG_PTR *)&ConditionVariable->Ptr;
+            continue;
+        }
+
+        /* Retrieve the list head currently associated with the
+           condition variable. */
+        OldListHead = (PLIST_ENTRY)(OldVal & COND_VAR_ADDRESS_MASK);
+        if (InsertEntry == NULL)
+        {
+            /* The caller doesn't want to put any entry on the list. */
+            if (OldListHead == NULL)
+            {
+                /* The list is empty, so there is nothing to lock. */
+                return NULL;
+            }
+
+            /* The list isn't empty. In this case we need to preserve
+               all of OldVal. */
+            NewVal = OldVal;
+        }
+        else
+        {
+            /* Let InsertEntry be the new list head. Preserve only the
+               bits inside the COND_VAR_FLAGS_MASK range. */
+            NewVal = ((OldVal & COND_VAR_FLAGS_MASK) |
+                      (ULONG_PTR)&InsertEntry->ListEntry);
+        }
+
+        /* Set the flag that indicates someone is holding the lock and
+           try to update the condition variable thread-safe. */
+        NewVal |= COND_VAR_LOCKED_FLAG;
+        LockRes = InternalCmpXChgCondVarAcq(ConditionVariable, NewVal, OldVal);
+        if (LockRes == OldVal)
+        {
+            /* We successfully updated ConditionVariable the way we
+               wanted and now hold the lock. */
+            if (InsertEntry == NULL)
+            {
+                /* We know that OldVal contains a valid address in
+                   this case. */
+                ASSERT(OldListHead != NULL);
+                return CONTAINING_COND_VAR_WAIT_ENTRY(OldListHead, ListEntry);
+            }
+
+            /* InsertEntry is not on the list yet, so add it. In any
+               case InsertEntry will be the new list head. */
+            if (OldListHead == NULL)
+            {
+                /* List was empty before. */
+                InitializeListHead(&InsertEntry->ListEntry);
+            }
+            else
+            {
+                /* Make InsertEntry the last entry of the old list.
+                   As InsertEntry will take the role as new list head,
+                   OldListHead will become the second entry (InsertEntry->Flink)
+                   on the new list. */
+                InsertTailList(OldListHead, &InsertEntry->ListEntry);
+            }
+
+            return InsertEntry;
+        }
+
+        /* We didn't manage to update ConditionVariable, so try again. */
+        OldVal = LockRes;
+    }
+}
+
+static
+VOID
+InternalUnlockCondVar(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                      IN PCOND_VAR_WAIT_ENTRY RemoveEntry OPTIONAL)
+{
+    /* This routine assumes that the lock is being held on entry.
+       RemoveEntry may be NULL. If it is not NULL, this routine
+       assumes that RemoveEntry is on the list and will remove it
+       before releasing the lock. */
+    ULONG_PTR OldVal = (ULONG_PTR)ConditionVariable->Ptr;
+    PLIST_ENTRY NewHeadEntry;
+
+    ASSERT((OldVal & COND_VAR_LOCKED_FLAG) &&
+           (OldVal & COND_VAR_ADDRESS_MASK));
+
+    NewHeadEntry = (PLIST_ENTRY)(OldVal & COND_VAR_ADDRESS_MASK);
+    if (RemoveEntry != NULL)
+    {
+        /* We have to drop RemoveEntry from the list. */
+        if (&RemoveEntry->ListEntry == NewHeadEntry)
+        {
+            /* RemoveEntry is the list head. */
+            if (!IsListEmpty(NewHeadEntry))
+            {
+                /* The second entry in the list will become the new
+                   list head. It's from the thread that arrived
+                   right before the owner of RemoveEntry. */
+                NewHeadEntry = NewHeadEntry->Flink;
+                RemoveEntryList(&RemoveEntry->ListEntry);
+            }
+            else
+            {
+                /* The list will be empty, so discard the list. */
+                NewHeadEntry = NULL;
+            }
+        }
+        else
+        {
+            /* RemoveEntry is not the list head. The current list head
+               will remain. */
+            RemoveEntryList(&RemoveEntry->ListEntry);
+        }
+
+        /* Indicate to the owner of RemoveEntry that the entry
+           was removed from the list. RemoveEntry may not be touched
+           from here on. We don't use volatile semantics here since
+           the cache will anyway be flushed soon when we update
+           ConditionVariable. */
+        RemoveEntry->ListRemovalHandled = TRUE;
+    }
+
+    /* Now unlock thread-safe, while preserving any flags within the
+       COND_VAR_FLAGS_MASK range except for COND_VAR_LOCKED_FLAG. */
+    for (;;)
+    {
+        ULONG_PTR NewVal = ((OldVal & (COND_VAR_FLAGS_MASK ^ COND_VAR_LOCKED_FLAG)) |
+                            (ULONG_PTR)NewHeadEntry);
+        ULONG_PTR LockRes = InternalCmpXChgCondVarRel(ConditionVariable, NewVal, OldVal);
+        if (LockRes == OldVal)
+        {
+            /* We unlocked. */
+            break;
+        }
+
+        /* Try again. */
+        OldVal = LockRes;
+    }
+}
+
+static
+VOID
+InternalWake(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+             IN BOOLEAN ReleaseAll)
+{
+    /* If ReleaseAll is zero on entry, one thread at most will be woken.
+       Otherwise all waiting threads are woken. Wakeups happen in FIFO
+       order. */
+    PCOND_VAR_WAIT_ENTRY CONST HeadEntry = InternalLockCondVar(ConditionVariable, NULL, NULL);
+    PCOND_VAR_WAIT_ENTRY Entry;
+    PCOND_VAR_WAIT_ENTRY NextEntry;
+    LARGE_INTEGER Timeout;
+    PCOND_VAR_WAIT_ENTRY RemoveOnUnlockEntry;
+
+    ASSERT(CondVarKeyedEventHandle != NULL);
+
+    if (HeadEntry == NULL)
+    {
+        /* There is noone there to wake up. In this case do nothing
+           and return immediately. We don't stockpile releases. */
+        return;
+    }
+
+    Timeout.QuadPart = 0;
+    RemoveOnUnlockEntry = NULL;
+
+    /* Release sleeping threads. We will iterate from the last entry on
+       the list to the first. Note that the loop condition is always
+       true for the initial test. */
+    for (Entry = CONTAINING_COND_VAR_WAIT_ENTRY(HeadEntry->ListEntry.Blink, ListEntry);
+         Entry != NULL;
+         Entry = NextEntry)
+    {
+        NTSTATUS Status;
+
+        if (HeadEntry == Entry)
+        {
+            /* After the current entry we've iterated through the
+               entire list in backward direction. Then exit.*/
+            NextEntry = NULL;
+        }
+        else
+        {
+            /* Store away the next reference right now, since we may
+               not touch Entry anymore at the end of the block. */
+            NextEntry = CONTAINING_COND_VAR_WAIT_ENTRY(Entry->ListEntry.Blink, ListEntry);
+        }
+
+        /* Wake the thread associated with this event. We will
+           immediately return if we failed (zero timeout). */
+        Status = NtReleaseKeyedEvent(CondVarKeyedEventHandle,
+                                     &Entry->WaitKey,
+                                     FALSE,
+                                     &Timeout);
+
+        if (!NT_SUCCESS(Status))
+        {
+            /* We failed to wake a thread. We'll keep trying. */
+            ASSERT(STATUS_INVALID_HANDLE != Status);
+            continue;
+        }
+
+        /* We've woken a thread and will make sure this thread
+           is removed from the list. */
+        if (HeadEntry == Entry)
+        {
+            /* This is the list head. We can't remove it as easily as
+               other entries and will pass it to the unlock routine
+               later (we will exit the loop after this round anyway). */
+            RemoveOnUnlockEntry = HeadEntry;
+        }
+        else
+        {
+            /* We can remove the entry right away. */
+            RemoveEntryList(&Entry->ListEntry);
+
+            /* Now tell the woken thread that removal from the list was
+               already taken care of here so that this thread can resume
+               its normal operation more quickly. We may not touch
+               Entry after signaling this, since it may lie in invalid
+               memory from there on. */
+            *InternalGetListRemovalHandledFlag(Entry) = TRUE;
+        }
+
+        if (!ReleaseAll)
+        {
+            /* We've successfully woken one thread as the caller
+               demanded. */
+            break;
+        }
+    }
+
+    InternalUnlockCondVar(ConditionVariable, RemoveOnUnlockEntry);
+}
+
+VOID
+NTAPI
+RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
+VOID
+NTAPI
+RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock);
+
+static
+NTSTATUS
+InternalSleep(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+              IN OUT PRTL_CRITICAL_SECTION CriticalSection OPTIONAL,
+              IN OUT PRTL_SRWLOCK SRWLock OPTIONAL,
+              IN ULONG SRWFlags,
+              IN const LARGE_INTEGER * TimeOut OPTIONAL)
+{
+    /* Either CriticalSection or SRWLock must be NULL, but not both.
+       These caller provided lock must be held on entry and will be
+       held again on return. */
+
+    COND_VAR_WAIT_ENTRY OwnEntry;
+    NTSTATUS Status;
+
+    ASSERT(CondVarKeyedEventHandle != NULL);
+    ASSERT((CriticalSection == NULL) != (SRWLock == NULL));
+
+    RtlZeroMemory(&OwnEntry, sizeof(OwnEntry));
+
+    /* Put OwnEntry on the list. */
+    InternalLockCondVar(ConditionVariable, &OwnEntry, NULL);
+    InternalUnlockCondVar(ConditionVariable, NULL);
+
+    /* We can now drop the caller provided lock as a preparation for
+       going to sleep. */
+    if (CriticalSection == NULL)
+    {
+        if (0 == (RTL_CONDITION_VARIABLE_LOCKMODE_SHARED & SRWFlags))
+        {
+            RtlReleaseSRWLockExclusive(SRWLock);
+        }
+        else
+        {
+            RtlReleaseSRWLockShared(SRWLock);
+        }
+    }
+    else
+    {
+        RtlLeaveCriticalSection(CriticalSection);
+    }
+
+    /* Now sleep using the caller provided timeout. */
+    Status = NtWaitForKeyedEvent(CondVarKeyedEventHandle,
+                                 &OwnEntry.WaitKey,
+                                 FALSE,
+                                 (PLARGE_INTEGER)TimeOut);
+
+    ASSERT(STATUS_INVALID_HANDLE != Status);
+
+    if (!*InternalGetListRemovalHandledFlag(&OwnEntry))
+    {
+        /* Remove OwnEntry from the list again, since it still seems to
+           be on the list. We will know for sure once we've acquired
+           the lock. */
+        if (InternalLockCondVar(ConditionVariable,
+                                NULL,
+                                InternalGetListRemovalHandledFlag(&OwnEntry)))
+        {
+            /* Unlock and potentially remove OwnEntry. Self-removal is
+               usually only necessary when a timeout occurred. */
+            InternalUnlockCondVar(ConditionVariable,
+                                  !OwnEntry.ListRemovalHandled ?
+                                  &OwnEntry : NULL);
+        }
+    }
+
+#if _DEBUG
+    /* Clear OwnEntry to aid in detecting bugs. */
+    RtlZeroMemory(&OwnEntry, sizeof(OwnEntry));
+#endif
+
+    /* Reacquire the caller provided lock, as we are about to return. */
+    if (CriticalSection == NULL)
+    {
+        if (0 == (RTL_CONDITION_VARIABLE_LOCKMODE_SHARED & SRWFlags))
+        {
+            RtlAcquireSRWLockExclusive(SRWLock);
+        }
+        else
+        {
+            RtlAcquireSRWLockShared(SRWLock);
+        }
+    }
+    else
+    {
+        RtlEnterCriticalSection(CriticalSection);
+    }
+
+    /* Return whatever NtWaitForKeyedEvent returned. */
+    return Status;
+}
+
+VOID
+RtlpInitializeKeyedEvent(VOID)
+{
+    ASSERT(CondVarKeyedEventHandle == NULL);
+    NtCreateKeyedEvent(&CondVarKeyedEventHandle, EVENT_ALL_ACCESS, NULL, 0);
+}
+
+VOID
+RtlpCloseKeyedEvent(VOID)
+{
+    ASSERT(CondVarKeyedEventHandle != NULL);
+    NtClose(CondVarKeyedEventHandle);
+    CondVarKeyedEventHandle = NULL;
+}
+
+/* EXPORTED FUNCTIONS ********************************************************/
+
+VOID
+NTAPI
+RtlInitializeConditionVariable(OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    ConditionVariable->Ptr = NULL;
+}
+
+VOID
+NTAPI
+RtlWakeConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    InternalWake(ConditionVariable, FALSE);
+}
+
+VOID
+NTAPI
+RtlWakeAllConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable)
+{
+    InternalWake(ConditionVariable, TRUE);
+}
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                            IN OUT PRTL_CRITICAL_SECTION CriticalSection,
+                            IN const LARGE_INTEGER * TimeOut OPTIONAL)
+{
+    return InternalSleep(ConditionVariable,
+                         CriticalSection,
+                         (PRTL_SRWLOCK)NULL,
+                         0,
+                         TimeOut);
+}
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
+                             IN OUT PRTL_SRWLOCK SRWLock,
+                             IN const LARGE_INTEGER * TimeOut OPTIONAL,
+                             IN ULONG Flags)
+{
+    return InternalSleep(ConditionVariable,
+                         (PRTL_CRITICAL_SECTION)NULL,
+                         SRWLock,
+                         Flags,
+                         TimeOut);
+}
+
+/* EOF */
diff --git a/reactos/dll/win32/ntdll_vista/ntdll_vista.spec b/reactos/dll/win32/ntdll_vista/ntdll_vista.spec
new file mode 100644 (file)
index 0000000..2bcde61
--- /dev/null
@@ -0,0 +1,10 @@
+@ stdcall RtlInitializeConditionVariable(ptr)
+@ stdcall RtlWakeConditionVariable(ptr)
+@ stdcall RtlWakeAllConditionVariable(ptr)
+@ stdcall RtlSleepConditionVariableCS(ptr ptr ptr)
+@ stdcall RtlSleepConditionVariableSRW(ptr ptr ptr long)
+@ stdcall RtlInitializeSRWLock(ptr)
+@ stdcall RtlAcquireSRWLockShared(ptr)
+@ stdcall RtlReleaseSRWLockShared(ptr)
+@ stdcall RtlAcquireSRWLockExclusive(ptr)
+@ stdcall RtlReleaseSRWLockExclusive(ptr)
diff --git a/reactos/dll/win32/ntdll_vista/rtl_vista.h b/reactos/dll/win32/ntdll_vista/rtl_vista.h
new file mode 100644 (file)
index 0000000..9f96f15
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS System Libraries
+ * FILE:            lib/rtl/rtl.h
+ * PURPOSE:         Run-Time Libary Header
+ * PROGRAMMER:      Alex Ionescu
+ */
+
+#ifndef RTL_H
+#define RTL_H
+
+/* We're a core NT DLL, we don't import syscalls */
+#define _INC_SWPRINTF_INL_
+#undef __MSVCRT__
+
+/* C Headers */
+#include <stdlib.h>
+#include <stdio.h>
+
+/* PSDK/NDK Headers */
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+#define COBJMACROS
+#define CONST_VTABLE
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <objbase.h>
+#include <ntintsafe.h>
+#include <ndk/exfuncs.h>
+#include <ndk/iofuncs.h>
+#include <ndk/kefuncs.h>
+#include <ndk/ldrfuncs.h>
+#include <ndk/mmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/psfuncs.h>
+#include <ndk/rtlfuncs.h>
+#include <ndk/setypes.h>
+#include <ndk/sefuncs.h>
+#include <ndk/umfuncs.h>
+
+/* SEH support with PSEH */
+#include <pseh/pseh2.h>
+
+/* Use intrinsics for x86 and x64 */
+#if defined(_M_IX86) || defined(_M_AMD64)
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedIncrement _InterlockedIncrement
+#define InterlockedDecrement _InterlockedDecrement
+#define InterlockedExchangeAdd _InterlockedExchangeAdd
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedBitTestAndSet _interlockedbittestandset
+#define InterlockedBitTestAndSet64 _interlockedbittestandset64
+#endif
+
+#endif /* RTL_H */
similarity index 99%
rename from reactos/sdk/lib/rtl/srw.c
rename to reactos/dll/win32/ntdll_vista/srw.c
index bd62787..3173017 100644 (file)
@@ -13,7 +13,7 @@
 
 /* INCLUDES *****************************************************************/
 
-#include <rtl.h>
+#include <rtl_vista.h>
 
 #define NDEBUG
 #include <debug.h>
index 5c4cbe7..7279a2e 100644 (file)
@@ -16,7 +16,6 @@ list(APPEND SOURCE
     bitmap.c
     bootdata.c
     compress.c
-    condvar.c
     crc32.c
     critical.c
     dbgbuffer.c
@@ -56,7 +55,6 @@ list(APPEND SOURCE
     security.c
     slist.c
     sid.c
-    srw.c
     splaytree.c
     thread.c
     time.c