diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index cf3f7b9f6f2..eaf2f1a45b7 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -2346,6 +2346,7 @@ static void test_affinity(void) DWORD_PTR proc_affinity, thread_affinity; THREAD_BASIC_INFORMATION tbi; SYSTEM_INFO si; + ULONG dummy; GetSystemInfo(&si); status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL ); @@ -2450,6 +2451,32 @@ static void test_affinity(void) ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( tbi.AffinityMask == (1 << si.dwNumberOfProcessors) - 1, "Unexpected thread affinity\n" ); + + dummy = 0; + status = pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger, &dummy, sizeof(ULONG) ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status ); + dummy = 0; + status = pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger, &dummy, 1 ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status ); + status = pNtSetInformationThread( (HANDLE)0xdeadbeef, ThreadHideFromDebugger, NULL, 0 ); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status ); + status = pNtSetInformationThread( GetCurrentThread(), ThreadHideFromDebugger, NULL, 0 ); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); + dummy = 0; + status = NtQueryInformationThread( GetCurrentThread(), ThreadHideFromDebugger, &dummy, sizeof(ULONG), NULL ); + if (status == STATUS_INVALID_INFO_CLASS) + win_skip("ThreadHideFromDebugger not available\n"); + else + { + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status ); + dummy = 0; + status = NtQueryInformationThread( (HANDLE)0xdeadbeef, ThreadHideFromDebugger, &dummy, sizeof(ULONG), NULL ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status ); + dummy = 0; + status = NtQueryInformationThread( GetCurrentThread(), ThreadHideFromDebugger, &dummy, 1, NULL ); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); + if (status == STATUS_SUCCESS) ok( dummy == 1, "Expected dummy == 1, got %08x\n", dummy ); + } } static void test_NtGetCurrentProcessorNumber(void) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index d26e0a98cac..2e2e5a3882d 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -831,6 +831,8 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, { NTSTATUS status; + TRACE("(%p,%d,%p,%x,%p)\n", handle, class, data, length, ret_len); + switch (class) { case ThreadBasicInformation: @@ -1063,6 +1065,14 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, #endif } + case ThreadHideFromDebugger: + if (length != sizeof(BOOLEAN)) return STATUS_INFO_LENGTH_MISMATCH; + if (!data) return STATUS_ACCESS_VIOLATION; + if (handle != GetCurrentThread()) return STATUS_ACCESS_DENIED; + *(BOOLEAN*)data = TRUE; + if (ret_len) *ret_len = sizeof(BOOLEAN); + return STATUS_SUCCESS; + case ThreadPriority: case ThreadBasePriority: case ThreadImpersonationToken: @@ -1088,6 +1098,8 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, { NTSTATUS status; + TRACE("(%p,%d,%p,%x)\n", handle, class, data, length); + switch (class) { case ThreadZeroTlsCell: @@ -1152,6 +1164,8 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, } case ThreadHideFromDebugger: + if (length) return STATUS_INFO_LENGTH_MISMATCH; + if (handle != GetCurrentThread()) return STATUS_INVALID_HANDLE; /* pretend the call succeeded to satisfy some code protectors */ return STATUS_SUCCESS;