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
445996d3
Commit
445996d3
authored
Nov 07, 2017
by
Hans Leidekker
Committed by
Alexandre Julliard
Nov 08, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32: Fix EnumServicesStatusEx on Wow64.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ac0744d4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
21 deletions
+84
-21
service.c
dlls/advapi32/service.c
+69
-13
svcctl.idl
include/wine/svcctl.idl
+7
-0
rpc.c
programs/services/rpc.c
+8
-8
No files found.
dlls/advapi32/service.c
View file @
445996d3
...
...
@@ -1893,9 +1893,11 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
LPBYTE
buffer
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPDWORD
resume_handle
,
LPCWSTR
group
)
{
DWORD
err
,
i
;
ENUM_SERVICE_STATUS_PROCESSW
dummy_status
;
DWORD
err
,
i
,
offset
,
buflen
,
count
,
total_size
=
0
;
ENUM_SERVICE_STATUS_PROCESSW
*
services
=
(
ENUM_SERVICE_STATUS_PROCESSW
*
)
buffer
;
struct
enum_service_status_process
*
entry
;
const
WCHAR
*
str
;
BYTE
*
buf
;
TRACE
(
"%p %u 0x%x 0x%x %p %u %p %p %p %s
\n
"
,
hmngr
,
level
,
type
,
state
,
buffer
,
size
,
needed
,
returned
,
resume_handle
,
debugstr_w
(
group
));
...
...
@@ -1910,18 +1912,24 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
if
(
!
needed
||
!
returned
)
{
SetLastError
(
ERROR_INVALID_ADDRESS
);
return
FALSE
;
}
/* make sure we pass a valid buffer pointer */
if
(
!
services
||
size
<
sizeof
(
*
services
))
/* make sure we pass a valid pointer */
buflen
=
max
(
size
,
sizeof
(
*
services
)
);
if
(
!
(
buf
=
heap_alloc
(
buflen
)))
{
buffer
=
(
BYTE
*
)
&
dummy_status
;
size
=
sizeof
(
dummy_status
)
;
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
)
;
return
FALSE
;
}
__TRY
{
err
=
svcctl_EnumServicesStatusExW
(
hmngr
,
SC_ENUM_PROCESS_INFO
,
type
,
state
,
buf
fer
,
size
,
needed
,
returned
,
resume_handle
,
group
);
err
=
svcctl_EnumServicesStatusExW
(
hmngr
,
SC_ENUM_PROCESS_INFO
,
type
,
state
,
buf
,
buflen
,
needed
,
&
count
,
resume_handle
,
group
);
}
__EXCEPT
(
rpc_filter
)
{
...
...
@@ -1929,20 +1937,68 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
}
__ENDTRY
*
returned
=
0
;
if
(
err
!=
ERROR_SUCCESS
)
{
/* double the needed size to fit the potentially larger ENUM_SERVICE_STATUS_PROCESSW */
if
(
err
==
ERROR_MORE_DATA
)
*
needed
*=
2
;
heap_free
(
buf
);
SetLastError
(
err
);
return
FALSE
;
}
for
(
i
=
0
;
i
<
*
returned
;
i
++
)
entry
=
(
struct
enum_service_status_process
*
)
buf
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
/* convert buffer offsets into pointers */
services
[
i
].
lpServiceName
=
(
WCHAR
*
)((
char
*
)
services
+
(
DWORD_PTR
)
services
[
i
].
lpServiceName
);
if
(
services
[
i
].
lpDisplayName
)
services
[
i
].
lpDisplayName
=
(
WCHAR
*
)((
char
*
)
services
+
(
DWORD_PTR
)
services
[
i
].
lpDisplayName
);
total_size
+=
sizeof
(
*
services
);
if
(
entry
->
service_name
)
{
str
=
(
const
WCHAR
*
)(
buf
+
entry
->
service_name
);
total_size
+=
(
strlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
}
if
(
entry
->
display_name
)
{
str
=
(
const
WCHAR
*
)(
buf
+
entry
->
display_name
);
total_size
+=
(
strlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
}
entry
++
;
}
if
(
total_size
>
size
)
{
heap_free
(
buf
);
*
needed
=
total_size
;
SetLastError
(
ERROR_MORE_DATA
);
return
FALSE
;
}
offset
=
count
*
sizeof
(
*
services
);
entry
=
(
struct
enum_service_status_process
*
)
buf
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
DWORD
str_size
;
str
=
(
const
WCHAR
*
)(
buf
+
entry
->
service_name
);
str_size
=
(
strlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
services
[
i
].
lpServiceName
=
(
WCHAR
*
)((
char
*
)
services
+
offset
);
memcpy
(
services
[
i
].
lpServiceName
,
str
,
str_size
);
offset
+=
str_size
;
if
(
!
entry
->
display_name
)
services
[
i
].
lpDisplayName
=
NULL
;
else
{
str
=
(
const
WCHAR
*
)(
buf
+
entry
->
display_name
);
str_size
=
(
strlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
services
[
i
].
lpDisplayName
=
(
WCHAR
*
)((
char
*
)
services
+
offset
);
memcpy
(
services
[
i
].
lpDisplayName
,
str
,
str_size
);
offset
+=
str_size
;
}
services
[
i
].
ServiceStatusProcess
=
entry
->
service_status_process
;
entry
++
;
}
heap_free
(
buf
);
*
needed
=
0
;
*
returned
=
count
;
return
TRUE
;
}
...
...
include/wine/svcctl.idl
View file @
445996d3
...
...
@@ -218,6 +218,13 @@ struct enum_service_status
SERVICE_STATUS service_status;
};
struct enum_service_status_process
{
DWORD service_name;
DWORD display_name;
SERVICE_STATUS_PROCESS service_status_process;
};
typedef struct _SERVICE_RPC_REQUIRED_PRIVILEGES_INFO {
DWORD cbRequiredPrivileges;
[size_is(cbRequiredPrivileges)] BYTE *pRequiredPrivileges;
...
...
programs/services/rpc.c
View file @
445996d3
...
...
@@ -1461,7 +1461,7 @@ DWORD __cdecl svcctl_EnumServicesStatusExW(
DWORD_PTR
offset
;
struct
sc_manager_handle
*
manager
;
struct
service_entry
*
service
;
ENUM_SERVICE_STATUS_PROCESSW
*
s
;
struct
enum_service_status_process
*
s
;
WINE_TRACE
(
"(%p, 0x%x, 0x%x, %p, %u, %p, %p, %s)
\n
"
,
hmngr
,
type
,
state
,
buffer
,
size
,
needed
,
returned
,
wine_dbgstr_w
(
group
));
...
...
@@ -1489,7 +1489,7 @@ DWORD __cdecl svcctl_EnumServicesStatusExW(
if
((
service
->
status
.
dwServiceType
&
type
)
&&
map_state
(
service
->
status
.
dwCurrentState
,
state
)
&&
match_group
(
service
->
config
.
lpLoadOrderGroup
,
group
))
{
total_size
+=
sizeof
(
ENUM_SERVICE_STATUS_PROCESSW
);
total_size
+=
sizeof
(
*
s
);
total_size
+=
(
strlenW
(
service
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
if
(
service
->
config
.
lpDisplayName
)
{
...
...
@@ -1505,8 +1505,8 @@ DWORD __cdecl svcctl_EnumServicesStatusExW(
scmdatabase_unlock
(
manager
->
db
);
return
ERROR_MORE_DATA
;
}
s
=
(
ENUM_SERVICE_STATUS_PROCESSW
*
)
buffer
;
offset
=
num_services
*
sizeof
(
ENUM_SERVICE_STATUS_PROCESSW
);
s
=
(
struct
enum_service_status_process
*
)
buffer
;
offset
=
num_services
*
sizeof
(
*
s
);
LIST_FOR_EACH_ENTRY
(
service
,
&
manager
->
db
->
services
,
struct
service_entry
,
entry
)
{
if
((
service
->
status
.
dwServiceType
&
type
)
&&
map_state
(
service
->
status
.
dwCurrentState
,
state
)
...
...
@@ -1514,18 +1514,18 @@ DWORD __cdecl svcctl_EnumServicesStatusExW(
{
sz
=
(
strlenW
(
service
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
buffer
+
offset
,
service
->
name
,
sz
);
s
->
lpServiceName
=
(
WCHAR
*
)
offset
;
/* store a buffer offset instead of a pointer */
s
->
service_name
=
offset
;
offset
+=
sz
;
if
(
!
service
->
config
.
lpDisplayName
)
s
->
lpDisplayName
=
NULL
;
if
(
!
service
->
config
.
lpDisplayName
)
s
->
display_name
=
0
;
else
{
sz
=
(
strlenW
(
service
->
config
.
lpDisplayName
)
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
buffer
+
offset
,
service
->
config
.
lpDisplayName
,
sz
);
s
->
lpDisplayName
=
(
WCHAR
*
)
offset
;
s
->
display_name
=
offset
;
offset
+=
sz
;
}
fill_status_process
(
&
s
->
ServiceStatusP
rocess
,
service
);
fill_status_process
(
&
s
->
service_status_p
rocess
,
service
);
s
++
;
}
}
...
...
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