Commit 97e2af1f authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

ntdll: Implement non-blocking mode for LdrLockLoaderLock().

parent 176b7aa8
...@@ -1337,17 +1337,33 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod) ...@@ -1337,17 +1337,33 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
/****************************************************************** /******************************************************************
* LdrLockLoaderLock (NTDLL.@) * LdrLockLoaderLock (NTDLL.@)
* *
* Note: flags are not implemented. * Note: some flags are not implemented.
* Flag 0x01 is used to raise exceptions on errors. * 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 ) 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; if (!magic) return STATUS_INVALID_PARAMETER_3;
if (flags & 0x2)
{
if (!RtlTryEnterCriticalSection( &loader_section ))
{
*result = 2;
return STATUS_SUCCESS;
}
*result = 1;
}
else
{
RtlEnterCriticalSection( &loader_section ); RtlEnterCriticalSection( &loader_section );
if (result) *result = 1;
}
*magic = GetCurrentThreadId(); *magic = GetCurrentThreadId();
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
......
...@@ -90,6 +90,8 @@ static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); ...@@ -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 *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *);
static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE);
static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG*);
static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG);
static HMODULE hkernel32 = 0; static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
...@@ -135,6 +137,8 @@ static void InitFunctionPtrs(void) ...@@ -135,6 +137,8 @@ static void InitFunctionPtrs(void)
pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA");
pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll");
pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock");
pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock");
} }
hkernel32 = LoadLibraryA("kernel32.dll"); hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n"); ok(hkernel32 != 0, "LoadLibrary failed\n");
...@@ -1543,6 +1547,57 @@ static void test_LdrAddRefDll(void) ...@@ -1543,6 +1547,57 @@ static void test_LdrAddRefDll(void)
ok(mod2 != NULL, "got %p\n", mod2); 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) START_TEST(rtl)
{ {
InitFunctionPtrs(); InitFunctionPtrs();
...@@ -1568,4 +1623,5 @@ START_TEST(rtl) ...@@ -1568,4 +1623,5 @@ START_TEST(rtl)
test_RtlIpv4AddressToStringEx(); test_RtlIpv4AddressToStringEx();
test_RtlIpv4StringToAddress(); test_RtlIpv4StringToAddress();
test_LdrAddRefDll(); test_LdrAddRefDll();
test_LdrLockLoaderLock();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment