ReactOS 0.4.17-dev-573-g8315b8c
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)
 
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:523
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 371 of file NtQueryInformationThread.c.

375{
376 BOOL bEmptyName = ((TestName == (PCWSTR)(ULONG_PTR)-1) || !TestName || !*TestName);
377 ULONG ExpectedNameLength = (ULONG)(bEmptyName ? 0 : wcslen(TestName) * sizeof(WCHAR));
378 ULONG ExpectedLength = sizeof(UNICODE_STRING) + ExpectedNameLength;
379
382 PTHREAD_NAME_INFORMATION pNameInfo;
383 /* IMPORTANT REMARK: The fixed Buffer is made large enough
384 * to hold all the TestName's being tested in this file. */
385 struct { THREAD_NAME_INFORMATION Info; WCHAR Buffer[MAX_PATH]; } NameInfo;
386
387 ASSERT(sizeof(NameInfo.Buffer) >= ExpectedNameLength);
388
389 winetest_push_context("Test %lu", i);
390
391 /* Set a new thread name only if it's not '-1'; otherwise we
392 * just query the existing name without setting it before. */
393 if (TestName != (PCWSTR)(ULONG_PTR)-1)
394 {
395 /* Set a non-empty thread name, to reset it to something different
396 * from the previous case and distinguish with the next one. */
397 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xEF);
398 NameInfo.Info.ThreadName.Length = NameInfo.Info.ThreadName.MaximumLength = sizeof(NameInfo.Buffer);
399 NameInfo.Info.ThreadName.Buffer = NameInfo.Buffer;
401 &NameInfo.Info, sizeof(NameInfo.Info));
403
404 /* Now set the thread name to be tested */
405 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
406 RtlInitUnicodeString(&NameInfo.Info.ThreadName, TestName);
408 &NameInfo.Info, sizeof(NameInfo.Info));
410 }
411
412 /* Verify that ThreadNameInformation call with NULL buffer returns the expected length */
413 Length = 0;
416 ok_long(Length, ExpectedLength);
417
418 pNameInfo = &NameInfo.Info;
419
420 /* Test ThreadNameInformation call with minimally-sized buffer */
421 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
422 Length = 0;
424 pNameInfo, sizeof(*pNameInfo), &Length);
425 if (bEmptyName)
426 {
428 ok_long(Length, ExpectedLength); // == sizeof(UNICODE_STRING);
429 ok_long((ULONG)pNameInfo->ThreadName.Length, 0);
430 }
431 else
432 {
434 ok_long(Length, ExpectedLength); // == sizeof(UNICODE_STRING) + ExpectedNameLength;
435 ok_long((ULONG)pNameInfo->ThreadName.Length, 0xABAB);
436 }
437 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
438 if (bEmptyName)
439 {
440 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
441 /* All Win10+ versions erroneously point the Buffer past the end of the data */
442 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
443 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
444 /* NOTE: pNameInfo->ThreadName.Buffer[0] is invalid */
445 }
446 else
447 {
448 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(ULONG_PTR)0xABABABABABABABABULL);
449 }
450
451 RtlFillMemory(&NameInfo, sizeof(NameInfo), 0xAB);
452 Length = 0;
453 if (bEmptyName)
454 {
455 /* Retest the same with a slightly-larger buffer */
457 &NameInfo,
458 sizeof(UNICODE_STRING) + sizeof(UNICODE_NULL),
459 &Length);
460 }
461 else
462 {
463 /* Test direct ThreadNameInformation call with correctly-sized buffer */
465 &NameInfo,
466 ExpectedLength,
467 &Length);
468 }
470 ok_long(Length, ExpectedLength);
471 ok_long((ULONG)pNameInfo->ThreadName.Length, ExpectedNameLength);
472 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
473 if (bEmptyName)
474 {
475 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
476 /* All Win10+ versions erroneously point the Buffer past the end of the data */
477 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
478 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
479
480 /* NOTE: pNameInfo->ThreadName.Buffer[0] should be invalid, but let's
481 * check past it to see what data there is (in the "broken" Windows case). */
482 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
483 ok_wchar(pNameInfo->ThreadName.Buffer[0], 0xABAB);
484 }
485 else
486 {
487 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(&pNameInfo->ThreadName + 1));
488 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
489 ok_nwstr(pNameInfo->ThreadName.Buffer, TestName, ExpectedNameLength / sizeof(WCHAR));
490 else
491 skip("pNameInfo->ThreadName.Buffer is invalid (0x%p)\n", pNameInfo->ThreadName.Buffer);
492 }
493
494 /* Test ThreadNameInformation with dynamically allocated buffer */
495 pNameInfo = NULL;
496 Length = 0;
497 Status = ntGetThreadName(hThread, &pNameInfo, &Length, 0xCD);
499 ok_long(Length, ExpectedLength);
500 ok(pNameInfo != NULL, "Expected not NULL, got NULL\n");
501 if (pNameInfo)
502 {
503 ok_long((ULONG)pNameInfo->ThreadName.Length, ExpectedNameLength);
504 ok_long((ULONG)pNameInfo->ThreadName.MaximumLength, (ULONG)pNameInfo->ThreadName.Length);
505 if (bEmptyName)
506 {
507 ok(pNameInfo->ThreadName.Buffer == NULL || /* ReactOS will set the Buffer to NULL */
508 /* All Win10+ versions erroneously point the Buffer past the end of the data */
509 broken(pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1)),
510 "Expected NULL pointer, got 0x%p\n", pNameInfo->ThreadName.Buffer);
511 /* NOTE: pNameInfo->ThreadName.Buffer[0] is invalid */
512 }
513 else
514 {
515 ok_ptr(pNameInfo->ThreadName.Buffer, (PVOID)(&pNameInfo->ThreadName + 1));
516 if (pNameInfo->ThreadName.Buffer == (PVOID)(&pNameInfo->ThreadName + 1))
517 ok_nwstr(pNameInfo->ThreadName.Buffer, TestName, ExpectedNameLength / sizeof(WCHAR));
518 else
519 skip("pNameInfo->ThreadName.Buffer is invalid (0x%p)\n", pNameInfo->ThreadName.Buffer);
520 }
521 RtlFreeHeap(RtlGetProcessHeap(), 0, pNameInfo);
522 }
523 else
524 {
525 skip("pNameInfo is NULL\n");
526 }
527
529}
#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:2988
struct _UNICODE_STRING UNICODE_STRING
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:24
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:1084
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:5372
_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 316 of file NtQueryInformationThread.c.

321{
323 PVOID ptr;
326
327 *ppThreadNameInfo = NULL;
328 *pLength = 0;
329
330 /* Since there may be concurrent SetThreadDescription() invocations being
331 * executed, we need to loop over the buffer allocation size until we can
332 * successfully capture the thread name. */
333 Length = 0;
336 return Status;
337
338 /* Loop again only if we get buffer-too-small types of errors;
339 * otherwise, break the loop: any error will be handled below. */
342 {
343 /* (Re-)allocate the information buffer */
344 ptr = (NameInfo ? RtlReAllocateHeap(RtlGetProcessHeap(), 0, NameInfo, Length)
345 : RtlAllocateHeap(RtlGetProcessHeap(), 0, Length));
346 if (!ptr)
347 {
349 break;
350 }
352 NameInfo = ptr;
354 NameInfo, Length, &Length);
355 // Status should be STATUS_SUCCESS, unless concurrent SetThreadDescription() happens.
356 }
357 if (NT_SUCCESS(Status))
358 {
359 *ppThreadNameInfo = NameInfo;
360 *pLength = Length;
361 }
362 else
363 {
364 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInfo);
365 }
366
367 return Status;
368}
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:286
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{
623#if 0 // This test is too broken
625#endif
627}
static void Test_ThreadHideFromDebuggerClass(void)
static void Test_ThreadBasicInformationClass(void)
static void Test_ThreadNameInformation(void)
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:1145

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:3420
@ 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 533 of file NtQueryInformationThread.c.

534{
535 ULONG NTDDIVersion;
537 HANDLE hWaitEvent = NULL, hThread = NULL;
538
539 OSVERSIONINFOEXW osVerInfo;
540 osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
541 GetVersionExW((LPOSVERSIONINFOW)&osVerInfo);
542 trace("osVerInfo: %lu.%lu.%lu ('%S')\n",
543 osVerInfo.dwMajorVersion,
544 osVerInfo.dwMinorVersion,
545 osVerInfo.dwBuildNumber,
546 osVerInfo.szCSDVersion);
547
548 NTDDIVersion = GetNTDDIVersion();
549 trace("NTDDIVersion: 0x%08lx\n", NTDDIVersion);
550 if (!is_reactos() && NTDDIVersion < NTDDI_WIN10_RS1)
551 {
552 skip("Skipping %s on NT %hu.%hu(.%hu), because it is not supported.\n",
554 (NTDDIVersion & 0xFF000000) >> 24,
555 (NTDDIVersion & 0x00FF0000) >> 16,
556 (NTDDIVersion & 0x000000FF));
557 return;
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 is_reactos()
Definition: kmt_test.h:534
#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()

void Test_ThreadQueryAlignmentProbe ( void  )

Definition at line 282 of file NtQueryInformationThread.c.

283{
284 ULONG InfoClass;
285
286 /* Iterate over the process info classes and begin the tests */
287 for (InfoClass = 0; InfoClass < _countof(PsThreadInfoClass); InfoClass++)
288 {
289 /* The buffer is misaligned */
291 InfoClass,
292 (PVOID)(ULONG_PTR)1,
293 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
295
296 /* We query an invalid buffer address */
298 InfoClass,
299 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
300 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
302
303 /* The information length is wrong */
305 InfoClass,
306 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
307 PsThreadInfoClass[InfoClass].RequiredSizeQUERY - 1,
309 }
310}
@ 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().