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
b0951ba8
Commit
b0951ba8
authored
Dec 03, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add support for querying thread suspend count.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7082ebc6
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
93 additions
and
4 deletions
+93
-4
exception.c
dlls/ntdll/tests/exception.c
+62
-1
thread.c
dlls/ntdll/thread.c
+21
-0
server_protocol.h
include/wine/server_protocol.h
+3
-1
winternl.h
include/winternl.h
+1
-0
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+3
-2
thread.c
server/thread.c
+1
-0
trace.c
server/trace.c
+1
-0
No files found.
dlls/ntdll/tests/exception.c
View file @
b0951ba8
...
...
@@ -50,6 +50,7 @@ static ULONG (WINAPI *pRtlRemoveVectoredContinueHandler)(PVOID handler);
static
NTSTATUS
(
WINAPI
*
pNtReadVirtualMemory
)(
HANDLE
,
const
void
*
,
void
*
,
SIZE_T
,
SIZE_T
*
);
static
NTSTATUS
(
WINAPI
*
pNtTerminateProcess
)(
HANDLE
handle
,
LONG
exit_code
);
static
NTSTATUS
(
WINAPI
*
pNtQueryInformationProcess
)(
HANDLE
,
PROCESSINFOCLASS
,
PVOID
,
ULONG
,
PULONG
);
static
NTSTATUS
(
WINAPI
*
pNtQueryInformationThread
)(
HANDLE
,
THREADINFOCLASS
,
PVOID
,
ULONG
,
PULONG
);
static
NTSTATUS
(
WINAPI
*
pNtSetInformationProcess
)(
HANDLE
,
PROCESSINFOCLASS
,
PVOID
,
ULONG
);
static
BOOL
(
WINAPI
*
pIsWow64Process
)(
HANDLE
,
PBOOL
);
static
NTSTATUS
(
WINAPI
*
pNtClose
)(
HANDLE
);
...
...
@@ -3163,11 +3164,34 @@ static DWORD WINAPI suspend_thread_test( void *arg )
return
0
;
}
static
void
test_suspend_count
(
HANDLE
hthread
,
ULONG
expected_count
,
int
line
)
{
static
BOOL
supported
=
TRUE
;
NTSTATUS
status
;
ULONG
count
;
if
(
!
supported
)
return
;
count
=
~
0u
;
status
=
pNtQueryInformationThread
(
hthread
,
ThreadSuspendCount
,
&
count
,
sizeof
(
count
),
NULL
);
if
(
status
)
{
win_skip
(
"ThreadSuspendCount is not supported.
\n
"
);
supported
=
FALSE
;
return
;
}
ok_
(
__FILE__
,
line
)(
!
status
,
"Failed to get suspend count, status %#x.
\n
"
,
status
);
ok_
(
__FILE__
,
line
)(
count
==
expected_count
,
"Unexpected suspend count %u.
\n
"
,
count
);
}
static
void
test_suspend_thread
(
void
)
{
#define TEST_SUSPEND_COUNT(thread, count) test_suspend_count((thread), (count), __LINE__)
HANDLE
thread
,
event
;
ULONG
count
,
len
;
NTSTATUS
status
;
ULONG
count
;
DWORD
ret
;
status
=
NtSuspendThread
(
0
,
NULL
);
...
...
@@ -3184,6 +3208,31 @@ static void test_suspend_thread(void)
ret
=
WaitForSingleObject
(
thread
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"Unexpected status %d.
\n
"
,
ret
);
status
=
pNtQueryInformationThread
(
thread
,
ThreadSuspendCount
,
&
count
,
sizeof
(
count
),
NULL
);
if
(
!
status
)
{
status
=
pNtQueryInformationThread
(
thread
,
ThreadSuspendCount
,
NULL
,
sizeof
(
count
),
NULL
);
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
"Unexpected status %#x.
\n
"
,
status
);
status
=
pNtQueryInformationThread
(
thread
,
ThreadSuspendCount
,
&
count
,
sizeof
(
count
)
/
2
,
NULL
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Unexpected status %#x.
\n
"
,
status
);
len
=
123
;
status
=
pNtQueryInformationThread
(
thread
,
ThreadSuspendCount
,
&
count
,
sizeof
(
count
)
/
2
,
&
len
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
len
==
123
,
"Unexpected info length %u.
\n
"
,
len
);
len
=
123
;
status
=
pNtQueryInformationThread
(
thread
,
ThreadSuspendCount
,
NULL
,
0
,
&
len
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
len
==
123
,
"Unexpected info length %u.
\n
"
,
len
);
count
=
10
;
status
=
pNtQueryInformationThread
(
0
,
ThreadSuspendCount
,
&
count
,
sizeof
(
count
),
NULL
);
ok
(
status
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
count
==
10
,
"Unexpected suspend count %u.
\n
"
,
count
);
}
status
=
NtResumeThread
(
thread
,
NULL
);
ok
(
!
status
,
"Unexpected status %#x.
\n
"
,
status
);
...
...
@@ -3191,24 +3240,35 @@ static void test_suspend_thread(void)
ok
(
!
status
,
"Unexpected status %#x.
\n
"
,
status
);
ok
(
count
==
0
,
"Unexpected suspended count %u.
\n
"
,
count
);
TEST_SUSPEND_COUNT
(
thread
,
0
);
status
=
NtSuspendThread
(
thread
,
NULL
);
ok
(
!
status
,
"Failed to suspend a thread, status %#x.
\n
"
,
status
);
TEST_SUSPEND_COUNT
(
thread
,
1
);
status
=
NtSuspendThread
(
thread
,
&
count
);
ok
(
!
status
,
"Failed to suspend a thread, status %#x.
\n
"
,
status
);
ok
(
count
==
1
,
"Unexpected suspended count %u.
\n
"
,
count
);
TEST_SUSPEND_COUNT
(
thread
,
2
);
status
=
NtResumeThread
(
thread
,
&
count
);
ok
(
!
status
,
"Failed to resume a thread, status %#x.
\n
"
,
status
);
ok
(
count
==
2
,
"Unexpected suspended count %u.
\n
"
,
count
);
TEST_SUSPEND_COUNT
(
thread
,
1
);
status
=
NtResumeThread
(
thread
,
NULL
);
ok
(
!
status
,
"Failed to resume a thread, status %#x.
\n
"
,
status
);
TEST_SUSPEND_COUNT
(
thread
,
0
);
SetEvent
(
event
);
WaitForSingleObject
(
thread
,
INFINITE
);
CloseHandle
(
thread
);
#undef TEST_SUSPEND_COUNT
}
static
const
char
*
suspend_process_event_name
=
"suspend_process_event"
;
...
...
@@ -3418,6 +3478,7 @@ START_TEST(exception)
X
(
RtlAddVectoredContinueHandler
);
X
(
RtlRemoveVectoredContinueHandler
);
X
(
NtQueryInformationProcess
);
X
(
NtQueryInformationThread
);
X
(
NtSetInformationProcess
);
X
(
NtSuspendProcess
);
X
(
NtResumeProcess
);
...
...
dlls/ntdll/thread.c
View file @
b0951ba8
...
...
@@ -1115,6 +1115,27 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
*
(
BOOL
*
)
data
=
FALSE
;
if
(
ret_len
)
*
ret_len
=
sizeof
(
BOOL
);
return
STATUS_SUCCESS
;
case
ThreadSuspendCount
:
{
ULONG
count
=
0
;
if
(
length
!=
sizeof
(
ULONG
))
return
STATUS_INFO_LENGTH_MISMATCH
;
if
(
!
data
)
return
STATUS_ACCESS_VIOLATION
;
SERVER_START_REQ
(
get_thread_info
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
tid_in
=
0
;
if
(
!
(
status
=
wine_server_call
(
req
)))
count
=
reply
->
suspend_count
;
}
SERVER_END_REQ
;
if
(
!
status
)
*
(
ULONG
*
)
data
=
count
;
return
status
;
}
case
ThreadDescription
:
{
THREAD_DESCRIPTION_INFORMATION
*
info
=
data
;
...
...
include/wine/server_protocol.h
View file @
b0951ba8
...
...
@@ -1006,8 +1006,10 @@ struct get_thread_info_reply
int
exit_code
;
int
priority
;
int
last
;
int
suspend_count
;
data_size_t
desc_len
;
/* VARARG(desc,unicode_str); */
char
__pad_60
[
4
];
};
...
...
@@ -6700,6 +6702,6 @@ union generic_reply
struct
resume_process_reply
resume_process_reply
;
};
#define SERVER_PROTOCOL_VERSION 59
2
#define SERVER_PROTOCOL_VERSION 59
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
include/winternl.h
View file @
b0951ba8
...
...
@@ -1008,6 +1008,7 @@ typedef enum _THREADINFOCLASS {
ThreadUmsInformation
,
ThreadCounterProfiling
,
ThreadIdealProcessorEx
,
ThreadSuspendCount
=
35
,
ThreadDescription
=
38
,
MaxThreadInfoClass
}
THREADINFOCLASS
;
...
...
server/protocol.def
View file @
b0951ba8
...
...
@@ -944,6 +944,7 @@ struct rawinput_device
int exit_code; /* thread exit code */
int priority; /* thread priority level */
int last; /* last thread in process */
int suspend_count; /* thread suspend count */
data_size_t desc_len; /* description length in bytes */
VARARG(desc,unicode_str); /* description string */
@END
...
...
server/request.h
View file @
b0951ba8
...
...
@@ -849,8 +849,9 @@ C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, affinity) == 32 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
exit_code
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
priority
)
==
44
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
last
)
==
48
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
desc_len
)
==
52
);
C_ASSERT
(
sizeof
(
struct
get_thread_info_reply
)
==
56
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
suspend_count
)
==
52
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_info_reply
,
desc_len
)
==
56
);
C_ASSERT
(
sizeof
(
struct
get_thread_info_reply
)
==
64
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_times_request
,
handle
)
==
12
);
C_ASSERT
(
sizeof
(
struct
get_thread_times_request
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_times_reply
,
creation_time
)
==
8
);
...
...
server/thread.c
View file @
b0951ba8
...
...
@@ -1463,6 +1463,7 @@ DECL_HANDLER(get_thread_info)
reply
->
priority
=
thread
->
priority
;
reply
->
affinity
=
thread
->
affinity
;
reply
->
last
=
thread
->
process
->
running_threads
==
1
;
reply
->
suspend_count
=
thread
->
suspend
;
reply
->
desc_len
=
thread
->
desc_len
;
if
(
thread
->
desc
&&
get_reply_max_size
())
...
...
server/trace.c
View file @
b0951ba8
...
...
@@ -1423,6 +1423,7 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req
fprintf
(
stderr
,
", exit_code=%d"
,
req
->
exit_code
);
fprintf
(
stderr
,
", priority=%d"
,
req
->
priority
);
fprintf
(
stderr
,
", last=%d"
,
req
->
last
);
fprintf
(
stderr
,
", suspend_count=%d"
,
req
->
suspend_count
);
fprintf
(
stderr
,
", desc_len=%u"
,
req
->
desc_len
);
dump_varargs_unicode_str
(
", desc="
,
cur_size
);
}
...
...
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