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
7135ac76
Commit
7135ac76
authored
Oct 29, 2010
by
Hans Leidekker
Committed by
Alexandre Julliard
Oct 29, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32: Implement EnumServicesStatusExA/W.
parent
27bf4c37
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
235 additions
and
64 deletions
+235
-64
service.c
dlls/advapi32/service.c
+113
-19
service.c
dlls/advapi32/tests/service.c
+7
-45
svcctl.idl
include/wine/svcctl.idl
+11
-0
rpc.c
programs/services/rpc.c
+104
-0
No files found.
dlls/advapi32/service.c
View file @
7135ac76
...
...
@@ -1558,31 +1558,125 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
* EnumServicesStatusExA [ADVAPI32.@]
*/
BOOL
WINAPI
EnumServicesStatusExA
(
SC_HANDLE
hSCManager
,
SC_ENUM_TYPE
InfoLevel
,
DWORD
dwServiceType
,
DWORD
dwServiceState
,
LPBYTE
lpServices
,
DWORD
cbBufSize
,
LPDWORD
pcbBytesNeeded
,
LPDWORD
lpServicesReturned
,
LPDWORD
lpResumeHandle
,
LPCSTR
pszGroupName
)
{
FIXME
(
"%p level=%d type=%x state=%x %p %x %p %p %p %s
\n
"
,
hSCManager
,
InfoLevel
,
dwServiceType
,
dwServiceState
,
lpServices
,
cbBufSize
,
pcbBytesNeeded
,
lpServicesReturned
,
lpResumeHandle
,
debugstr_a
(
pszGroupName
));
if
(
lpServicesReturned
)
*
lpServicesReturned
=
0
;
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
EnumServicesStatusExA
(
SC_HANDLE
hmngr
,
SC_ENUM_TYPE
level
,
DWORD
type
,
DWORD
state
,
LPBYTE
buffer
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPDWORD
resume_handle
,
LPCSTR
group
)
{
BOOL
ret
;
unsigned
int
i
;
ENUM_SERVICE_STATUS_PROCESSA
*
services
=
(
ENUM_SERVICE_STATUS_PROCESSA
*
)
buffer
;
ENUM_SERVICE_STATUS_PROCESSW
*
servicesW
=
NULL
;
WCHAR
*
groupW
=
NULL
;
DWORD
sz
,
n
;
char
*
p
;
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_a
(
group
));
if
(
size
&&
!
(
servicesW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
2
*
size
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
if
(
group
)
{
int
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
group
,
-
1
,
NULL
,
0
);
if
(
!
(
groupW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
HeapFree
(
GetProcessHeap
(),
0
,
servicesW
);
return
FALSE
;
}
MultiByteToWideChar
(
CP_ACP
,
0
,
group
,
-
1
,
groupW
,
len
*
sizeof
(
WCHAR
)
);
}
ret
=
EnumServicesStatusExW
(
hmngr
,
level
,
type
,
state
,
(
BYTE
*
)
servicesW
,
2
*
size
,
needed
,
returned
,
resume_handle
,
groupW
);
if
(
!
ret
)
goto
done
;
p
=
(
char
*
)
services
+
*
returned
*
sizeof
(
ENUM_SERVICE_STATUS_PROCESSA
);
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
].
ServiceStatusProcess
=
servicesW
[
i
].
ServiceStatusProcess
;
}
ret
=
TRUE
;
done:
HeapFree
(
GetProcessHeap
(),
0
,
servicesW
);
HeapFree
(
GetProcessHeap
(),
0
,
groupW
);
return
ret
;
}
/******************************************************************************
* EnumServicesStatusExW [ADVAPI32.@]
*/
BOOL
WINAPI
EnumServicesStatusExW
(
SC_HANDLE
hSCManager
,
SC_ENUM_TYPE
InfoLevel
,
DWORD
dwServiceType
,
DWORD
dwServiceState
,
LPBYTE
lpServices
,
DWORD
cbBufSize
,
LPDWORD
pcbBytesNeeded
,
LPDWORD
lpServicesReturned
,
LPDWORD
lpResumeHandle
,
LPCWSTR
pszGroupName
)
{
FIXME
(
"%p level=%d type=%x state=%x %p %x %p %p %p %s
\n
"
,
hSCManager
,
InfoLevel
,
dwServiceType
,
dwServiceState
,
lpServices
,
cbBufSize
,
pcbBytesNeeded
,
lpServicesReturned
,
lpResumeHandle
,
debugstr_w
(
pszGroupName
));
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
EnumServicesStatusExW
(
SC_HANDLE
hmngr
,
SC_ENUM_TYPE
level
,
DWORD
type
,
DWORD
state
,
LPBYTE
buffer
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPDWORD
resume_handle
,
LPCWSTR
group
)
{
DWORD
err
,
i
;
ENUM_SERVICE_STATUS_PROCESSW
*
services
=
(
ENUM_SERVICE_STATUS_PROCESSW
*
)
buffer
;
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
));
if
(
resume_handle
)
FIXME
(
"resume handle not supported
\n
"
);
if
(
level
!=
SC_ENUM_PROCESS_INFO
)
{
SetLastError
(
ERROR_INVALID_LEVEL
);
return
FALSE
;
}
if
(
!
hmngr
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
__TRY
{
err
=
svcctl_EnumServicesStatusExW
(
hmngr
,
type
,
state
,
buffer
,
size
,
needed
,
returned
,
group
);
}
__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 @
7135ac76
This diff is collapsed.
Click to expand it.
include/wine/svcctl.idl
View file @
7135ac76
...
...
@@ -352,4 +352,15 @@ typedef [switch_type(DWORD)] union
[
in
]
DWORD
cbBufSize
,
[
out
]
LPDWORD
pcbBytesNeeded
)
;
DWORD
svcctl_EnumServicesStatusExW
(
[
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
,
[
in
,
unique
]
LPCWSTR
group
)
;
}
programs/services/rpc.c
View file @
7135ac76
...
...
@@ -1212,6 +1212,110 @@ DWORD svcctl_EnumServicesStatusW(
return
ERROR_SUCCESS
;
}
struct
service_entry
*
find_service_by_group
(
struct
scmdatabase
*
db
,
const
WCHAR
*
group
)
{
struct
service_entry
*
service
;
LIST_FOR_EACH_ENTRY
(
service
,
&
db
->
services
,
struct
service_entry
,
entry
)
{
if
(
service
->
config
.
lpLoadOrderGroup
&&
!
strcmpiW
(
group
,
service
->
config
.
lpLoadOrderGroup
))
return
service
;
}
return
NULL
;
}
static
BOOL
match_group
(
const
WCHAR
*
g1
,
const
WCHAR
*
g2
)
{
if
(
!
g2
)
return
TRUE
;
if
(
!
g2
[
0
]
&&
(
!
g1
||
!
g1
[
0
]))
return
TRUE
;
if
(
g1
&&
!
strcmpW
(
g1
,
g2
))
return
TRUE
;
return
FALSE
;
}
DWORD
svcctl_EnumServicesStatusExW
(
SC_RPC_HANDLE
hmngr
,
DWORD
type
,
DWORD
state
,
BYTE
*
buffer
,
DWORD
size
,
LPDWORD
needed
,
LPDWORD
returned
,
LPCWSTR
group
)
{
DWORD
err
,
sz
,
total_size
,
num_services
;
DWORD_PTR
offset
;
struct
sc_manager_handle
*
manager
;
struct
service_entry
*
service
;
ENUM_SERVICE_STATUS_PROCESSW
*
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
));
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
);
if
(
group
&&
!
find_service_by_group
(
manager
->
db
,
group
))
{
scmdatabase_unlock
(
manager
->
db
);
return
ERROR_SERVICE_DOES_NOT_EXIST
;
}
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
)
&&
match_group
(
service
->
config
.
lpLoadOrderGroup
,
group
))
{
total_size
+=
sizeof
(
ENUM_SERVICE_STATUS_PROCESSW
);
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_STATUS_PROCESSW
*
)
buffer
;
offset
=
num_services
*
sizeof
(
ENUM_SERVICE_STATUS_PROCESSW
);
LIST_FOR_EACH_ENTRY
(
service
,
&
manager
->
db
->
services
,
struct
service_entry
,
entry
)
{
if
((
service
->
status
.
dwServiceType
&
type
)
&&
map_state
(
service
->
status
.
dwCurrentState
,
state
)
&&
match_group
(
service
->
config
.
lpLoadOrderGroup
,
group
))
{
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
;
}
s
->
ServiceStatusProcess
=
service
->
status
;
s
++
;
}
}
*
returned
=
num_services
;
*
needed
=
0
;
scmdatabase_unlock
(
manager
->
db
);
return
ERROR_SUCCESS
;
}
DWORD
svcctl_QueryServiceObjectSecurity
(
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