Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
602eb52c
Commit
602eb52c
authored
Nov 24, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Nov 25, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32/tests: Add some tests for thread description API.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1658d5a2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
140 additions
and
1 deletion
+140
-1
thread.c
dlls/kernel32/tests/thread.c
+132
-0
winternl.h
include/winternl.h
+8
-1
No files found.
dlls/kernel32/tests/thread.c
View file @
602eb52c
...
...
@@ -105,6 +105,8 @@ static NTSTATUS (WINAPI *pNtQueryInformationThread)(HANDLE,THREADINFOCLASS,PVOID
static
BOOL
(
WINAPI
*
pGetThreadGroupAffinity
)(
HANDLE
,
GROUP_AFFINITY
*
);
static
BOOL
(
WINAPI
*
pSetThreadGroupAffinity
)(
HANDLE
,
const
GROUP_AFFINITY
*
,
GROUP_AFFINITY
*
);
static
NTSTATUS
(
WINAPI
*
pNtSetInformationThread
)(
HANDLE
,
THREADINFOCLASS
,
LPCVOID
,
ULONG
);
static
HRESULT
(
WINAPI
*
pSetThreadDescription
)(
HANDLE
,
const
WCHAR
*
);
static
HRESULT
(
WINAPI
*
pGetThreadDescription
)(
HANDLE
,
WCHAR
**
);
static
HANDLE
create_target_process
(
const
char
*
arg
)
{
...
...
@@ -2111,6 +2113,133 @@ todo_wine
CloseHandle
(
thread
);
}
static
void
test_thread_description
(
void
)
{
THREAD_DESCRIPTION_INFORMATION
*
thread_desc
;
static
const
WCHAR
*
desc
=
L"thread_desc"
;
ULONG
len
,
len2
,
desc_len
;
NTSTATUS
status
;
char
buff
[
128
];
WCHAR
*
ptr
;
HRESULT
hr
;
if
(
!
pGetThreadDescription
)
{
skip
(
"Thread description API is not supported.
\n
"
);
return
;
}
desc_len
=
lstrlenW
(
desc
)
*
sizeof
(
*
desc
);
thread_desc
=
(
THREAD_DESCRIPTION_INFORMATION
*
)
buff
;
/* Initial description. */
ptr
=
NULL
;
hr
=
pGetThreadDescription
(
GetCurrentThread
(),
&
ptr
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to get thread description, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
ptr
,
L""
),
"Unexpected description %s.
\n
"
,
wine_dbgstr_w
(
ptr
));
LocalFree
(
ptr
);
len
=
0
;
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
NULL
,
0
,
&
len
);
ok
(
status
==
STATUS_BUFFER_TOO_SMALL
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
len
==
sizeof
(
*
thread_desc
),
"Unexpected structure length %u.
\n
"
,
len
);
len2
=
0
;
thread_desc
->
Length
=
1
;
thread_desc
->
Description
=
(
WCHAR
*
)
thread_desc
;
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
thread_desc
,
len
,
&
len2
);
ok
(
!
status
,
"Failed to get thread info, status %#x.
\n
"
,
status
);
ok
(
len2
==
sizeof
(
*
thread_desc
),
"Unexpected structure length %u.
\n
"
,
len
);
ok
(
!
thread_desc
->
Length
,
"Unexpected description length %#x.
\n
"
,
thread_desc
->
Length
);
ok
(
thread_desc
->
Description
==
(
WCHAR
*
)(
thread_desc
+
1
),
"Unexpected description string pointer %p, %p.
\n
"
,
thread_desc
->
Description
,
thread_desc
);
hr
=
pSetThreadDescription
(
GetCurrentThread
(),
NULL
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to set thread description, hr %#x.
\n
"
,
hr
);
hr
=
pSetThreadDescription
(
GetCurrentThread
(),
desc
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to set thread description, hr %#x.
\n
"
,
hr
);
ptr
=
NULL
;
hr
=
pGetThreadDescription
(
GetCurrentThread
(),
&
ptr
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to get thread description, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
ptr
,
desc
),
"Unexpected description %s.
\n
"
,
wine_dbgstr_w
(
ptr
));
LocalFree
(
ptr
);
len
=
0
;
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
NULL
,
0
,
&
len
);
ok
(
status
==
STATUS_BUFFER_TOO_SMALL
,
"Failed to get thread info, status %#x.
\n
"
,
status
);
ok
(
len
==
sizeof
(
*
thread_desc
)
+
desc_len
,
"Unexpected structure length %u.
\n
"
,
len
);
len
=
0
;
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
buff
,
sizeof
(
buff
),
&
len
);
ok
(
!
status
,
"Failed to get thread info.
\n
"
);
ok
(
len
==
sizeof
(
*
thread_desc
)
+
desc_len
,
"Unexpected structure length %u.
\n
"
,
len
);
ok
(
thread_desc
->
Length
==
(
desc_len
<<
16
|
desc_len
),
"Unexpected description length %#x.
\n
"
,
thread_desc
->
Length
);
ok
(
thread_desc
->
Description
==
(
WCHAR
*
)(
thread_desc
+
1
),
"Unexpected description string pointer %p, %p.
\n
"
,
thread_desc
->
Description
,
thread_desc
);
ok
(
!
memcmp
(
thread_desc
->
Description
,
desc
,
desc_len
),
"Unexpected description string.
\n
"
);
/* Partial results. */
len
=
0
;
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
NULL
,
0
,
&
len
);
ok
(
status
==
STATUS_BUFFER_TOO_SMALL
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
len
==
sizeof
(
*
thread_desc
)
+
desc_len
,
"Unexpected structure length %u.
\n
"
,
len
);
status
=
pNtQueryInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
buff
,
len
-
sizeof
(
WCHAR
),
&
len
);
ok
(
status
==
STATUS_BUFFER_TOO_SMALL
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
len
==
sizeof
(
*
thread_desc
)
+
desc_len
,
"Unexpected structure length %u.
\n
"
,
len
);
/* Change description. */
thread_desc
->
Length
=
8
<<
16
|
8
;
lstrcpyW
((
WCHAR
*
)(
thread_desc
+
1
),
L"desc"
);
status
=
pNtSetInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
thread_desc
,
sizeof
(
*
thread_desc
));
ok
(
status
==
STATUS_SUCCESS
,
"Failed to set thread description, status %#x.
\n
"
,
status
);
ptr
=
NULL
;
hr
=
pGetThreadDescription
(
GetCurrentThread
(),
&
ptr
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to get thread description, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
ptr
,
L"desc"
),
"Unexpected description %s.
\n
"
,
wine_dbgstr_w
(
ptr
));
LocalFree
(
ptr
);
status
=
pNtSetInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
thread_desc
,
sizeof
(
*
thread_desc
)
-
1
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Unexpected status %#x.
\n
"
,
status
);
status
=
NtSetInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
NULL
,
sizeof
(
*
thread_desc
));
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
"Unexpected status %#x.
\n
"
,
status
);
thread_desc
->
Description
=
NULL
;
status
=
pNtSetInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
thread_desc
,
sizeof
(
*
thread_desc
));
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
"Unexpected status %#x.
\n
"
,
status
);
hr
=
pSetThreadDescription
(
GetCurrentThread
(),
NULL
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to set thread description, hr %#x.
\n
"
,
hr
);
ptr
=
NULL
;
hr
=
pGetThreadDescription
(
GetCurrentThread
(),
&
ptr
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to get thread description, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
ptr
,
L""
),
"Unexpected description %s.
\n
"
,
wine_dbgstr_w
(
ptr
));
LocalFree
(
ptr
);
/* Set with 0 length/NULL pointer. */
hr
=
pSetThreadDescription
(
GetCurrentThread
(),
L"123"
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to set thread description, hr %#x.
\n
"
,
hr
);
thread_desc
->
Length
=
0
;
thread_desc
->
Description
=
NULL
;
status
=
pNtSetInformationThread
(
GetCurrentThread
(),
ThreadDescription
,
thread_desc
,
sizeof
(
*
thread_desc
));
ok
(
!
status
,
"Failed to set thread description, status %#x.
\n
"
,
status
);
ptr
=
NULL
;
hr
=
pGetThreadDescription
(
GetCurrentThread
(),
&
ptr
);
ok
(
hr
==
HRESULT_FROM_NT
(
STATUS_SUCCESS
),
"Failed to get thread description, hr %#x.
\n
"
,
hr
);
ok
(
!
lstrcmpW
(
ptr
,
L""
),
"Unexpected description %s.
\n
"
,
wine_dbgstr_w
(
ptr
));
LocalFree
(
ptr
);
}
static
void
init_funcs
(
void
)
{
HMODULE
hKernel32
=
GetModuleHandleA
(
"kernel32.dll"
);
...
...
@@ -2147,6 +2276,8 @@ static void init_funcs(void)
X
(
GetThreadGroupAffinity
);
X
(
SetThreadGroupAffinity
);
X
(
SetThreadDescription
);
X
(
GetThreadDescription
);
X
(
FlsAlloc
);
X
(
FlsFree
);
...
...
@@ -2223,6 +2354,7 @@ START_TEST(thread)
test_ThreadErrorMode
();
test_thread_fpu_cw
();
test_thread_actctx
();
test_thread_description
();
test_threadpool
();
}
include/winternl.h
View file @
602eb52c
...
...
@@ -974,7 +974,7 @@ typedef enum _SYSTEM_INFORMATION_CLASS {
}
SYSTEM_INFORMATION_CLASS
,
*
PSYSTEM_INFORMATION_CLASS
;
typedef
enum
_THREADINFOCLASS
{
ThreadBasicInformation
,
ThreadBasicInformation
=
0
,
ThreadTimes
,
ThreadPriority
,
ThreadBasePriority
,
...
...
@@ -1008,6 +1008,7 @@ typedef enum _THREADINFOCLASS {
ThreadUmsInformation
,
ThreadCounterProfiling
,
ThreadIdealProcessorEx
,
ThreadDescription
=
38
,
MaxThreadInfoClass
}
THREADINFOCLASS
;
...
...
@@ -1027,6 +1028,12 @@ typedef struct _THREAD_DESCRIPTOR_INFORMATION
LDT_ENTRY
Entry
;
}
THREAD_DESCRIPTOR_INFORMATION
,
*
PTHREAD_DESCRIPTOR_INFORMATION
;
typedef
struct
_THREAD_DESCRIPTION_INFORMATION
{
DWORD
Length
;
WCHAR
*
Description
;
}
THREAD_DESCRIPTION_INFORMATION
,
*
PTHREAD_DESCRIPTION_INFORMATION
;
typedef
struct
_KERNEL_USER_TIMES
{
LARGE_INTEGER
CreateTime
;
LARGE_INTEGER
ExitTime
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment