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
c56971ff
Commit
c56971ff
authored
Jan 30, 2023
by
Eric Pouech
Committed by
Alexandre Julliard
Feb 13, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Implement EnumProcessModulesEx.
Signed-off-by:
Eric Pouech
<
eric.pouech@gmail.com
>
parent
84a9a1c8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
159 additions
and
21 deletions
+159
-21
debug.c
dlls/kernelbase/debug.c
+140
-9
psapi_main.c
dlls/psapi/tests/psapi_main.c
+19
-12
No files found.
dlls/kernelbase/debug.c
View file @
c56971ff
...
...
@@ -772,19 +772,19 @@ struct module_iterator
};
static
BOOL
init_module_iterator
(
struct
module_iterator
*
iter
,
HANDLE
process
)
/* Caller must ensure that wow64=TRUE is only passed from 64bit for 'process' being a wow64 process */
static
BOOL
init_module_iterator
(
struct
module_iterator
*
iter
,
HANDLE
process
,
BOOL
wow64
)
{
PROCESS_BASIC_INFORMATION
pbi
;
PPEB_LDR_DATA
ldr_data
;
if
(
!
IsWow64Process
(
process
,
&
iter
->
wow64
))
return
FALSE
;
/* get address of PEB */
if
(
!
set_ntstatus
(
NtQueryInformationProcess
(
process
,
ProcessBasicInformation
,
&
pbi
,
sizeof
(
pbi
),
NULL
)))
return
FALSE
;
if
(
is_win64
&&
iter
->
wow64
)
iter
->
wow64
=
wow64
;
if
(
wow64
)
{
PEB_LDR_DATA32
*
ldr_data32_ptr
;
DWORD
ldr_data32
,
first_module
;
...
...
@@ -807,6 +807,12 @@ static BOOL init_module_iterator( struct module_iterator *iter, HANDLE process )
if
(
!
ReadProcessMemory
(
process
,
&
pbi
.
PebBaseAddress
->
LdrData
,
&
ldr_data
,
sizeof
(
ldr_data
),
NULL
))
return
FALSE
;
/* This happens when running "old" wow64 configuration. Mark it as such. */
if
(
!
ldr_data
)
{
SetLastError
(
ERROR_EMPTY
);
return
FALSE
;
}
/* read address of first module from LdrData */
if
(
!
ReadProcessMemory
(
process
,
&
ldr_data
->
InLoadOrderModuleList
.
Flink
,
&
iter
->
current
,
sizeof
(
iter
->
current
),
NULL
))
...
...
@@ -849,7 +855,7 @@ static BOOL get_ldr_module( HANDLE process, HMODULE module, LDR_DATA_TABLE_ENTRY
struct
module_iterator
iter
;
INT
ret
;
if
(
!
init_module_iterator
(
&
iter
,
process
))
return
FALSE
;
if
(
!
init_module_iterator
(
&
iter
,
process
,
FALSE
))
return
FALSE
;
while
((
ret
=
module_iterator_next
(
&
iter
))
>
0
)
/* When hModule is NULL we return the process image - which will be
...
...
@@ -870,7 +876,7 @@ static BOOL get_ldr_module32( HANDLE process, HMODULE module, LDR_DATA_TABLE_ENT
struct
module_iterator
iter
;
INT
ret
;
if
(
!
init_module_iterator
(
&
iter
,
process
))
return
FALSE
;
if
(
!
init_module_iterator
(
&
iter
,
process
,
TRUE
))
return
FALSE
;
while
((
ret
=
module_iterator_next
(
&
iter
))
>
0
)
/* When hModule is NULL we return the process image - which will be
...
...
@@ -939,6 +945,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumProcessModules( HANDLE process, HMODULE *modul
{
struct
module_iterator
iter
;
DWORD
size
=
0
;
BOOL
target_wow64
;
INT
ret
;
if
(
process
==
GetCurrentProcess
())
...
...
@@ -972,7 +979,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumProcessModules( HANDLE process, HMODULE *modul
return
TRUE
;
}
if
(
!
init_module_iterator
(
&
iter
,
process
))
return
FALSE
;
if
(
!
IsWow64Process
(
process
,
&
target_wow64
))
return
FALSE
;
if
(
!
init_module_iterator
(
&
iter
,
process
,
is_win64
&&
target_wow64
))
return
FALSE
;
if
(
count
&&
!
module
)
{
...
...
@@ -1003,6 +1011,41 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumProcessModules( HANDLE process, HMODULE *modul
}
struct
module_push
{
HMODULE
*
module
;
unsigned
count
;
unsigned
size
;
};
static
void
module_push
(
struct
module_push
*
mp
,
HMODULE
module
)
{
if
(
mp
->
count
>=
sizeof
(
HMODULE
))
{
*
mp
->
module
++
=
module
;
mp
->
count
-=
sizeof
(
HMODULE
);
}
mp
->
size
+=
sizeof
(
HMODULE
);
}
static
void
module_push_iter
(
struct
module_push
*
mp
,
struct
module_iterator
*
iter
)
{
if
(
is_win64
&&
iter
->
wow64
)
module_push
(
mp
,
(
HMODULE
)
(
DWORD_PTR
)
iter
->
ldr_module32
.
BaseAddress
);
else
module_push
(
mp
,
iter
->
ldr_module
.
DllBase
);
}
static
int
module_push_all
(
struct
module_push
*
mp
,
struct
module_iterator
*
iter
)
{
int
ret
;
while
((
ret
=
module_iterator_next
(
iter
))
>
0
)
module_push_iter
(
mp
,
iter
);
return
ret
;
}
/***********************************************************************
* EnumProcessModulesEx (kernelbase.@)
* K32EnumProcessModulesEx (kernelbase.@)
...
...
@@ -1010,8 +1053,96 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumProcessModules( HANDLE process, HMODULE *modul
BOOL
WINAPI
EnumProcessModulesEx
(
HANDLE
process
,
HMODULE
*
module
,
DWORD
count
,
DWORD
*
needed
,
DWORD
filter
)
{
FIXME
(
"(%p, %p, %ld, %p, %ld) semi-stub
\n
"
,
process
,
module
,
count
,
needed
,
filter
);
return
EnumProcessModules
(
process
,
module
,
count
,
needed
);
struct
module_push
mp
=
{
module
,
count
,
0
};
unsigned
list_mode
;
BOOL
target_wow64
;
INT
ret
=
0
;
TRACE
(
"(%p, %p, %ld, %p, %ld)
\n
"
,
process
,
module
,
count
,
needed
,
filter
);
if
(
process
!=
GetCurrentProcess
())
{
if
(
!
IsWow64Process
(
process
,
&
target_wow64
))
return
FALSE
;
}
else
target_wow64
=
is_wow64
;
if
(
filter
&
~
LIST_MODULES_ALL
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
list_mode
=
filter
&
LIST_MODULES_ALL
;
/* Can't access 64bit process from (wow64) 32bit */
if
(
is_wow64
&&
!
target_wow64
)
{
SetLastError
(
ERROR_PARTIAL_COPY
);
return
FALSE
;
}
if
(
count
&&
!
module
)
{
SetLastError
(
ERROR_NOACCESS
);
return
FALSE
;
}
if
(
process
==
GetCurrentProcess
())
{
if
(
!
(
is_win64
&&
list_mode
==
LIST_MODULES_32BIT
))
{
PPEB_LDR_DATA
ldr_data
=
NtCurrentTeb
()
->
Peb
->
LdrData
;
PLIST_ENTRY
head
=
&
ldr_data
->
InLoadOrderModuleList
;
PLIST_ENTRY
entry
=
head
->
Flink
;
while
(
entry
!=
head
)
{
LDR_DATA_TABLE_ENTRY
*
ldr
=
CONTAINING_RECORD
(
entry
,
LDR_DATA_TABLE_ENTRY
,
InLoadOrderLinks
);
module_push
(
&
mp
,
ldr
->
DllBase
);
entry
=
entry
->
Flink
;
}
}
}
else
{
struct
module_iterator
iter
;
if
(
is_win64
&&
target_wow64
&&
(
list_mode
&
LIST_MODULES_32BIT
))
{
if
(
!
init_module_iterator
(
&
iter
,
process
,
TRUE
)
||
module_push_all
(
&
mp
,
&
iter
)
<
0
)
return
FALSE
;
}
if
(
!
(
is_win64
&&
list_mode
==
LIST_MODULES_32BIT
))
{
if
(
init_module_iterator
(
&
iter
,
process
,
FALSE
))
{
if
(
is_win64
&&
target_wow64
&&
(
list_mode
&
LIST_MODULES_64BIT
))
/* Don't add main module twice in _ALL mode */
ret
=
module_iterator_next
(
&
iter
);
if
(
ret
>=
0
)
ret
=
module_push_all
(
&
mp
,
&
iter
);
}
else
if
(
GetLastError
()
==
ERROR_EMPTY
)
{
/* We're running on "old" wow configuration.
* Fallback to PEB32 to get at least main module if requested.
*/
if
(
list_mode
==
LIST_MODULES_DEFAULT
)
{
if
(
init_module_iterator
(
&
iter
,
process
,
TRUE
)
&&
module_iterator_next
(
&
iter
)
>
0
)
module_push_iter
(
&
mp
,
&
iter
);
else
ret
=
-
1
;
}
}
else
return
FALSE
;
}
}
if
(
!
needed
)
{
SetLastError
(
ERROR_NOACCESS
);
return
FALSE
;
}
*
needed
=
mp
.
size
;
return
ret
==
0
;
}
...
...
dlls/psapi/tests/psapi_main.c
View file @
c56971ff
...
...
@@ -215,6 +215,10 @@ static BOOL test_EnumProcessModulesEx_snapshot(HANDLE proc, struct moduleex_snap
MODULEINFO
info
;
int
i
,
j
;
BOOL
ret
;
BOOL
fail
,
wow64
;
ret
=
IsWow64Process
(
proc
,
&
wow64
);
ok
(
ret
,
"IsWow64Process failed: %lu
\n
"
,
GetLastError
());
for
(
i
=
0
;
i
<
numsnap
;
i
++
)
{
...
...
@@ -227,16 +231,29 @@ static BOOL test_EnumProcessModulesEx_snapshot(HANDLE proc, struct moduleex_snap
mxsnap
[
i
].
num_modules
=
min
(
needed
,
sizeof
(
mxsnap
[
i
].
modules
))
/
sizeof
(
HMODULE
);
for
(
j
=
0
;
j
<
mxsnap
[
i
].
num_modules
;
j
++
)
{
/* temporary todo until GetModuleBaseName and friends are fixed */
if
((
fail
=
sizeof
(
void
*
)
==
8
&&
wow64
))
switch
(
mxsnap
[
i
].
list
)
{
case
LIST_MODULES_32BIT
:
fail
=
FALSE
;
break
;
case
LIST_MODULES_DEFAULT
:
fail
=
j
>=
1
;
break
;
case
LIST_MODULES_ALL
:
fail
=
j
>=
mxsnap
[
0
].
num_modules
;
break
;
case
LIST_MODULES_64BIT
:
break
;
}
ret
=
GetModuleBaseNameA
(
proc
,
mxsnap
[
i
].
modules
[
j
],
buffer
,
sizeof
(
buffer
));
todo_wine_if
(
fail
)
ok
(
ret
,
"GetModuleBaseName failed: %lu (%u/%lu=%p)
\n
"
,
GetLastError
(),
j
,
mxsnap
[
i
].
num_modules
,
mxsnap
[
i
].
modules
[
j
]);
ret
=
GetModuleFileNameExA
(
proc
,
mxsnap
[
i
].
modules
[
j
],
buffer
,
sizeof
(
buffer
));
todo_wine_if
(
fail
)
ok
(
ret
,
"GetModuleFileNameEx failed: %lu (%u/%lu=%p)
\n
"
,
GetLastError
(),
j
,
mxsnap
[
i
].
num_modules
,
mxsnap
[
i
].
modules
[
j
]);
memset
(
&
info
,
0
,
sizeof
(
info
));
ret
=
GetModuleInformation
(
proc
,
mxsnap
[
i
].
modules
[
j
],
&
info
,
sizeof
(
info
));
todo_wine_if
(
fail
)
{
ok
(
ret
,
"GetModuleInformation failed: %lu
\n
"
,
GetLastError
());
ok
(
info
.
lpBaseOfDll
==
mxsnap
[
i
].
modules
[
j
],
"expected %p, got %p
\n
"
,
mxsnap
[
i
].
modules
[
j
],
info
.
lpBaseOfDll
);
ok
(
info
.
SizeOfImage
,
"image size was 0
\n
"
);
/* info.EntryPoint to be checked */
}
}
winetest_pop_context
();
}
...
...
@@ -356,7 +373,6 @@ static void test_EnumProcessModulesEx(void)
if
(
sizeof
(
void
*
)
==
8
)
{
test_EnumProcessModulesEx_snapshot
(
hpQV
,
snap
,
ARRAY_SIZE
(
snap
));
todo_wine
ok
(
snapshot_is_empty
(
&
snap
[
0
]),
"didn't expect 32bit module
\n
"
);
ok
(
snapshot_is_equal
(
&
snap
[
1
],
&
snap
[
2
]),
"mismatch in modules count
\n
"
);
ok
(
snapshot_is_equal
(
&
snap
[
2
],
&
snap
[
3
]),
"mismatch in modules count
\n
"
);
...
...
@@ -369,9 +385,7 @@ static void test_EnumProcessModulesEx(void)
*/
SetLastError
(
0xdeadbeef
);
ret
=
EnumProcessModulesEx
(
hpQV
,
&
hMod
,
sizeof
(
HMODULE
),
&
cbNeeded
,
0x400
);
todo_wine
ok
(
!
ret
,
"succeeded
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"expected error=ERROR_INVALID_PARAMETER but got %ld
\n
"
,
GetLastError
());
}
else
if
(
wow64
)
...
...
@@ -397,7 +411,6 @@ static void test_EnumProcessModulesEx(void)
{
winetest_push_context
(
"pcs-6464"
);
test_EnumProcessModulesEx_snapshot
(
pi
.
hProcess
,
snap
,
ARRAY_SIZE
(
snap
));
todo_wine
ok
(
snapshot_is_empty
(
&
snap
[
0
]),
"didn't expect 32bit module
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
1
],
&
snap
[
2
]),
"64bit and default module lists should match
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
2
],
&
snap
[
3
]),
"default and all module lists should match
\n
"
);
...
...
@@ -411,9 +424,7 @@ static void test_EnumProcessModulesEx(void)
*/
SetLastError
(
0xdeadbeef
);
ret
=
EnumProcessModulesEx
(
hpQV
,
&
hMod
,
sizeof
(
HMODULE
),
&
cbNeeded
,
0x400
);
todo_wine
ok
(
!
ret
,
"succeeded
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"expected error=ERROR_INVALID_PARAMETER but got %ld
\n
"
,
GetLastError
());
}
else
if
(
wow64
)
...
...
@@ -446,20 +457,19 @@ static void test_EnumProcessModulesEx(void)
winetest_push_context
(
"pcs-6432"
);
test_EnumProcessModulesEx_snapshot
(
pi
.
hProcess
,
snap
,
ARRAY_SIZE
(
snap
));
ok
(
!
snapshot_is_empty
(
&
snap
[
0
]),
"expecting 32bit modules
\n
"
);
/* FIXME: this tests fails on Wine "old" wow configuration, but succceeds in "multi-arch" and Windows */
todo_wine_if
(
snapshot_is_empty
(
&
snap
[
1
]))
ok
(
!
snapshot_is_empty
(
&
snap
[
1
]),
"expecting 64bit modules
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
1
],
&
snap
[
2
]),
"64bit and default module lists should match
\n
"
);
todo_wine
ok
(
snapshot_are_disjoint
(
&
snap
[
0
],
&
snap
[
1
],
0
),
"32bit and 64bit list should be disjoint
\n
"
);
/* Main module (even 32bit) is present in both 32bit (makes sense) but also default
* (even if all the other modules are 64bit)
*/
todo_wine
ok
(
snapshot_are_disjoint
(
&
snap
[
0
],
&
snap
[
2
],
1
),
"32bit and default list should be disjoint
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
0
],
&
snap
[
3
]),
"32bit and all module lists should match
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
1
],
&
snap
[
3
]),
"64bit and all module lists should match
\n
"
);
ok
(
snapshot_is_subset
(
&
snap
[
2
],
&
snap
[
3
]),
"default and all module list should match
\n
"
);
snapshot_check_first_main_module
(
&
snap
[
0
],
pi
.
hProcess
,
buffer
);
todo_wine
ok
(
!
snapshot_contains
(
&
snap
[
1
],
snap
[
0
].
modules
[
0
]),
"main module shouldn't be present in 64bit list
\n
"
);
snapshot_check_first_main_module
(
&
snap
[
2
],
pi
.
hProcess
,
buffer
);
snapshot_check_first_main_module
(
&
snap
[
3
],
pi
.
hProcess
,
buffer
);
...
...
@@ -469,9 +479,7 @@ static void test_EnumProcessModulesEx(void)
*/
SetLastError
(
0xdeadbeef
);
ret
=
EnumProcessModulesEx
(
hpQV
,
&
hMod
,
sizeof
(
HMODULE
),
&
cbNeeded
,
0x400
);
todo_wine
ok
(
!
ret
,
"succeeded
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"expected error=ERROR_INVALID_PARAMETER but got %ld
\n
"
,
GetLastError
());
winetest_pop_context
();
...
...
@@ -503,7 +511,6 @@ static void test_EnumProcessModulesEx(void)
SetLastError
(
0xdeadbeef
);
ret
=
EnumProcessModulesEx
(
pi
.
hProcess
,
&
hMod
,
sizeof
(
HMODULE
),
&
cbNeeded
,
snap
[
i
].
list
);
ok
(
!
ret
,
"succeeded
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_PARTIAL_COPY
,
"expected error=ERROR_PARTIAL_COPY but got %ld
\n
"
,
GetLastError
());
}
winetest_pop_context
();
...
...
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