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
ab7485bb
Commit
ab7485bb
authored
Jun 29, 2020
by
Changping Yu
Committed by
Alexandre Julliard
Jun 29, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32/tests: Add test for thread enumeration order in toolhelp.
Signed-off-by:
Changping Yu
<
dead.ash@hotmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
43be3507
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
171 additions
and
1 deletion
+171
-1
toolhelp.c
dlls/kernel32/tests/toolhelp.c
+171
-1
No files found.
dlls/kernel32/tests/toolhelp.c
View file @
ab7485bb
...
...
@@ -22,11 +22,14 @@
#include <stdlib.h>
#include <stdio.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "tlhelp32.h"
#include "wine/test.h"
#include "winuser.h"
#include "winternl.h"
static
char
selfname
[
MAX_PATH
];
...
...
@@ -38,9 +41,12 @@ static BOOL (WINAPI *pProcess32First)(HANDLE, LPPROCESSENTRY32);
static
BOOL
(
WINAPI
*
pProcess32Next
)(
HANDLE
,
LPPROCESSENTRY32
);
static
BOOL
(
WINAPI
*
pThread32First
)(
HANDLE
,
LPTHREADENTRY32
);
static
BOOL
(
WINAPI
*
pThread32Next
)(
HANDLE
,
LPTHREADENTRY32
);
static
NTSTATUS
(
WINAPI
*
pNtQuerySystemInformation
)(
SYSTEM_INFORMATION_CLASS
,
void
*
,
ULONG
,
ULONG
*
);
/* 1 minute should be more than enough */
#define WAIT_TIME (60 * 1000)
/* Specify the number of simultaneous threads to test */
#define NUM_THREADS 4
static
DWORD
WINAPI
sub_thread
(
void
*
pmt
)
{
...
...
@@ -150,6 +156,166 @@ static void test_process(DWORD curr_pid, DWORD sub_pcs_pid)
ok
(
!
pProcess32First
(
hSnapshot
,
&
pe
),
"shouldn't return a process
\n
"
);
}
static
DWORD
WINAPI
get_id_thread
(
void
*
curr_pid
)
{
HANDLE
hSnapshot
;
THREADENTRY32
te
;
HANDLE
ev
,
threads
[
NUM_THREADS
];
DWORD
thread_ids
[
NUM_THREADS
];
DWORD
thread_traversed
[
NUM_THREADS
];
DWORD
tid
,
first_tid
=
0
;
BOOL
found
=
FALSE
;
int
i
,
matched_idx
=
-
1
;
ULONG
buf_size
=
0
;
NTSTATUS
status
;
BYTE
*
pcs_buffer
=
NULL
;
DWORD
pcs_offset
=
0
;
SYSTEM_PROCESS_INFORMATION
*
spi
=
NULL
;
ev
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
ok
(
ev
!=
NULL
,
"Cannot create event
\n
"
);
for
(
i
=
0
;
i
<
NUM_THREADS
;
i
++
)
{
threads
[
i
]
=
CreateThread
(
NULL
,
0
,
sub_thread
,
ev
,
0
,
&
tid
);
ok
(
threads
[
i
]
!=
NULL
,
"Cannot create thread
\n
"
);
thread_ids
[
i
]
=
tid
;
}
hSnapshot
=
pCreateToolhelp32Snapshot
(
TH32CS_SNAPTHREAD
,
0
);
ok
(
hSnapshot
!=
NULL
,
"Cannot create snapshot
\n
"
);
/* Check that this current process is enumerated */
te
.
dwSize
=
sizeof
(
te
);
ok
(
pThread32First
(
hSnapshot
,
&
te
),
"Thread cannot traverse
\n
"
);
do
{
if
(
found
)
{
if
(
te
.
th32OwnerProcessID
!=
PtrToUlong
(
curr_pid
))
break
;
if
(
matched_idx
>=
0
)
{
thread_traversed
[
matched_idx
++
]
=
te
.
th32ThreadID
;
if
(
matched_idx
>=
NUM_THREADS
)
break
;
}
else
if
(
thread_ids
[
0
]
==
te
.
th32ThreadID
)
{
matched_idx
=
0
;
thread_traversed
[
matched_idx
++
]
=
te
.
th32ThreadID
;
}
}
else
if
(
te
.
th32OwnerProcessID
==
PtrToUlong
(
curr_pid
))
{
found
=
TRUE
;
first_tid
=
te
.
th32ThreadID
;
}
}
while
(
pThread32Next
(
hSnapshot
,
&
te
));
ok
(
found
,
"Couldn't find self and/or sub-process in process list
\n
"
);
/* Check if the thread order is strictly consistent */
found
=
FALSE
;
for
(
i
=
0
;
i
<
NUM_THREADS
;
i
++
)
{
if
(
thread_traversed
[
i
]
!=
thread_ids
[
i
])
{
found
=
TRUE
;
break
;
}
/* Reset data */
thread_traversed
[
i
]
=
0
;
}
todo_wine
ok
(
found
==
FALSE
,
"The thread order is not strictly consistent
\n
"
);
/* Determine the order by NtQuerySystemInformation function */
pcs_buffer
=
NULL
;
status
=
pNtQuerySystemInformation
(
SystemProcessInformation
,
pcs_buffer
,
buf_size
,
&
buf_size
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Failed with %x
\n
"
,
status
);
if
(
status
==
STATUS_INFO_LENGTH_MISMATCH
)
{
pcs_buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buf_size
);
ok
(
pcs_buffer
!=
NULL
,
"Unable to allocate space
\n
"
);
found
=
FALSE
;
matched_idx
=
-
1
;
status
=
NtQuerySystemInformation
(
SystemProcessInformation
,
pcs_buffer
,
buf_size
,
&
buf_size
);
do
{
spi
=
(
SYSTEM_PROCESS_INFORMATION
*
)
&
pcs_buffer
[
pcs_offset
];
if
(
spi
->
UniqueProcessId
==
curr_pid
)
{
found
=
TRUE
;
break
;
}
pcs_offset
+=
spi
->
NextEntryOffset
;
}
while
(
spi
->
NextEntryOffset
!=
0
);
ok
(
found
&&
spi
,
"No process found
\n
"
);
for
(
i
=
0
;
i
<
spi
->
dwThreadCount
;
i
++
)
{
tid
=
HandleToULong
(
spi
->
ti
[
i
].
ClientId
.
UniqueThread
);
if
(
matched_idx
>
0
)
{
thread_traversed
[
matched_idx
++
]
=
tid
;
if
(
matched_idx
>=
NUM_THREADS
)
break
;
}
else
if
(
tid
==
thread_ids
[
0
])
{
matched_idx
=
0
;
thread_traversed
[
matched_idx
++
]
=
tid
;
}
}
}
if
(
pcs_buffer
)
HeapFree
(
GetProcessHeap
(),
0
,
pcs_buffer
);
ok
(
matched_idx
>
0
,
"No thread id match found
\n
"
);
found
=
FALSE
;
for
(
i
=
0
;
i
<
NUM_THREADS
;
i
++
)
{
if
(
thread_traversed
[
i
]
!=
thread_ids
[
i
])
{
found
=
TRUE
;
break
;
}
}
todo_wine
ok
(
found
==
FALSE
,
"wrong order in NtQuerySystemInformation function
\n
"
);
SetEvent
(
ev
);
WaitForMultipleObjects
(
NUM_THREADS
,
threads
,
TRUE
,
WAIT_TIME
);
for
(
i
=
0
;
i
<
NUM_THREADS
;
i
++
)
CloseHandle
(
threads
[
i
]);
CloseHandle
(
ev
);
CloseHandle
(
hSnapshot
);
return
first_tid
;
}
static
void
test_main_thread
(
DWORD
curr_pid
,
DWORD
main_tid
)
{
HANDLE
thread
;
DWORD
tid
=
0
;
int
error
;
/* Check that the main thread id is first one in this thread. */
tid
=
get_id_thread
(
ULongToPtr
(
curr_pid
));
todo_wine
ok
(
tid
==
main_tid
,
"The first thread id returned is not the main thread id
\n
"
);
/* Check that the main thread id is first one in other thread. */
thread
=
CreateThread
(
NULL
,
0
,
get_id_thread
,
ULongToPtr
(
curr_pid
),
0
,
NULL
);
error
=
WaitForSingleObject
(
thread
,
WAIT_TIME
);
ok
(
error
==
WAIT_OBJECT_0
,
"Thread did not complete within timelimit
\n
"
);
ok
(
GetExitCodeThread
(
thread
,
&
tid
),
"Could not retrieve exit code
\n
"
);
todo_wine
ok
(
tid
==
main_tid
,
"The first thread id returned is not the main thread id
\n
"
);
}
static
void
test_thread
(
DWORD
curr_pid
,
DWORD
sub_pcs_pid
)
{
HANDLE
hSnapshot
;
...
...
@@ -291,6 +457,7 @@ START_TEST(toolhelp)
HANDLE
ev1
,
ev2
;
DWORD
w
;
HANDLE
hkernel32
=
GetModuleHandleA
(
"kernel32"
);
HANDLE
hntdll
=
GetModuleHandleA
(
"ntdll.dll"
);
pCreateToolhelp32Snapshot
=
(
VOID
*
)
GetProcAddress
(
hkernel32
,
"CreateToolhelp32Snapshot"
);
pModule32First
=
(
VOID
*
)
GetProcAddress
(
hkernel32
,
"Module32First"
);
...
...
@@ -299,11 +466,13 @@ START_TEST(toolhelp)
pProcess32Next
=
(
VOID
*
)
GetProcAddress
(
hkernel32
,
"Process32Next"
);
pThread32First
=
(
VOID
*
)
GetProcAddress
(
hkernel32
,
"Thread32First"
);
pThread32Next
=
(
VOID
*
)
GetProcAddress
(
hkernel32
,
"Thread32Next"
);
pNtQuerySystemInformation
=
(
VOID
*
)
GetProcAddress
(
hntdll
,
"NtQuerySystemInformation"
);
if
(
!
pCreateToolhelp32Snapshot
||
!
pModule32First
||
!
pModule32Next
||
!
pProcess32First
||
!
pProcess32Next
||
!
pThread32First
||
!
pThread32Next
)
!
pThread32First
||
!
pThread32Next
||
!
pNtQuerySystemInformation
)
{
win_skip
(
"Needed functions are not available, most likely running on Windows NT
\n
"
);
return
;
...
...
@@ -339,6 +508,7 @@ START_TEST(toolhelp)
test_process
(
pid
,
info
.
dwProcessId
);
test_thread
(
pid
,
info
.
dwProcessId
);
test_main_thread
(
pid
,
GetCurrentThreadId
());
test_module
(
pid
,
curr_expected_modules
,
ARRAY_SIZE
(
curr_expected_modules
));
test_module
(
info
.
dwProcessId
,
sub_expected_modules
,
ARRAY_SIZE
(
sub_expected_modules
));
...
...
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