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…
==============================================================================
--- 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…
==============================================================================
--- 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(a)relsoft.net)
+ * Aleksey Bragin (aleksey(a)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?re…
==============================================================================
--- 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?re…
==============================================================================
--- 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=…
==============================================================================
--- 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…
==============================================================================
--- 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>