Signed-off-by: Daniel Lehman dlehman25@gmail.com --- dlls/ntdll/tests/exception.c | 70 ++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index e01e280d741..98d185f5f07 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -1211,7 +1211,7 @@ static void test_debugger(DWORD cont_status)
if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } - else if (stage == 11 || stage == 12 || stage == 13) + else if (stage == 11 || stage == 12) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE, "unexpected exception code %08lx, expected %08lx\n", de.u.Exception.ExceptionRecord.ExceptionCode, @@ -1219,7 +1219,13 @@ static void test_debugger(DWORD cont_status) ok(de.u.Exception.ExceptionRecord.NumberParameters == 0, "unexpected number of parameters %ld, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters);
- if (stage == 12|| stage == 13) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + if (stage == 12) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 13) + { + todo_wine + ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); + continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else if (stage == 14 || stage == 15) { @@ -3905,7 +3911,7 @@ static void test_debugger(DWORD cont_status) "expected Rip = %p, got %p\n", (char *)code_mem_address + 2, (char *)ctx.Rip); if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } - else if (stage == 11 || stage == 12 || stage == 13) + else if (stage == 11 || stage == 12) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE, "unexpected exception code %08lx, expected %08lx\n", de.u.Exception.ExceptionRecord.ExceptionCode, @@ -3913,7 +3919,13 @@ static void test_debugger(DWORD cont_status) ok(de.u.Exception.ExceptionRecord.NumberParameters == 0, "unexpected number of parameters %ld, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters);
- if (stage == 12|| stage == 13) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + if (stage == 12) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 13) + { + todo_wine + ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); + continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else if (stage == 14 || stage == 15) { @@ -6603,7 +6615,7 @@ static void test_debugger(DWORD cont_status) "expected Pc = %p, got 0x%x\n", (char *)code_mem_address + 3, ctx.Pc); if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } - else if (stage == 11 || stage == 12 || stage == 13) + else if (stage == 11 || stage == 12) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE, "unexpected exception code %08x, expected %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode, @@ -6611,7 +6623,13 @@ static void test_debugger(DWORD cont_status) ok(de.u.Exception.ExceptionRecord.NumberParameters == 0, "unexpected number of parameters %d, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters);
- if (stage == 12|| stage == 13) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + if (stage == 12) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 13) + { + todo_wine + ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); + continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else ok(FALSE, "unexpected stage %x\n", stage); @@ -7851,7 +7869,7 @@ static void test_debugger(DWORD cont_status) "expected Pc = %p, got %p\n", (char *)code_mem_address + 4, (char *)ctx.Pc); if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } - else if (stage == 11 || stage == 12 || stage == 13) + else if (stage == 11 || stage == 12) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE, "unexpected exception code %08x, expected %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode, @@ -7859,7 +7877,13 @@ static void test_debugger(DWORD cont_status) ok(de.u.Exception.ExceptionRecord.NumberParameters == 0, "unexpected number of parameters %d, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters);
- if (stage == 12|| stage == 13) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + if (stage == 12) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 13) + { + todo_wine + ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); + continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else ok(FALSE, "unexpected stage %x\n", stage); @@ -8575,6 +8599,11 @@ static LONG CALLBACK invalid_handle_vectored_handler(EXCEPTION_POINTERS *Excepti return (rec->ExceptionCode == EXCEPTION_INVALID_HANDLE) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; }
+static inline BOOL is_magic_handle(HANDLE handle) +{ + return HandleToLong(handle) >= ~5 && HandleToLong(handle) <= ~0; +} + static void test_closehandle(DWORD numexc, HANDLE handle) { PVOID vectored_handler; @@ -8590,13 +8619,17 @@ static void test_closehandle(DWORD numexc, HANDLE handle)
invalid_handle_exceptions = 0; CloseHandle(handle); - ok(invalid_handle_exceptions == numexc, "CloseHandle generated %ld exceptions, expected %ld\n", - invalid_handle_exceptions, numexc); + todo_wine_if(is_magic_handle(handle)) + ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ + "CloseHandle generated %ld exceptions, expected %ld for %p\n", + invalid_handle_exceptions, numexc, handle);
invalid_handle_exceptions = 0; pNtClose(handle); - ok(invalid_handle_exceptions == numexc, "NtClose generated %ld exceptions, expected %ld\n", - invalid_handle_exceptions, numexc); + todo_wine_if(is_magic_handle(handle)) + ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ + "CloseHandle generated %ld exceptions, expected %ld for %p\n", + invalid_handle_exceptions, numexc, handle);
pRtlRemoveVectoredExceptionHandler(vectored_handler); } @@ -10676,10 +10709,19 @@ START_TEST(exception) test_breakpoint(1); test_stage = 11; test_closehandle(0, (HANDLE)0xdeadbeef); + test_closehandle(0, (HANDLE)0x7fffffff); test_stage = 12; test_closehandle(1, (HANDLE)0xdeadbeef); - test_stage = 13; - test_closehandle(0, 0); /* Special case. */ + test_closehandle(1, (HANDLE)~(ULONG_PTR)6); + test_stage = 13; /* special cases */ + test_closehandle(0, 0); + test_closehandle(0, INVALID_HANDLE_VALUE); + test_closehandle(0, GetCurrentProcess()); + test_closehandle(0, GetCurrentThread()); + test_closehandle(0, (HANDLE)~(ULONG_PTR)2); + test_closehandle(0, GetCurrentProcessToken()); + test_closehandle(0, GetCurrentThreadToken()); + test_closehandle(0, GetCurrentThreadEffectiveToken()); #if defined(__i386__) || defined(__x86_64__) test_stage = 14; test_debuggee_xstate();
Signed-off-by: Daniel Lehman dlehman25@gmail.com --- dlls/ntdll/tests/exception.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 98d185f5f07..8af8d6b70da 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -8606,7 +8606,9 @@ static inline BOOL is_magic_handle(HANDLE handle)
static void test_closehandle(DWORD numexc, HANDLE handle) { + NTSTATUS status, expect; PVOID vectored_handler; + BOOL ret, expectret;
if (!pRtlAddVectoredExceptionHandler || !pRtlRemoveVectoredExceptionHandler || !pRtlRaiseException) { @@ -8618,18 +8620,28 @@ static void test_closehandle(DWORD numexc, HANDLE handle) ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
invalid_handle_exceptions = 0; - CloseHandle(handle); - todo_wine_if(is_magic_handle(handle)) + expectret = is_magic_handle(handle) || broken(numexc && sizeof(handle) == 4); /* < Win10 */ + ret = CloseHandle(handle); + ok(expectret || (GetLastError() == ERROR_INVALID_HANDLE), + "CloseHandle had wrong GetLastError(), got %lu for %p\n", GetLastError(), handle); + todo_wine_if(is_magic_handle(handle)) { + ok(ret == expectret || broken(HandleToLong(handle) < 0) /* < Win10 */, + "CloseHandle expected %d, got %d for %p\n", expectret, ret, handle); ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ "CloseHandle generated %ld exceptions, expected %ld for %p\n", invalid_handle_exceptions, numexc, handle); + }
invalid_handle_exceptions = 0; - pNtClose(handle); - todo_wine_if(is_magic_handle(handle)) + expect = expectret ? STATUS_SUCCESS : STATUS_INVALID_HANDLE; + status = pNtClose(handle); + todo_wine_if(is_magic_handle(handle)) { + ok(status == expect || broken(HandleToLong(handle) < 0), /* < Win10 */ + "NtClose returned unexpected status %#lx, expected %#lx for %p\n", status, expect, handle); ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ "CloseHandle generated %ld exceptions, expected %ld for %p\n", invalid_handle_exceptions, numexc, handle); + }
pRtlRemoveVectoredExceptionHandler(vectored_handler); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111814
Your paranoid android.
=== debian11 (64 bit WoW report) ===
Report validation errors: ntdll:exception prints too much data (38460 bytes)
https://bugs.winehq.org/show_bug.cgi?id=51529
Signed-off-by: Daniel Lehman dlehman25@gmail.com
--- the CloseHandle docs say Windows will return error and throw exception for bogus or pseudo handle: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-cl...
but the docs for GetCurrentProcess/Thread say closing a pseudo handle has no effect https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-proc... https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-proc...
looks like behavior changed at Windows 10
--- dlls/ntdll/tests/exception.c | 8 -------- dlls/ntdll/unix/server.c | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 8af8d6b70da..42722e7b952 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -1223,7 +1223,6 @@ static void test_debugger(DWORD cont_status) } else if (stage == 13) { - todo_wine ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); continuestatus = DBG_EXCEPTION_NOT_HANDLED; } @@ -3923,7 +3922,6 @@ static void test_debugger(DWORD cont_status) } else if (stage == 13) { - todo_wine ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); continuestatus = DBG_EXCEPTION_NOT_HANDLED; } @@ -6627,7 +6625,6 @@ static void test_debugger(DWORD cont_status) } else if (stage == 13) { - todo_wine ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); continuestatus = DBG_EXCEPTION_NOT_HANDLED; } @@ -7881,7 +7878,6 @@ static void test_debugger(DWORD cont_status) } else if (stage == 13) { - todo_wine ok(FALSE || broken(TRUE) /* < Win10 */, "should not throw exception\n"); continuestatus = DBG_EXCEPTION_NOT_HANDLED; } @@ -8624,24 +8620,20 @@ static void test_closehandle(DWORD numexc, HANDLE handle) ret = CloseHandle(handle); ok(expectret || (GetLastError() == ERROR_INVALID_HANDLE), "CloseHandle had wrong GetLastError(), got %lu for %p\n", GetLastError(), handle); - todo_wine_if(is_magic_handle(handle)) { ok(ret == expectret || broken(HandleToLong(handle) < 0) /* < Win10 */, "CloseHandle expected %d, got %d for %p\n", expectret, ret, handle); ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ "CloseHandle generated %ld exceptions, expected %ld for %p\n", invalid_handle_exceptions, numexc, handle); - }
invalid_handle_exceptions = 0; expect = expectret ? STATUS_SUCCESS : STATUS_INVALID_HANDLE; status = pNtClose(handle); - todo_wine_if(is_magic_handle(handle)) { ok(status == expect || broken(HandleToLong(handle) < 0), /* < Win10 */ "NtClose returned unexpected status %#lx, expected %#lx for %p\n", status, expect, handle); ok(invalid_handle_exceptions == numexc || broken(!numexc && is_magic_handle(handle)), /* < Win10 */ "CloseHandle generated %ld exceptions, expected %ld for %p\n", invalid_handle_exceptions, numexc, handle); - }
pRtlRemoveVectoredExceptionHandler(vectored_handler); } diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index ab9d99c4f47..77e8d5c7566 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1704,6 +1704,9 @@ NTSTATUS WINAPI NtClose( HANDLE handle ) NTSTATUS ret; int fd;
+ if (HandleToLong( handle ) >= ~5 && HandleToLong( handle ) <= ~0) + return STATUS_SUCCESS; + server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
/* always remove the cached fd; if the server request fails we'll just
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111815
Your paranoid android.
=== debian11 (32 bit Hebrew:Israel report) ===
ntdll: exception.c:8937: Test failed: Wait failed.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111813
Your paranoid android.
=== debian11 (64 bit WoW report) ===
Report validation errors: ntdll:exception prints too much data (35604 bytes)