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
ae7d41bf
Commit
ae7d41bf
authored
Oct 27, 2010
by
Hans Leidekker
Committed by
Alexandre Julliard
Oct 27, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32: Implement EnumServicesStatusA/W.
parent
c287ed22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
201 additions
and
27 deletions
+201
-27
service.c
dlls/advapi32/service.c
+89
-18
service.c
dlls/advapi32/tests/service.c
+0
-0
svcctl.idl
include/wine/svcctl.idl
+15
-1
rpc.c
programs/services/rpc.c
+97
-8
No files found.
dlls/advapi32/service.c
View file @
ae7d41bf
...
...
@@ -1455,32 +1455,103 @@ BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffe
* EnumServicesStatusA [ADVAPI32.@]
*/
BOOL
WINAPI
EnumServicesStatusA
(
SC_HANDLE
hSCManager
,
DWORD
dwServiceType
,
DWORD
dwServiceState
,
LPENUM_SERVICE_STATUSA
lpServices
,
DWORD
cbBufSize
,
LPDWORD
pcbBytesNeeded
,
LPDWORD
lpServicesReturned
,
LPDWORD
lpResumeHandle
)
EnumServicesStatusA
(
SC_HANDLE
hmngr
,
DWORD
type
,
DWORD
state
,
LPENUM_SERVICE_STATUSA
services
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPDWORD
resume_handle
)
{
FIXME
(
"%p type=%x state=%x %p %x %p %p %p
\n
"
,
hSCManager
,
dwServiceType
,
dwServiceState
,
lpServices
,
cbBufSize
,
pcbBytesNeeded
,
lpServicesReturned
,
lpResumeHandle
);
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
BOOL
ret
;
unsigned
int
i
;
ENUM_SERVICE_STATUSW
*
servicesW
=
NULL
;
DWORD
sz
,
n
;
char
*
p
;
TRACE
(
"%p 0x%x 0x%x %p %u %p %p %p
\n
"
,
hmngr
,
type
,
state
,
services
,
size
,
needed
,
returned
,
resume_handle
);
if
(
size
&&
!
(
servicesW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
2
*
size
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
ret
=
EnumServicesStatusW
(
hmngr
,
type
,
state
,
servicesW
,
2
*
size
,
needed
,
returned
,
resume_handle
);
if
(
!
ret
)
goto
done
;
p
=
(
char
*
)
services
+
*
returned
*
sizeof
(
ENUM_SERVICE_STATUSA
);
n
=
size
-
(
p
-
(
char
*
)
services
);
ret
=
FALSE
;
for
(
i
=
0
;
i
<
*
returned
;
i
++
)
{
sz
=
WideCharToMultiByte
(
CP_ACP
,
0
,
servicesW
[
i
].
lpServiceName
,
-
1
,
p
,
n
,
NULL
,
NULL
);
if
(
!
sz
)
goto
done
;
services
[
i
].
lpServiceName
=
p
;
p
+=
sz
;
n
-=
sz
;
if
(
servicesW
[
i
].
lpDisplayName
)
{
sz
=
WideCharToMultiByte
(
CP_ACP
,
0
,
servicesW
[
i
].
lpDisplayName
,
-
1
,
p
,
n
,
NULL
,
NULL
);
if
(
!
sz
)
goto
done
;
services
[
i
].
lpDisplayName
=
p
;
p
+=
sz
;
n
-=
sz
;
}
services
[
i
].
ServiceStatus
=
servicesW
[
i
].
ServiceStatus
;
}
ret
=
TRUE
;
done:
HeapFree
(
GetProcessHeap
(),
0
,
servicesW
);
return
ret
;
}
/******************************************************************************
* EnumServicesStatusW [ADVAPI32.@]
*/
BOOL
WINAPI
EnumServicesStatusW
(
SC_HANDLE
hSCManager
,
DWORD
dwServiceType
,
DWORD
dwServiceState
,
LPENUM_SERVICE_STATUSW
lpServices
,
DWORD
cbBufSize
,
LPDWORD
pcbBytesNeeded
,
LPDWORD
lpServicesReturned
,
LPDWORD
lpResumeHandle
)
EnumServicesStatusW
(
SC_HANDLE
hmngr
,
DWORD
type
,
DWORD
state
,
LPENUM_SERVICE_STATUSW
services
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPDWORD
resume_handle
)
{
FIXME
(
"%p type=%x state=%x %p %x %p %p %p
\n
"
,
hSCManager
,
dwServiceType
,
dwServiceState
,
lpServices
,
cbBufSize
,
pcbBytesNeeded
,
lpServicesReturned
,
lpResumeHandle
);
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
DWORD
err
,
i
;
TRACE
(
"%p 0x%x 0x%x %p %u %p %p %p
\n
"
,
hmngr
,
type
,
state
,
services
,
size
,
needed
,
returned
,
resume_handle
);
if
(
resume_handle
)
FIXME
(
"resume handle not supported
\n
"
);
if
(
!
hmngr
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
__TRY
{
err
=
svcctl_EnumServicesStatusW
(
hmngr
,
type
,
state
,
(
BYTE
*
)
services
,
size
,
needed
,
returned
);
}
__EXCEPT
(
rpc_filter
)
{
err
=
map_exception_code
(
GetExceptionCode
()
);
}
__ENDTRY
if
(
err
!=
ERROR_SUCCESS
)
{
SetLastError
(
err
);
return
FALSE
;
}
for
(
i
=
0
;
i
<
*
returned
;
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
);
}
return
TRUE
;
}
/******************************************************************************
...
...
dlls/advapi32/tests/service.c
View file @
ae7d41bf
This diff is collapsed.
Click to expand it.
include/wine/svcctl.idl
View file @
ae7d41bf
...
...
@@ -122,6 +122,12 @@ typedef struct _SERVICE_FAILURE_ACTIONSW {
#
define
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO
6
#
define
SERVICE_CONFIG_PRESHUTDOWN_INFO
7
typedef
struct
_ENUM_SERVICE_STATUSW
{
LPWSTR
lpServiceName
;
LPWSTR
lpDisplayName
;
SERVICE_STATUS
ServiceStatus
;
}
ENUM_SERVICE_STATUSW
,
*
LPENUM_SERVICE_STATUSW
;
cpp_quote
(
"#endif"
)
typedef
[
switch_type
(
DWORD
)
]
union
...
...
@@ -220,7 +226,15 @@ typedef [switch_type(DWORD)] union
DWORD
svcctl_EnumDependentServicesW
(/*
FIXME
*/)
;
/*
Not
compatible
with
Windows
function
0
x0e
*/
DWORD
svcctl_EnumServicesStatusW
(/*
FIXME
*/)
;
DWORD
svcctl_EnumServicesStatusW
(
[
in
]
SC_RPC_HANDLE
hmngr
,
[
in
]
DWORD
type
,
[
in
]
DWORD
state
,
[
out
,
size_is
(
size
)
]
BYTE
*
buffer
,
[
in
]
DWORD
size
,
[
out
]
LPDWORD
needed
,
[
out
]
LPDWORD
returned
)
;
/*
Compatible
with
Windows
function
0
x0f
*/
DWORD
svcctl_OpenSCManagerW
(
...
...
programs/services/rpc.c
View file @
ae7d41bf
...
...
@@ -1115,6 +1115,103 @@ DWORD svcctl_UnlockServiceDatabase(
return
ERROR_SUCCESS
;
}
static
BOOL
map_state
(
DWORD
state
,
DWORD
mask
)
{
switch
(
state
)
{
case
SERVICE_START_PENDING
:
case
SERVICE_STOP_PENDING
:
case
SERVICE_RUNNING
:
case
SERVICE_CONTINUE_PENDING
:
case
SERVICE_PAUSE_PENDING
:
case
SERVICE_PAUSED
:
if
(
SERVICE_ACTIVE
&
mask
)
return
TRUE
;
break
;
case
SERVICE_STOPPED
:
if
(
SERVICE_INACTIVE
&
mask
)
return
TRUE
;
break
;
default:
WINE_ERR
(
"unknown state %u
\n
"
,
state
);
break
;
}
return
FALSE
;
}
DWORD
svcctl_EnumServicesStatusW
(
SC_RPC_HANDLE
hmngr
,
DWORD
type
,
DWORD
state
,
BYTE
*
buffer
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
)
{
DWORD
err
,
sz
,
total_size
,
num_services
;
DWORD_PTR
offset
;
struct
sc_manager_handle
*
manager
;
struct
service_entry
*
service
;
ENUM_SERVICE_STATUSW
*
s
;
WINE_TRACE
(
"(%p, 0x%x, 0x%x, %p, %u, %p, %p)
\n
"
,
hmngr
,
type
,
state
,
buffer
,
size
,
needed
,
returned
);
if
(
!
type
||
!
state
)
return
ERROR_INVALID_PARAMETER
;
if
((
err
=
validate_scm_handle
(
hmngr
,
SC_MANAGER_ENUMERATE_SERVICE
,
&
manager
))
!=
ERROR_SUCCESS
)
return
err
;
scmdatabase_lock_exclusive
(
manager
->
db
);
total_size
=
num_services
=
0
;
LIST_FOR_EACH_ENTRY
(
service
,
&
manager
->
db
->
services
,
struct
service_entry
,
entry
)
{
if
((
service
->
status
.
dwServiceType
&
type
)
&&
map_state
(
service
->
status
.
dwCurrentState
,
state
))
{
total_size
+=
sizeof
(
ENUM_SERVICE_STATUSW
);
total_size
+=
(
strlenW
(
service
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
if
(
service
->
config
.
lpDisplayName
)
{
total_size
+=
(
strlenW
(
service
->
config
.
lpDisplayName
)
+
1
)
*
sizeof
(
WCHAR
);
}
num_services
++
;
}
}
*
returned
=
0
;
*
needed
=
total_size
;
if
(
total_size
>
size
)
{
scmdatabase_unlock
(
manager
->
db
);
return
ERROR_MORE_DATA
;
}
s
=
(
ENUM_SERVICE_STATUSW
*
)
buffer
;
offset
=
num_services
*
sizeof
(
ENUM_SERVICE_STATUSW
);
LIST_FOR_EACH_ENTRY
(
service
,
&
manager
->
db
->
services
,
struct
service_entry
,
entry
)
{
if
((
service
->
status
.
dwServiceType
&
type
)
&&
map_state
(
service
->
status
.
dwCurrentState
,
state
))
{
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 */
offset
+=
sz
;
if
(
!
service
->
config
.
lpDisplayName
)
s
->
lpDisplayName
=
NULL
;
else
{
sz
=
(
strlenW
(
service
->
config
.
lpDisplayName
)
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
buffer
+
offset
,
service
->
config
.
lpDisplayName
,
sz
);
s
->
lpDisplayName
=
(
WCHAR
*
)
offset
;
offset
+=
sz
;
}
memcpy
(
&
s
->
ServiceStatus
,
&
service
->
status
,
sizeof
(
SERVICE_STATUS
));
s
++
;
}
}
*
returned
=
num_services
;
*
needed
=
0
;
scmdatabase_unlock
(
manager
->
db
);
return
ERROR_SUCCESS
;
}
DWORD
svcctl_QueryServiceObjectSecurity
(
void
)
{
...
...
@@ -1159,14 +1256,6 @@ DWORD svcctl_EnumDependentServicesW(
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
DWORD
svcctl_EnumServicesStatusW
(
void
)
{
WINE_FIXME
(
"
\n
"
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
DWORD
svcctl_QueryServiceLockStatusW
(
void
)
{
...
...
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