Nikolay Sivov : ntdll: Implement non-blocking mode for LdrLockLoaderLock() .
Alexandre Julliard
julliard at winehq.org
Fri May 16 12:13:57 CDT 2014
Module: wine
Branch: master
Commit: 97e2af1f73b6985bd9c91fce18d0de1a1d95dc85
URL: http://source.winehq.org/git/wine.git/?a=commit;h=97e2af1f73b6985bd9c91fce18d0de1a1d95dc85
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri May 16 09:03:27 2014 +0400
ntdll: Implement non-blocking mode for LdrLockLoaderLock().
---
dlls/ntdll/loader.c | 26 +++++++++++++++++-----
dlls/ntdll/tests/rtl.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index d458a31..6471290 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1337,17 +1337,33 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
/******************************************************************
* LdrLockLoaderLock (NTDLL.@)
*
- * Note: flags are not implemented.
+ * Note: some flags are not implemented.
* Flag 0x01 is used to raise exceptions on errors.
- * Flag 0x02 is used to avoid waiting on the section (does RtlTryEnterCriticalSection instead).
*/
NTSTATUS WINAPI LdrLockLoaderLock( ULONG flags, ULONG *result, ULONG *magic )
{
- if (flags) FIXME( "flags %x not supported\n", flags );
+ if (flags & ~0x2) FIXME( "flags %x not supported\n", flags );
- if (result) *result = 1;
+ if (result) *result = 0;
+ if (magic) *magic = 0;
+ if (flags & ~0x3) return STATUS_INVALID_PARAMETER_1;
+ if (!result && (flags & 0x2)) return STATUS_INVALID_PARAMETER_2;
if (!magic) return STATUS_INVALID_PARAMETER_3;
- RtlEnterCriticalSection( &loader_section );
+
+ if (flags & 0x2)
+ {
+ if (!RtlTryEnterCriticalSection( &loader_section ))
+ {
+ *result = 2;
+ return STATUS_SUCCESS;
+ }
+ *result = 1;
+ }
+ else
+ {
+ RtlEnterCriticalSection( &loader_section );
+ if (result) *result = 1;
+ }
*magic = GetCurrentThreadId();
return STATUS_SUCCESS;
}
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 6eb6de3..72cee05 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -90,6 +90,8 @@ static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR);
static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *);
static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE);
+static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG*);
+static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -135,6 +137,8 @@ static void InitFunctionPtrs(void)
pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA");
pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll");
+ pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock");
+ pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -1543,6 +1547,57 @@ static void test_LdrAddRefDll(void)
ok(mod2 != NULL, "got %p\n", mod2);
}
+static void test_LdrLockLoaderLock(void)
+{
+ ULONG result, magic;
+ NTSTATUS status;
+
+ if (!pLdrLockLoaderLock)
+ {
+ win_skip("LdrLockLoaderLock() is not available\n");
+ return;
+ }
+
+ /* invalid flags */
+ result = 10;
+ magic = 0xdeadbeef;
+ status = pLdrLockLoaderLock(0x10, &result, &magic);
+ ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08x\n", status);
+ ok(result == 0, "got %d\n", result);
+ ok(magic == 0, "got 0x%08x\n", magic);
+
+ magic = 0xdeadbeef;
+ status = pLdrLockLoaderLock(0x10, NULL, &magic);
+ ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08x\n", status);
+ ok(magic == 0, "got 0x%08x\n", magic);
+
+ result = 10;
+ status = pLdrLockLoaderLock(0x10, &result, NULL);
+ ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08x\n", status);
+ ok(result == 0, "got %d\n", result);
+
+ /* non-blocking mode, result is null */
+ magic = 0xdeadbeef;
+ status = pLdrLockLoaderLock(0x2, NULL, &magic);
+ ok(status == STATUS_INVALID_PARAMETER_2, "got 0x%08x\n", status);
+ ok(magic == 0, "got 0x%08x\n", magic);
+
+ /* magic pointer is null */
+ result = 10;
+ status = pLdrLockLoaderLock(0, &result, NULL);
+ ok(status == STATUS_INVALID_PARAMETER_3, "got 0x%08x\n", status);
+ ok(result == 0, "got %d\n", result);
+
+ /* lock in non-blocking mode */
+ result = 0;
+ magic = 0;
+ status = pLdrLockLoaderLock(0x2, &result, &magic);
+ ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
+ ok(result == 1, "got %d\n", result);
+ ok(magic != 0, "got 0x%08x\n", magic);
+ pLdrUnlockLoaderLock(0, magic);
+}
+
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -1568,4 +1623,5 @@ START_TEST(rtl)
test_RtlIpv4AddressToStringEx();
test_RtlIpv4StringToAddress();
test_LdrAddRefDll();
+ test_LdrLockLoaderLock();
}
More information about the wine-cvs
mailing list