diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 22d83aa4181..ac171bd0567 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -1169,12 +1169,12 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) break; } - if (test_dll_phase == 0 || test_dll_phase == 3) + if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3) ok(param != NULL, "dll: param %p\n", param); else ok(!param, "dll: param %p\n", param); - if (test_dll_phase == 0) expected_code = 195; + if (test_dll_phase == 0 || test_dll_phase == 1) expected_code = 195; else if (test_dll_phase == 3) expected_code = 196; else expected_code = STILL_ACTIVE; @@ -1199,9 +1199,25 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) for (i = 0; i < attached_thread_count; i++) { + /* Calling GetExitCodeThread() without waiting for thread termination + * leads to different results due to a race condition. + */ + if (expected_code != STILL_ACTIVE) + { + ret = WaitForSingleObject(attached_thread[i], 1000); + /* FIXME: remove once Wine is fixed */ + if (test_dll_phase == 1) todo_wine + ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); + else + ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); + } ret = GetExitCodeThread(attached_thread[i], &code); trace("dll: GetExitCodeThread(%u) => %d,%u\n", i, ret, code); ok(ret == 1, "GetExitCodeThread returned %d, expected 1\n", ret); + /* FIXME: remove once Wine is fixed */ + if (test_dll_phase == 1) todo_wine + ok(code == expected_code, "expected thread exit code %u, got %u\n", expected_code, code); + else ok(code == expected_code, "expected thread exit code %u, got %u\n", expected_code, code); } @@ -1212,7 +1228,13 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) if (expected_code == STILL_ACTIVE) ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret); else + { + /* FIXME: remove once Wine is fixed */ + if (test_dll_phase == 1) todo_wine ok(ret == WAIT_ABANDONED, "expected WAIT_ABANDONED, got %#x\n", ret); + else + ok(ret == WAIT_ABANDONED, "expected WAIT_ABANDONED, got %#x\n", ret); + } /* semaphore is not abandoned on thread termination */ ret = WaitForSingleObject(semaphore, 0); @@ -1228,8 +1250,16 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) else { ret = WaitForSingleObject(attached_thread[0], 0); + /* FIXME: remove once Wine is fixed */ + if (test_dll_phase == 1) todo_wine + ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); + else ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); ret = WaitForSingleObject(attached_thread[1], 0); + /* FIXME: remove once Wine is fixed */ + if (test_dll_phase == 1) todo_wine + ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); + else ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret); } @@ -1548,7 +1578,11 @@ static void child_process(const char *dll_name, DWORD target_offset) ok(!ret, "NtSetInformationProcess error %#x\n", ret); break; - case 1: + case 1: /* normal ExitProcess */ + ret = pRtlDllShutdownInProgress(); + ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret); + break; + case 2: /* ExitProcess will be called by the PROCESS_DETACH handler */ ret = pRtlDllShutdownInProgress(); ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);