[PATCH 14/22] ntdll: Use shared loader locking in LdrAddRefDll().
Paul Gofman
pgofman at codeweavers.com
Fri Oct 1 13:20:59 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/ntdll/loader.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 766a3108425..927de8e25f5 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -496,6 +496,16 @@ static void unlock_module_info(void)
RtlReleaseSRWLockExclusive( &loader_module_info_lock );
}
+/*************************************************************************
+ * is_thread_exclusive
+ *
+ * The loader must be locked while calling this function.
+ */
+static BOOL is_thread_exclusive(void)
+{
+ return RtlDllShutdownInProgress() || exclusive_lock_thread_id == GetCurrentThreadId();
+}
+
/*************************************************************************
* get_cached_modref
*
@@ -3431,14 +3441,24 @@ NTSTATUS WINAPI LdrAddRefDll( ULONG flags, HMODULE module )
if (flags & ~LDR_ADDREF_DLL_PIN) FIXME( "%p flags %x not implemented\n", module, flags );
- lock_loader_exclusive();
+ lock_loader_shared();
if ((wm = get_modref( module )))
{
- if (flags & LDR_ADDREF_DLL_PIN)
- wm->ldr.LoadCount = -1;
- else
- if (wm->ldr.LoadCount != -1) wm->ldr.LoadCount++;
+ lock_module_info();
+ /* If LdrAddRefDll is called during unloading from the application callback
+ * (DLL entry point or LDR notification) it fails with LDR_ADDREF_DLL_PIN flag
+ * but succeeds without, while module is still unloaded regardless. */
+ if (!wm->ldr.LoadCount)
+ {
+ if (is_thread_exclusive())
+ ret = flags & LDR_ADDREF_DLL_PIN ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
+ else
+ ret = STATUS_DLL_NOT_FOUND;
+ }
+ else if (flags & LDR_ADDREF_DLL_PIN) wm->ldr.LoadCount = -1;
+ else if (wm->ldr.LoadCount != -1) ++wm->ldr.LoadCount;
+ unlock_module_info();
TRACE( "(%s) ldr.LoadCount: %d\n", debugstr_w(wm->ldr.BaseDllName.Buffer), wm->ldr.LoadCount );
}
else ret = STATUS_INVALID_PARAMETER;
--
2.31.1
More information about the wine-devel
mailing list