[ros-diffs] [fireball] 51056: [NTDLL/LDR] - Rewrite loader lock APIs. Now they support proper flags, return correct error codes and generate/check a cookie.

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Mar 15 18:56:18 UTC 2011


Author: fireball
Date: Tue Mar 15 18:56:17 2011
New Revision: 51056

URL: http://svn.reactos.org/svn/reactos?rev=51056&view=rev
Log:
[NTDLL/LDR]
- Rewrite loader lock APIs. Now they support proper flags, return correct error codes and generate/check a cookie.

Added:
    trunk/reactos/dll/ntdll/ldr/ldrapi.c   (with props)
Modified:
    trunk/reactos/dll/ntdll/include/ntdllp.h
    trunk/reactos/dll/ntdll/ldr/ldrinit.c
    trunk/reactos/dll/ntdll/ldr/startup.c
    trunk/reactos/dll/ntdll/ldr/utils.c
    trunk/reactos/dll/ntdll/ntdll.rbuild

Modified: trunk/reactos/dll/ntdll/include/ntdllp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/include/ntdllp.h?rev=51056&r1=51055&r2=51056&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/include/ntdllp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/include/ntdllp.h [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -21,6 +21,8 @@
                        ULONG ul_reason_for_call,
                        LPVOID lpReserved);
 
+/* Global data */
+extern RTL_CRITICAL_SECTION LdrpLoaderLock;
 
 /* ldrinit.c */
 NTSTATUS NTAPI LdrpInitializeTls(VOID);

Added: trunk/reactos/dll/ntdll/ldr/ldrapi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrapi.c?rev=51056&view=auto
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/ldrapi.c (added)
+++ trunk/reactos/dll/ntdll/ldr/ldrapi.c [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -1,0 +1,249 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS NT User Mode Library
+ * FILE:            dll/ntdll/ldr/ldrapi.c
+ * PURPOSE:         PE Loader Public APIs
+ * PROGRAMMERS:     Alex Ionescu (alex at relsoft.net)
+ *                  Aleksey Bragin (aleksey at reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntdll.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define LDR_LOCK_HELD 0x2
+#define LDR_LOCK_FREE 0x1
+
+LONG LdrpLoaderLockAcquisitonCount;
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+LdrUnlockLoaderLock(IN ULONG Flags,
+                    IN ULONG Cookie OPTIONAL)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    DPRINT("LdrUnlockLoaderLock(%x %x)\n", Flags, Cookie);
+
+    /* Check for valid flags */
+    if (Flags & ~1)
+    {
+        /* Flags are invalid, check how to fail */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+        {
+            /* The caller wants us to raise status */
+            RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
+        }
+        else
+        {
+           /* A normal failure */
+            return STATUS_INVALID_PARAMETER_1;
+        }
+    }
+
+    /* If we don't have a cookie, just return */
+    if (!Cookie) return STATUS_SUCCESS;
+
+    /* Validate the cookie */
+    if ((Cookie & 0xF0000000) ||
+        ((Cookie >> 16) ^ ((ULONG)(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
+    {
+        DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
+
+        /* Invalid cookie, check how to fail */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+        {
+            /* The caller wants us to raise status */
+            RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
+        }
+        else
+        {
+            /* A normal failure */
+            return STATUS_INVALID_PARAMETER_2;
+        }
+    }
+
+    /* Ready to release the lock */
+    if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+    {
+        /* Do a direct leave */
+        RtlLeaveCriticalSection(&LdrpLoaderLock);
+    }
+    else
+    {
+        /* Wrap this in SEH, since we're not supposed to raise */
+        _SEH2_TRY
+        {
+            /* Leave the lock */
+            RtlLeaveCriticalSection(&LdrpLoaderLock);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* We should use the LDR Filter instead */
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
+    }
+
+    /* All done */
+    return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+LdrLockLoaderLock(IN ULONG Flags,
+                  OUT PULONG Result OPTIONAL,
+                  OUT PULONG Cookie OPTIONAL)
+{
+    LONG OldCount;
+    NTSTATUS Status = STATUS_SUCCESS;
+    BOOLEAN InInit = FALSE; // FIXME
+    //BOOLEAN InInit = LdrpInLdrInit;
+
+    DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Result, Cookie);
+
+    /* Zero out the outputs */
+    if (Result) *Result = 0;
+    if (Cookie) *Cookie = 0;
+
+    /* Validate the flags */
+    if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS |
+                  LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY))
+    {
+        /* Flags are invalid, check how to fail */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+        {
+            /* The caller wants us to raise status */
+            RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
+        }
+
+        /* A normal failure */
+        return STATUS_INVALID_PARAMETER_1;
+    }
+
+    /* Make sure we got a cookie */
+    if (!Cookie)
+    {
+        /* No cookie check how to fail */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+        {
+            /* The caller wants us to raise status */
+            RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
+        }
+
+        /* A normal failure */
+        return STATUS_INVALID_PARAMETER_3;
+    }
+
+    /* If the flag is set, make sure we have a valid pointer to use */
+    if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
+    {
+        /* No pointer to return the data to */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+        {
+            /* The caller wants us to raise status */
+            RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
+        }
+
+        /* Fail */
+        return STATUS_INVALID_PARAMETER_2;
+    }
+
+    /* Return now if we are in the init phase */
+    if (InInit) return STATUS_SUCCESS;
+
+    /* Check what locking semantic to use */
+    if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
+    {
+        /* Check if we should enter or simply try */
+        if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
+        {
+            /* Do a try */
+            if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
+            {
+                /* It's locked */
+                *Result = LDR_LOCK_HELD;
+                goto Quickie;
+            }
+            else
+            {
+                /* It worked */
+                *Result = LDR_LOCK_FREE;
+            }
+        }
+        else
+        {
+            /* Do a enter */
+            RtlEnterCriticalSection(&LdrpLoaderLock);
+
+            /* See if result was requested */
+            if (Result) *Result = LDR_LOCK_FREE;
+        }
+
+        /* Increase the acquisition count */
+        OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount);
+
+        /* Generate a cookie */
+        *Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount;
+    }
+    else
+    {
+        /* Wrap this in SEH, since we're not supposed to raise */
+        _SEH2_TRY
+        {
+            /* Check if we should enter or simply try */
+            if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
+            {
+                /* Do a try */
+                if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
+                {
+                    /* It's locked */
+                    *Result = LDR_LOCK_HELD;
+                    _SEH2_YIELD(return STATUS_SUCCESS);
+                }
+                else
+                {
+                    /* It worked */
+                    *Result = LDR_LOCK_FREE;
+                }
+            }
+            else
+            {
+                /* Do an enter */
+                RtlEnterCriticalSection(&LdrpLoaderLock);
+
+                /* See if result was requested */
+                if (Result) *Result = LDR_LOCK_FREE;
+            }
+
+            /* Increase the acquisition count */
+            OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount);
+
+            /* Generate a cookie */
+            *Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* We should use the LDR Filter instead */
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
+    }
+
+Quickie:
+    return Status;
+}
+
+/* EOF */

Propchange: trunk/reactos/dll/ntdll/ldr/ldrapi.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/dll/ntdll/ldr/ldrinit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrinit.c?rev=51056&r1=51055&r2=51056&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/ldrinit.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/ldrinit.c [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -28,6 +28,8 @@
 ULONG LdrpNumberOfTlsEntries;
 ULONG LdrpNumberOfProcessors;
 
+RTL_CRITICAL_SECTION LdrpLoaderLock;
+
 BOOLEAN ShowSnaps;
 
 /* FUNCTIONS *****************************************************************/

Modified: trunk/reactos/dll/ntdll/ldr/startup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/startup.c?rev=51056&r1=51055&r2=51056&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/startup.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/startup.c [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -25,7 +25,6 @@
 
 PLDR_DATA_TABLE_ENTRY ExeModule;
 static RTL_CRITICAL_SECTION PebLock;
-static RTL_CRITICAL_SECTION LoaderLock;
 static RTL_BITMAP TlsBitMap;
 static RTL_BITMAP TlsExpansionBitMap;
 static volatile BOOLEAN LdrpInitialized = FALSE;
@@ -467,8 +466,8 @@
     }
 
     /* initalize loader lock */
-    RtlInitializeCriticalSection(&LoaderLock);
-    Peb->LoaderLock = &LoaderLock;
+    RtlInitializeCriticalSection(&LdrpLoaderLock);
+    Peb->LoaderLock = &LdrpLoaderLock;
 
     /* create loader information */
     Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,

Modified: trunk/reactos/dll/ntdll/ldr/utils.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/utils.c?rev=51056&r1=51055&r2=51056&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/utils.c [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -3154,79 +3154,6 @@
     return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
 }
 
-NTSTATUS
-NTAPI
-LdrLockLoaderLock(IN ULONG Flags,
-                  OUT PULONG Disposition OPTIONAL,
-                  OUT PULONG Cookie OPTIONAL)
-{
-    NTSTATUS Status;
-    BOOLEAN Ret;
-    BOOLEAN CookieSet = FALSE;
-
-    if ((Flags != 0x01) && (Flags != 0x02))
-        return STATUS_INVALID_PARAMETER_1;
-
-    if (!Cookie) return STATUS_INVALID_PARAMETER_3;
-
-    /* Set some defaults for failure while verifying params */
-    _SEH2_TRY
-    {
-        *Cookie = 0;
-        CookieSet = TRUE;
-        if (Disposition) *Disposition = 0;
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        if (CookieSet)
-            Status = STATUS_INVALID_PARAMETER_3;
-        else
-            Status =  STATUS_INVALID_PARAMETER_2;
-    }
-    _SEH2_END;
-
-    if (Flags == 0x01)
-    {
-        DPRINT1("Warning: Reporting errors with exception not supported yet!\n");
-        RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
-        Status = STATUS_SUCCESS;
-
-    }
-    else
-    {
-        if (!Disposition) return STATUS_INVALID_PARAMETER_2;
-
-        Ret = RtlTryEnterCriticalSection(NtCurrentPeb()->LoaderLock);
-
-        if (Ret)
-            *Disposition = 0x01;
-        else
-            *Disposition = 0x02;
-
-        Status = STATUS_SUCCESS;
-    }
-
-    /* FIXME: Cookie is based on part of the thread id */
-    *Cookie = (ULONG)NtCurrentTeb()->RealClientId.UniqueThread;
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-LdrUnlockLoaderLock(IN ULONG Flags,
-                    IN ULONG Cookie OPTIONAL)
-{
-    if (Flags != 0x01)
-        return STATUS_INVALID_PARAMETER_1;
-
-    if (Cookie != (ULONG)NtCurrentTeb()->RealClientId.UniqueThread)
-        return STATUS_INVALID_PARAMETER_2;
-
-    RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
-
-    return STATUS_SUCCESS;
-}
-
 BOOLEAN
 NTAPI
 LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)

Modified: trunk/reactos/dll/ntdll/ntdll.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ntdll.rbuild?rev=51056&r1=51055&r2=51056&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/ntdll.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ntdll.rbuild [iso-8859-1] Tue Mar 15 18:56:17 2011
@@ -47,6 +47,7 @@
 			<pch>ntdll.h</pch>
 		</directory>
 		<directory name="ldr">
+			<file>ldrapi.c</file>
 			<file>ldrinit.c</file>
 			<file>ldrutils.c</file>
 			<file>startup.c</file>




More information about the Ros-diffs mailing list