Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
98a54663
Commit
98a54663
authored
Oct 25, 2021
by
Paul Gofman
Committed by
Alexandre Julliard
Oct 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement SystemExtendedProcessInformation system info class.
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
bb6aa6c7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
126 additions
and
26 deletions
+126
-26
info.c
dlls/ntdll/tests/info.c
+80
-10
system.c
dlls/ntdll/unix/system.c
+27
-15
server_protocol.h
include/wine/server_protocol.h
+3
-1
winternl.h
include/winternl.h
+12
-0
process.c
server/process.c
+2
-0
protocol.def
server/protocol.def
+2
-0
No files found.
dlls/ntdll/tests/info.c
View file @
98a54663
...
...
@@ -438,7 +438,7 @@ static void test_query_timeofday(void)
if
(
winetest_debug
>
1
)
trace
(
"uCurrentTimeZoneId : (%d)
\n
"
,
sti
.
uCurrentTimeZoneId
);
}
static
void
test_query_process
(
void
)
static
void
test_query_process
(
BOOL
extended
)
{
NTSTATUS
status
;
DWORD
last_pid
;
...
...
@@ -470,12 +470,27 @@ static void test_query_process(void)
SYSTEM_THREAD_INFORMATION
ti
[
1
];
}
SYSTEM_PROCESS_INFORMATION_PRIVATE
;
BOOL
is_process_wow64
=
FALSE
,
current_process_found
=
FALSE
;
SYSTEM_PROCESS_INFORMATION_PRIVATE
*
spi
,
*
spi_buf
;
BOOL
current_process_found
=
FALSE
;
SYSTEM_EXTENDED_THREAD_INFORMATION
*
ti
;
SYSTEM_INFORMATION_CLASS
info_class
;
void
*
expected_address
;
ULONG
thread_info_size
;
if
(
extended
)
{
info_class
=
SystemExtendedProcessInformation
;
thread_info_size
=
sizeof
(
SYSTEM_EXTENDED_THREAD_INFORMATION
);
}
else
{
info_class
=
SystemProcessInformation
;
thread_info_size
=
sizeof
(
SYSTEM_THREAD_INFORMATION
);
}
/* test ReturnLength */
ReturnLength
=
0
;
status
=
pNtQuerySystemInformation
(
SystemProcessInformation
,
NULL
,
0
,
&
ReturnLength
);
status
=
pNtQuerySystemInformation
(
info_class
,
NULL
,
0
,
&
ReturnLength
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Expected STATUS_INFO_LENGTH_MISMATCH got %08x
\n
"
,
status
);
ok
(
ReturnLength
>
0
,
"got 0 length
\n
"
);
...
...
@@ -486,8 +501,10 @@ static void test_query_process(void)
return
;
}
winetest_push_context
(
"extended %d"
,
extended
);
spi_buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ReturnLength
);
status
=
pNtQuerySystemInformation
(
SystemProcessInformation
,
spi_buf
,
ReturnLength
,
&
ReturnLength
);
status
=
pNtQuerySystemInformation
(
info_class
,
spi_buf
,
ReturnLength
,
&
ReturnLength
);
/* Sometimes new process or threads appear between the call and increase the size,
* otherwise the previously returned buffer size should be sufficient. */
...
...
@@ -511,16 +528,67 @@ static void test_query_process(void)
if
(
last_pid
==
GetCurrentProcessId
())
current_process_found
=
TRUE
;
ok
(
!
(
last_pid
&
3
),
"Unexpected PID low bits: %p
\n
"
,
spi
->
UniqueProcessId
);
if
(
extended
&&
is_wow64
&&
spi
->
UniqueProcessId
)
{
InitializeObjectAttributes
(
&
attr
,
NULL
,
0
,
NULL
,
NULL
);
cid
.
UniqueProcess
=
spi
->
UniqueProcessId
;
cid
.
UniqueThread
=
0
;
status
=
NtOpenProcess
(
&
handle
,
PROCESS_QUERY_LIMITED_INFORMATION
,
&
attr
,
&
cid
);
ok
(
status
==
STATUS_SUCCESS
||
status
==
STATUS_ACCESS_DENIED
,
"Got unexpected status %#x, pid %p.
\n
"
,
status
,
spi
->
UniqueProcessId
);
if
(
!
status
)
{
ULONG_PTR
info
;
status
=
NtQueryInformationProcess
(
handle
,
ProcessWow64Information
,
&
info
,
sizeof
(
info
),
NULL
);
ok
(
status
==
STATUS_SUCCESS
,
"Got unexpected status %#x.
\n
"
,
status
);
is_process_wow64
=
!!
info
;
NtClose
(
handle
);
}
}
for
(
j
=
0
;
j
<
spi
->
dwThreadCount
;
j
++
)
{
ti
=
(
SYSTEM_EXTENDED_THREAD_INFORMATION
*
)((
BYTE
*
)
spi
->
ti
+
j
*
thread_info_size
);
k
++
;
ok
(
spi
->
ti
[
j
]
.
ClientId
.
UniqueProcess
==
spi
->
UniqueProcessId
,
ok
(
ti
->
ThreadInfo
.
ClientId
.
UniqueProcess
==
spi
->
UniqueProcessId
,
"The owning pid of the thread (%p) doesn't equal the pid (%p) of the process
\n
"
,
spi
->
ti
[
j
].
ClientId
.
UniqueProcess
,
spi
->
UniqueProcessId
);
ti
->
ThreadInfo
.
ClientId
.
UniqueProcess
,
spi
->
UniqueProcessId
);
tid
=
(
DWORD_PTR
)
ti
->
ThreadInfo
.
ClientId
.
UniqueThread
;
ok
(
!
(
tid
&
3
),
"Unexpected TID low bits: %p
\n
"
,
ti
->
ThreadInfo
.
ClientId
.
UniqueThread
);
tid
=
(
DWORD_PTR
)
spi
->
ti
[
j
].
ClientId
.
UniqueThread
;
ok
(
!
(
tid
&
3
),
"Unexpected TID low bits: %p
\n
"
,
spi
->
ti
[
j
].
ClientId
.
UniqueThread
);
if
(
extended
)
{
todo_wine
ok
(
!!
ti
->
StackBase
,
"Got NULL StackBase.
\n
"
);
todo_wine
ok
(
!!
ti
->
StackLimit
,
"Got NULL StackLimit.
\n
"
);
ok
(
!!
ti
->
Win32StartAddress
,
"Got NULL Win32StartAddress.
\n
"
);
cid
.
UniqueProcess
=
0
;
cid
.
UniqueThread
=
ti
->
ThreadInfo
.
ClientId
.
UniqueThread
;
InitializeObjectAttributes
(
&
attr
,
NULL
,
0
,
NULL
,
NULL
);
status
=
NtOpenThread
(
&
handle
,
THREAD_QUERY_INFORMATION
,
&
attr
,
&
cid
);
if
(
!
status
)
{
THREAD_BASIC_INFORMATION
tbi
;
status
=
pNtQueryInformationThread
(
handle
,
ThreadBasicInformation
,
&
tbi
,
sizeof
(
tbi
),
NULL
);
ok
(
status
==
STATUS_SUCCESS
,
"Got unexpected status %#x.
\n
"
,
status
);
expected_address
=
tbi
.
TebBaseAddress
;
if
(
is_wow64
&&
is_process_wow64
)
expected_address
=
(
BYTE
*
)
expected_address
-
0x2000
;
if
(
!
is_wow64
&&
!
is_process_wow64
&&
!
tbi
.
TebBaseAddress
)
win_skip
(
"Could not get TebBaseAddress, thread %u.
\n
"
,
j
);
else
ok
(
ti
->
TebBase
==
expected_address
||
(
is_wow64
&&
!
expected_address
&&
!!
ti
->
TebBase
),
"Got unexpected TebBase %p, expected %p.
\n
"
,
ti
->
TebBase
,
expected_address
);
NtClose
(
handle
);
}
}
}
if
(
!
spi
->
NextEntryOffset
)
...
...
@@ -577,6 +645,7 @@ static void test_query_process(void)
NtClose
(
handle
);
}
winetest_pop_context
();
}
static
void
test_query_procperf
(
void
)
...
...
@@ -3317,7 +3386,8 @@ START_TEST(info)
test_query_cpu
();
test_query_performance
();
test_query_timeofday
();
test_query_process
();
test_query_process
(
TRUE
);
test_query_process
(
FALSE
);
test_query_procperf
();
test_query_module
();
test_query_handle
();
...
...
dlls/ntdll/unix/system.c
View file @
98a54663
...
...
@@ -2359,9 +2359,10 @@ static void read_dev_urandom( void *buf, ULONG len )
else
WARN
(
"can't open /dev/urandom
\n
"
);
}
static
NTSTATUS
get_system_process_info
(
void
*
info
,
ULONG
size
,
ULONG
*
len
)
static
NTSTATUS
get_system_process_info
(
SYSTEM_INFORMATION_CLASS
class
,
void
*
info
,
ULONG
size
,
ULONG
*
len
)
{
unsigned
int
process_count
,
total_thread_count
,
total_name_len
,
i
,
j
;
unsigned
int
thread_info_size
;
unsigned
int
pos
=
0
;
char
*
buffer
=
NULL
;
NTSTATUS
ret
;
...
...
@@ -2369,6 +2370,11 @@ static NTSTATUS get_system_process_info( void *info, ULONG size, ULONG *len )
C_ASSERT
(
sizeof
(
struct
thread_info
)
<=
sizeof
(
SYSTEM_THREAD_INFORMATION
)
);
C_ASSERT
(
sizeof
(
struct
process_info
)
<=
sizeof
(
SYSTEM_PROCESS_INFORMATION
)
);
if
(
class
==
SystemExtendedProcessInformation
)
thread_info_size
=
sizeof
(
SYSTEM_EXTENDED_THREAD_INFORMATION
);
else
thread_info_size
=
sizeof
(
SYSTEM_THREAD_INFORMATION
);
*
len
=
0
;
if
(
size
&&
!
(
buffer
=
malloc
(
size
)))
return
STATUS_NO_MEMORY
;
...
...
@@ -2387,7 +2393,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
if
(
ret
==
STATUS_INFO_LENGTH_MISMATCH
)
*
len
=
sizeof
(
SYSTEM_PROCESS_INFORMATION
)
*
process_count
+
(
total_name_len
+
process_count
)
*
sizeof
(
WCHAR
)
+
total_thread_count
*
sizeof
(
SYSTEM_THREAD_INFORMATION
)
;
+
total_thread_count
*
thread_info_size
;
free
(
buffer
);
return
ret
;
...
...
@@ -2414,13 +2420,13 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
name_len
++
;
}
proc_len
=
sizeof
(
*
nt_process
)
+
server_process
->
thread_count
*
sizeof
(
SYSTEM_THREAD_INFORMATION
)
proc_len
=
sizeof
(
*
nt_process
)
+
server_process
->
thread_count
*
thread_info_size
+
(
name_len
+
1
)
*
sizeof
(
WCHAR
);
*
len
+=
proc_len
;
if
(
*
len
<=
size
)
{
memset
(
nt_process
,
0
,
sizeof
(
*
nt_process
)
);
memset
(
nt_process
,
0
,
proc_len
);
if
(
i
<
process_count
-
1
)
nt_process
->
NextEntryOffset
=
proc_len
;
nt_process
->
CreationTime
.
QuadPart
=
server_process
->
start_time
;
...
...
@@ -2438,16 +2444,23 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
for
(
j
=
0
;
j
<
server_process
->
thread_count
;
j
++
)
{
const
struct
thread_info
*
server_thread
=
(
const
struct
thread_info
*
)(
buffer
+
pos
);
SYSTEM_EXTENDED_THREAD_INFORMATION
*
ti
;
if
(
*
len
<=
size
)
{
nt_process
->
ti
[
j
].
CreateTime
.
QuadPart
=
server_thread
->
start_time
;
nt_process
->
ti
[
j
].
ClientId
.
UniqueProcess
=
UlongToHandle
(
server_process
->
pid
);
nt_process
->
ti
[
j
].
ClientId
.
UniqueThread
=
UlongToHandle
(
server_thread
->
tid
);
nt_process
->
ti
[
j
].
dwCurrentPriority
=
server_thread
->
current_priority
;
nt_process
->
ti
[
j
].
dwBasePriority
=
server_thread
->
base_priority
;
ti
=
(
SYSTEM_EXTENDED_THREAD_INFORMATION
*
)((
BYTE
*
)
nt_process
->
ti
+
j
*
thread_info_size
);
ti
->
ThreadInfo
.
CreateTime
.
QuadPart
=
server_thread
->
start_time
;
ti
->
ThreadInfo
.
ClientId
.
UniqueProcess
=
UlongToHandle
(
server_process
->
pid
);
ti
->
ThreadInfo
.
ClientId
.
UniqueThread
=
UlongToHandle
(
server_thread
->
tid
);
ti
->
ThreadInfo
.
dwCurrentPriority
=
server_thread
->
current_priority
;
ti
->
ThreadInfo
.
dwBasePriority
=
server_thread
->
base_priority
;
get_thread_times
(
server_process
->
unix_pid
,
server_thread
->
unix_tid
,
&
nt_process
->
ti
[
j
].
KernelTime
,
&
nt_process
->
ti
[
j
].
UserTime
);
&
ti
->
ThreadInfo
.
KernelTime
,
&
ti
->
ThreadInfo
.
UserTime
);
if
(
class
==
SystemExtendedProcessInformation
)
{
ti
->
Win32StartAddress
=
wine_server_get_ptr
(
server_thread
->
entry_point
);
ti
->
TebBase
=
wine_server_get_ptr
(
server_thread
->
teb
);
}
}
pos
+=
sizeof
(
*
server_thread
);
...
...
@@ -2455,7 +2468,8 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
if
(
*
len
<=
size
)
{
nt_process
->
ProcessName
.
Buffer
=
(
WCHAR
*
)
&
nt_process
->
ti
[
server_process
->
thread_count
];
nt_process
->
ProcessName
.
Buffer
=
(
WCHAR
*
)((
BYTE
*
)
nt_process
->
ti
+
server_process
->
thread_count
*
thread_info_size
);
nt_process
->
ProcessName
.
Length
=
name_len
*
sizeof
(
WCHAR
);
nt_process
->
ProcessName
.
MaximumLength
=
(
name_len
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
nt_process
->
ProcessName
.
Buffer
,
file_part
,
name_len
*
sizeof
(
WCHAR
));
...
...
@@ -2554,7 +2568,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
}
case
SystemProcessInformation
:
/* 5 */
ret
=
get_system_process_info
(
info
,
size
,
&
len
);
ret
=
get_system_process_info
(
class
,
info
,
size
,
&
len
);
break
;
case
SystemProcessorPerformanceInformation
:
/* 8 */
...
...
@@ -2858,9 +2872,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
}
case
SystemExtendedProcessInformation
:
/* 57 */
FIXME
(
"SystemExtendedProcessInformation, size %u, info %p, stub!
\n
"
,
size
,
info
);
memset
(
info
,
0
,
size
);
ret
=
STATUS_SUCCESS
;
ret
=
get_system_process_info
(
class
,
info
,
size
,
&
len
);
break
;
case
SystemRecommendedSharedDataAlignment
:
/* 58 */
...
...
include/wine/server_protocol.h
View file @
98a54663
...
...
@@ -2001,6 +2001,8 @@ struct thread_info
int
base_priority
;
int
current_priority
;
int
unix_tid
;
client_ptr_t
teb
;
client_ptr_t
entry_point
;
};
struct
process_info
...
...
@@ -6261,7 +6263,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 73
4
#define SERVER_PROTOCOL_VERSION 73
5
/* ### protocol_version end ### */
...
...
include/winternl.h
View file @
98a54663
...
...
@@ -2005,6 +2005,18 @@ typedef struct _SYSTEM_THREAD_INFORMATION
DWORD
dwUnknown
;
/* 3c/4c */
}
SYSTEM_THREAD_INFORMATION
,
*
PSYSTEM_THREAD_INFORMATION
;
typedef
struct
_SYSTEM_EXTENDED_THREAD_INFORMATION
{
SYSTEM_THREAD_INFORMATION
ThreadInfo
;
/* 00/00 */
void
*
StackBase
;
/* 40/50 */
void
*
StackLimit
;
/* 44/58 */
void
*
Win32StartAddress
;
/* 48/60 */
void
*
TebBase
;
/* 4c/68 */
ULONG_PTR
Reserved2
;
/* 50/70 */
ULONG_PTR
Reserved3
;
/* 54/78 */
ULONG_PTR
Reserved4
;
/* 58/80 */
}
SYSTEM_EXTENDED_THREAD_INFORMATION
,
*
PSYSTEM_EXTENDED_THREAD_INFORMATION
;
typedef
struct
_IO_STATUS_BLOCK
{
union
{
NTSTATUS
Status
;
...
...
server/process.c
View file @
98a54663
...
...
@@ -1920,6 +1920,8 @@ DECL_HANDLER(list_processes)
thread_info
->
base_priority
=
thread
->
priority
;
thread_info
->
current_priority
=
thread
->
priority
;
/* FIXME */
thread_info
->
unix_tid
=
thread
->
unix_tid
;
thread_info
->
entry_point
=
thread
->
entry_point
;
thread_info
->
teb
=
thread
->
teb
;
pos
+=
sizeof
(
*
thread_info
);
}
}
...
...
server/protocol.def
View file @
98a54663
...
...
@@ -1602,6 +1602,8 @@ struct thread_info
int base_priority;
int current_priority;
int unix_tid;
client_ptr_t teb;
client_ptr_t entry_point;
};
struct process_info
...
...
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