ReactOS 0.4.16-dev-2613-g9533ad7
NtQueryInformationThread.c File Reference
#include "precomp.h"
#include <internal/ps_i.h>
Include dependency graph for NtQueryInformationThread.c:

Go to the source code of this file.

Macros

#define ok_wchar(x, y)   ok_hex((unsigned)(unsigned short)(x), (unsigned)(unsigned short)(y))
 
#define ok_nwstr(str1, str2, count)
 

Functions

static void Test_ThreadBasicInformationClass (void)
 
static ULONG NTAPI DummyThread (_In_ PVOID Parameter)
 Dummy thread used by the Test_ThreadHideFromDebuggerClass() and the Test_ThreadNameInformation() API tests.
 
static void Test_ThreadHideFromDebuggerClass (void)
 
static void Test_ThreadQueryAlignmentProbe (void)
 
static NTSTATUS ntGetThreadName (_In_ HANDLE hThread, _Outptr_ PTHREAD_NAME_INFORMATION *ppThreadNameInfo, _Out_ PULONG pLength, _In_ UCHAR Fill)
 An NT-equivalent of kernel32!GetThreadDescription().
 
static void DoThreadNameTest (_In_ UINT i, _In_ HANDLE hThread, _In_opt_ PCWSTR TestName)
 
static void Test_ThreadNameInformation (void)
 
 START_TEST (NtQueryInformationThread)
 

Macro Definition Documentation

◆ ok_nwstr

#define ok_nwstr (   str1,
  str2,
  count 
)
Value:
ok(wcsncmp((PWCHAR)(str1), (PWCHAR)(str2), (count)) == 0, \
"Wrong string. Expected '%.*S', got '%.*S'\n", (count), (str1), (count), (str2))
#define ok(value,...)
Definition: atltest.h:57
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
GLuint GLuint GLsizei count
Definition: gl.h:1545
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
uint16_t * PWCHAR
Definition: typedefs.h:56

Definition at line 14 of file NtQueryInformationThread.c.

◆ ok_wchar

#define ok_wchar (   x,
  y 
)    ok_hex((unsigned)(unsigned short)(x), (unsigned)(unsigned short)(y))

Definition at line 12 of file NtQueryInformationThread.c.

Function Documentation

◆ DoThreadNameTest()

static void DoThreadNameTest ( _In_ UINT  i,
_In_ HANDLE  hThread,
_In_opt_ PCWSTR  TestName 
)
static

Definition at line 372 of file NtQueryInformationThread.c.

376{
377 BOOL bEmptyName = ((TestName == (PCWSTR)(ULONG_PTR)-1) || !TestName || !*TestName);
378 ULONG ExpectedNameLength = (ULONG)(bEmptyName ? 0 : wcslen(TestName) * sizeof(WCHAR));
379 ULONG ExpectedLength = sizeof(UNICODE_STRING) + ExpectedNameLength;
380
383 PTHREAD_NAME_INFORMATION pNameInfo;
384 /* IMPORTANT REMARK: The fixed Buffer is made large enough
385 * to hold all the TestName's being tested in this file. */
386 struct { THREAD_NAME_INFORMATION Info; WCHAR Buffer[MAX_PATH]; } NameInfo;
387
388 ASSERT(sizeof(NameInfo.Buffer) >= ExpectedNameLength);
389
390 winetest_push_context("Test %lu", i);
391
392 /* Set a new thread name only if it's not '-1'; otherwise we
393 * just query the existing name without setting it before. */
394 if (TestName != (PCWSTR)(ULONG_PTR)-1)
395 {
396 /* Set a non-empty thread name, to reset it to something different
397 * from the previous case and distinguish with the next one. */
398 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xEF);
399 NameInfo.Info.ThreadName.Length = NameInfo.Info.ThreadName.MaximumLength = sizeof(NameInfo.Buffer);
400 NameInfo.Info.ThreadName.Buffer = NameInfo.Buffer;
402 &NameInfo.Info, sizeof(NameInfo.Info));
404
405 /* Now set the thread name to be tested */
406 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
407 RtlInitUnicodeString(&NameInfo.Info.ThreadName, TestName);
409 &NameInfo.Info, sizeof(NameInfo.Info));
411 }
412
413 /* Verify that ThreadNameInformation call with NULL buffer returns the expected length */
414 Length = 0;
417 ok_long(Length, ExpectedLength);
418
419 pNameInfo = &NameInfo.Info;
420
421 /* Test ThreadNameInformation call with minimally-sized buffer */
422 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
423 Length = 0;
425 pNameInfo, sizeof(*pNameInfo), &Length);
426 if (bEmptyName)
427 {
429 ok_long(Length, ExpectedLength); // == sizeof(UNICODE_STRING);
430 ok_long((ULONG)pNameInfo->ThreadName.Length, 0);
431 }
432 else
433 {
435 ok_long(Length, ExpectedLength); // == sizeof(UNICODE_STRING) + ExpectedNameLength;
436 ok_long((ULONG)pNameInfo->ThreadName.Length, 0xABAB);
437 }
438 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
439 if (bEmptyName)
440 {
441 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
442 /* All Win10+ versions erroneously point the Buffer past the end of the data */
443 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
444 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
445 /* NOTE: pNameInfo->ThreadName.Buffer[0] is invalid */
446 }
447 else
448 {
449 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(ULONG_PTR)0xABABABABABABABABULL);
450 }
451
452 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
453 Length = 0;
454 if (bEmptyName)
455 {
456 /* Retest the same with a slightly-larger buffer */
458 &NameInfo,
459 sizeof(UNICODE_STRING) + sizeof(UNICODE_NULL),
460 &Length);
461 }
462 else
463 {
464 /* Test direct ThreadNameInformation call with correctly-sized buffer */
466 &NameInfo,
467 ExpectedLength,
468 &Length);
469 }
471 ok_long(Length, ExpectedLength);
472 ok_long((ULONG)pNameInfo->ThreadName.Length, ExpectedNameLength);
473 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
474 if (bEmptyName)
475 {
476 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
477 /* All Win10+ versions erroneously point the Buffer past the end of the data */
478 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
479 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
480
481 /* NOTE: pNameInfo->ThreadName.Buffer[0] should be invalid, but let's
482 * check past it to see what data there is (in the "broken" Windows case). */
483 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
484 ok_wchar(pNameInfo->ThreadName.Buffer[0], 0xABAB);
485 }
486 else
487 {
488 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(&pNameInfo->ThreadName + 1));
489 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
490 ok_nwstr(pNameInfo->ThreadName.Buffer, TestName, ExpectedNameLength / sizeof(WCHAR));
491 else
492 skip("pNameInfo->ThreadName.Buffer is invalid (0x%p)\n", pNameInfo->ThreadName.Buffer);
493 }
494
495 /* Test ThreadNameInformation with dynamically allocated buffer */
496 pNameInfo = NULL;
497 Length = 0;
498 Status = ntGetThreadName(hThread, &pNameInfo, &Length, 0xCD);
500 ok_long(Length, ExpectedLength);
501 ok(pNameInfo != NULL, "Expected not NULL, got NULL\n");
502 if (pNameInfo)
503 {
504 ok_long((ULONG)pNameInfo->ThreadName.Length, ExpectedNameLength);
505 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
506 if (bEmptyName)
507 {
508 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
509 /* All Win10+ versions erroneously point the Buffer past the end of the data */
510 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
511 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
512 /* NOTE: pNameInfo->ThreadName.Buffer[0] is invalid */
513 }
514 else
515 {
516 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(&pNameInfo->ThreadName + 1));
517 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
518 ok_nwstr(pNameInfo->ThreadName.Buffer, TestName, ExpectedNameLength / sizeof(WCHAR));
519 else
520 skip("pNameInfo->ThreadName.Buffer is invalid (0x%p)\n", pNameInfo->ThreadName.Buffer);
521 }
522 RtlFreeHeap(RtlGetProcessHeap(), 0, pNameInfo);
523 }
524 else
525 {
526 skip("pNameInfo is NULL\n");
527 }
528
530}
#define ok_nwstr(str1, str2, count)
static NTSTATUS ntGetThreadName(_In_ HANDLE hThread, _Outptr_ PTHREAD_NAME_INFORMATION *ppThreadNameInfo, _Out_ PULONG pLength, _In_ UCHAR Fill)
An NT-equivalent of kernel32!GetThreadDescription().
#define ok_wchar(x, y)
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define ok_long(expression, result)
Definition: atltest.h:133
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define ok_ptr(expression, result)
Definition: atltest.h:108
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
struct _UNICODE_STRING UNICODE_STRING
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define ASSERT(a)
Definition: mode.c:44
WCHAR TestName[MAX_PATH]
Definition: main.cpp:13
HANDLE hThread
Definition: wizard.c:28
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:2985
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2269
short WCHAR
Definition: pedump.c:58
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
UNICODE_STRING ThreadName
Definition: pstypes.h:1090
USHORT MaximumLength
Definition: env_spec_w32.h:370
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
@ ThreadNameInformation
Definition: winternl.h:2319

Referenced by Test_ThreadNameInformation().

◆ DummyThread()

static ULONG NTAPI DummyThread ( _In_ PVOID  Parameter)
static

Dummy thread used by the Test_ThreadHideFromDebuggerClass() and the Test_ThreadNameInformation() API tests.

Parameters
[in]ParameterHandle to an event that tells the thread to terminate itself when signaled.

Definition at line 121 of file NtQueryInformationThread.c.

123{
124 HANDLE hWaitEvent = (HANDLE)Parameter;
126
127 /* Indefinitely wait for the kill signal */
128 Status = NtWaitForSingleObject(hWaitEvent, FALSE, NULL);
130
132 return Status;
133}
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1287
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
PVOID HANDLE
Definition: typedefs.h:73
#define NtCurrentThread()
Definition: winternl.h:5368
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by Test_ThreadHideFromDebuggerClass(), and Test_ThreadNameInformation().

◆ ntGetThreadName()

static NTSTATUS ntGetThreadName ( _In_ HANDLE  hThread,
_Outptr_ PTHREAD_NAME_INFORMATION ppThreadNameInfo,
_Out_ PULONG  pLength,
_In_ UCHAR  Fill 
)
static

An NT-equivalent of kernel32!GetThreadDescription().

Definition at line 317 of file NtQueryInformationThread.c.

322{
324 PVOID ptr;
327
328 *ppThreadNameInfo = NULL;
329 *pLength = 0;
330
331 /* Since there may be concurrent SetThreadDescription() invocations being
332 * executed, we need to loop over the buffer allocation size until we can
333 * successfully capture the thread name. */
334 Length = 0;
337 return Status;
338
339 /* Loop again only if we get buffer-too-small types of errors;
340 * otherwise, break the loop: any error will be handled below. */
343 {
344 /* (Re-)allocate the information buffer */
345 ptr = (NameInfo ? RtlReAllocateHeap(RtlGetProcessHeap(), 0, NameInfo, Length)
346 : RtlAllocateHeap(RtlGetProcessHeap(), 0, Length));
347 if (!ptr)
348 {
350 break;
351 }
353 NameInfo = ptr;
355 NameInfo, Length, &Length);
356 // Status should be STATUS_SUCCESS, unless concurrent SetThreadDescription() happens.
357 }
358 if (NT_SUCCESS(Status))
359 {
360 *ppThreadNameInfo = NameInfo;
361 *pLength = Length;
362 }
363 else
364 {
365 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInfo);
366 }
367
368 return Status;
369}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
void Fill(HDC hdc, LONG x, LONG y, COLORREF color)
Definition: drawing.cpp:107
static PVOID ptr
Definition: dispmode.c:27
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap

Referenced by DoThreadNameTest().

◆ START_TEST()

START_TEST ( NtQueryInformationThread  )

Definition at line 619 of file NtQueryInformationThread.c.

620{
625}
static void Test_ThreadHideFromDebuggerClass(void)
static void Test_ThreadBasicInformationClass(void)
static void Test_ThreadNameInformation(void)
static void Test_ThreadQueryAlignmentProbe(void)

◆ Test_ThreadBasicInformationClass()

static void Test_ThreadBasicInformationClass ( void  )
static

Definition at line 20 of file NtQueryInformationThread.c.

21{
23 PTHREAD_BASIC_INFORMATION ThreadInfoBasic;
25
27 if (!ThreadInfoBasic)
28 {
29 skip("Failed to allocate memory for THREAD_BASIC_INFORMATION!\n");
30 return;
31 }
32
33 /* Everything is NULL */
36 NULL,
37 0,
38 NULL);
40
41 /* Don't give a valid thread handle */
44 ThreadInfoBasic,
46 NULL);
48
49 /* The information length is incorrect */
52 ThreadInfoBasic,
53 0,
54 NULL);
56
57 /* Don't query anything from the function */
60 NULL,
62 NULL);
64
65 /* The buffer is misaligned and length information is wrong */
68 (PVOID)1,
69 0,
70 NULL);
72
73 /* The buffer is misaligned */
76 (PVOID)1,
78 NULL);
80
81 /* The buffer is misaligned, try with an alignment size of 2 */
84 (PVOID)2,
86 NULL);
88
89 /* Query the basic information we need from the thread */
92 ThreadInfoBasic,
96 ok(ReturnedLength != 0, "The size of the buffer pointed by ThreadInformation shouldn't be 0!\n");
97
98 /* Output the thread basic information details */
99 trace("ReturnedLength = %lu\n", ReturnedLength);
100 trace("ThreadInfoBasic->ExitStatus = 0x%08lx\n", ThreadInfoBasic->ExitStatus);
101 trace("ThreadInfoBasic->TebBaseAddress = %p\n", ThreadInfoBasic->TebBaseAddress);
102 trace("ThreadInfoBasic->ClientId.UniqueProcess = %p\n", ThreadInfoBasic->ClientId.UniqueProcess);
103 trace("ThreadInfoBasic->ClientId.UniqueThread = %p\n", ThreadInfoBasic->ClientId.UniqueThread);
104 trace("ThreadInfoBasic->AffinityMask = %lu\n", ThreadInfoBasic->AffinityMask);
105 trace("ThreadInfoBasic->Priority = %li\n", ThreadInfoBasic->Priority);
106 trace("ThreadInfoBasic->BasePriority = %li\n", ThreadInfoBasic->BasePriority);
107
108 HeapFree(GetProcessHeap(), 0, ThreadInfoBasic);
109}
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
@ ThreadBasicInformation
Definition: compat.h:935
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define STATUS_ACCESS_VIOLATION
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:263
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
KPRIORITY BasePriority
Definition: compat.h:932
KAFFINITY AffinityMask
Definition: compat.h:930
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1146

Referenced by START_TEST().

◆ Test_ThreadHideFromDebuggerClass()

static void Test_ThreadHideFromDebuggerClass ( void  )
static

Definition at line 137 of file NtQueryInformationThread.c.

138{
140 HANDLE hWaitEvent = NULL, hThread = NULL;
141 BOOLEAN IsThreadHidden;
142 ULONG UlongData;
144
146 {
147 skip("Skipping test as NtQueryInformationThread(ThreadHideFromDebugger) isn't supported prior to Vista\n");
148 return;
149 }
151
152 Status = NtCreateEvent(&hWaitEvent,
154 NULL,
156 FALSE);
158 ok(hWaitEvent != NULL, "Expected not NULL, got NULL\n");
159 if (!NT_SUCCESS(Status))
160 {
161 skip("Could not create the stop event! (Status 0x%08lx)\n", Status);
162 goto Quit;
163 }
164
165 /* Create the dummy thread and wait for it to start up */
167 NULL,
168 FALSE,
169 0,
170 0,
171 0,
173 (PVOID)hWaitEvent,
174 &hThread,
175 NULL);
177 ok(hThread != NULL, "Expected not NULL, got NULL\n");
178 if (!NT_SUCCESS(Status))
179 {
180 skip("Failed to create the dummy thread (Status 0x%08lx)\n", Status);
181 goto Quit;
182 }
183
184
185 /* Verify that the thread is debuggable by default */
186 IsThreadHidden = 0xCC;
189 &IsThreadHidden,
190 sizeof(IsThreadHidden),
191 NULL);
193 ok_bool_false(IsThreadHidden, "IsThreadHidden is");
194
195 /* Make the thread hidden from the debugger -- The wrong way (1) */
196 IsThreadHidden = TRUE;
199 &IsThreadHidden,
200 sizeof(IsThreadHidden));
201 if (IsWow64)
203 else
205
206 /* The thread is still debuggable */
207 IsThreadHidden = 0xCC;
210 &IsThreadHidden,
211 sizeof(IsThreadHidden),
212 NULL);
214 ok_bool_false(IsThreadHidden, "IsThreadHidden is");
215
216 /* Make the thread hidden from the debugger -- The wrong way (2) */
217 UlongData = TRUE;
220 &UlongData,
221 sizeof(UlongData));
223
224 /* The thread is still debuggable */
225 IsThreadHidden = 0xCC;
228 &IsThreadHidden,
229 sizeof(IsThreadHidden),
230 NULL);
232 ok_bool_false(IsThreadHidden, "IsThreadHidden is");
233
234 /* Make the thread hidden from the debugger -- The wrong way (3) */
235 UlongData = TRUE;
238 &UlongData,
239 sizeof(BOOLEAN));
241
242 /* The thread is still debuggable */
243 IsThreadHidden = 0xCC;
246 &IsThreadHidden,
247 sizeof(IsThreadHidden),
248 NULL);
250 ok_bool_false(IsThreadHidden, "IsThreadHidden is");
251
252 /* Make the thread hidden from the debugger -- This way works! */
255 NULL, 0);
257
258 /* Verify that the thread is now hidden from the debugger */
259 IsThreadHidden = 0xCC;
262 &IsThreadHidden,
263 sizeof(IsThreadHidden),
264 NULL);
266 ok_bool_true(IsThreadHidden, "IsThreadHidden is");
267
268
269 /* Send the kill signal and wait for the thread to terminate */
270 NtSetEvent(hWaitEvent, NULL);
272 /* Close the thread */
275Quit:
276 /* Close the event */
277 if (hWaitEvent)
278 NtClose(hWaitEvent);
279}
static ULONG NTAPI DummyThread(_In_ PVOID Parameter)
Dummy thread used by the Test_ThreadHideFromDebuggerClass() and the Test_ThreadNameInformation() API ...
#define IsWow64()
Definition: NtReadFile.c:37
unsigned char BOOLEAN
Definition: actypes.h:127
#define GetNTVersion()
Definition: apitest.h:17
#define ok_bool_false(value, desc)
Definition: apitest.h:136
#define ok_bool_true(value, desc)
Definition: apitest.h:135
#define TRUE
Definition: types.h:120
@ ThreadHideFromDebugger
Definition: compat.h:952
#define GetCurrentProcess()
Definition: compat.h:759
#define IsWow64Process
Definition: compat.h:760
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
@ NotificationEvent
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:463
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25

Referenced by START_TEST().

◆ Test_ThreadNameInformation()

static void Test_ThreadNameInformation ( void  )
static

Definition at line 534 of file NtQueryInformationThread.c.

535{
536 ULONG NTDDIVersion;
538 HANDLE hWaitEvent = NULL, hThread = NULL;
539
540 OSVERSIONINFOEXW osVerInfo;
541 osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
542 GetVersionExW((LPOSVERSIONINFOW)&osVerInfo);
543 trace("osVerInfo: %lu.%lu.%lu ('%S')\n",
544 osVerInfo.dwMajorVersion,
545 osVerInfo.dwMinorVersion,
546 osVerInfo.dwBuildNumber,
547 osVerInfo.szCSDVersion);
548
549 NTDDIVersion = GetNTDDIVersion();
550 trace("NTDDIVersion: 0x%08lx\n", NTDDIVersion);
551 if (NTDDIVersion < NTDDI_WIN10_RS1)
552 {
553 trace("Running %s on NT %hu.%hu(.%hu), it may not work!\n",
555 (NTDDIVersion & 0xFF000000) >> 24,
556 (NTDDIVersion & 0x00FF0000) >> 16,
557 (NTDDIVersion & 0x000000FF));
558 }
559
560 Status = NtCreateEvent(&hWaitEvent,
562 NULL,
564 FALSE);
566 ok(hWaitEvent != NULL, "Expected not NULL, got NULL\n");
567 if (!NT_SUCCESS(Status))
568 {
569 skip("Could not create the stop event! (Status 0x%08lx)\n", Status);
570 goto Quit;
571 }
572
573 /* Create the dummy thread and wait for it to start up */
575 NULL,
576 FALSE,
577 0,
578 0,
579 0,
581 (PVOID)hWaitEvent,
582 &hThread,
583 NULL);
585 ok(hThread != NULL, "Expected not NULL, got NULL\n");
586 if (!NT_SUCCESS(Status))
587 {
588 skip("Failed to create the dummy thread (Status 0x%08lx)\n", Status);
589 goto Quit;
590 }
591
592 /* EXPECTATION: Initial thread name is empty. */
594
595 /* Set a non-empty thread name.
596 * EXPECTATION: Thread name is what we have set. */
597 DoThreadNameTest(2, hThread, L"Hello World!");
598
599 /* Set an empty-string thread name.
600 * EXPECTATION: Thread name is empty. */
602
603 /* Set a NULL-pointer empty-string thread name.
604 * EXPECTATION: Thread name is empty. */
606
607 /* Send the kill signal and wait for the thread to terminate */
608 NtSetEvent(hWaitEvent, NULL);
610 /* Close the thread */
613Quit:
614 /* Close the event */
615 if (hWaitEvent)
616 NtClose(hWaitEvent);
617}
static void DoThreadNameTest(_In_ UINT i, _In_ HANDLE hThread, _In_opt_ PCWSTR TestName)
static ULONG GetNTDDIVersion(VOID)
Definition: apitest.h:23
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
#define L(x)
Definition: resources.c:13
#define __FUNCTION__
Definition: types.h:116
#define NTDDI_WIN10_RS1
Definition: sdkddkver.h:119
WCHAR szCSDVersion[128]
Definition: rtltypes.h:274
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
ULONG dwBuildNumber
Definition: rtltypes.h:272

Referenced by START_TEST().

◆ Test_ThreadQueryAlignmentProbe()

static void Test_ThreadQueryAlignmentProbe ( void  )
static

Definition at line 283 of file NtQueryInformationThread.c.

284{
285 ULONG InfoClass;
286
287 /* Iterate over the process info classes and begin the tests */
288 for (InfoClass = 0; InfoClass < _countof(PsThreadInfoClass); InfoClass++)
289 {
290 /* The buffer is misaligned */
292 InfoClass,
293 (PVOID)(ULONG_PTR)1,
294 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
296
297 /* We query an invalid buffer address */
299 InfoClass,
300 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
301 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
303
304 /* The information length is wrong */
306 InfoClass,
307 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
308 PsThreadInfoClass[InfoClass].RequiredSizeQUERY - 1,
310 }
311}
@ QUERY
Definition: precomp.h:18
VOID QuerySetThreadValidator(_In_ ALIGNMENT_PROBE_MODE ValidationMode, _In_ ULONG InfoClassIndex, _In_ PVOID InfoPointer, _In_ ULONG InfoLength, _In_ NTSTATUS ExpectedStatus)
Definition: probelib.c:245
static const INFORMATION_CLASS_INFO PsThreadInfoClass[]
Definition: ps_i.h:362
#define _countof(array)
Definition: sndvol32.h:70

Referenced by START_TEST().