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
010dcb16
Commit
010dcb16
authored
Mar 16, 2008
by
Mikołaj Zalewski
Committed by
Alexandre Julliard
Mar 29, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Move GetServiceDisplayName to services.exe and implement GetServiceKeyName.
parent
76d4eeeb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
239 additions
and
61 deletions
+239
-61
service.c
dlls/advapi32/service.c
+73
-55
service.c
dlls/advapi32/tests/service.c
+64
-6
svcctl.idl
include/wine/svcctl.idl
+15
-0
rpc.c
programs/services/rpc.c
+87
-0
No files found.
dlls/advapi32/service.c
View file @
010dcb16
...
...
@@ -2135,8 +2135,44 @@ EnumServicesStatusExW(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServ
BOOL
WINAPI
GetServiceKeyNameA
(
SC_HANDLE
hSCManager
,
LPCSTR
lpDisplayName
,
LPSTR
lpServiceName
,
LPDWORD
lpcchBuffer
)
{
FIXME
(
"%p %s %p %p
\n
"
,
hSCManager
,
debugstr_a
(
lpDisplayName
),
lpServiceName
,
lpcchBuffer
);
return
FALSE
;
LPWSTR
lpDisplayNameW
,
lpServiceNameW
;
DWORD
sizeW
;
BOOL
ret
=
FALSE
;
TRACE
(
"%p %s %p %p
\n
"
,
hSCManager
,
debugstr_a
(
lpDisplayName
),
lpServiceName
,
lpcchBuffer
);
lpDisplayNameW
=
SERV_dup
(
lpDisplayName
);
if
(
lpServiceName
)
lpServiceNameW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
*
lpcchBuffer
*
sizeof
(
WCHAR
));
else
lpServiceNameW
=
NULL
;
sizeW
=
*
lpcchBuffer
;
if
(
!
GetServiceKeyNameW
(
hSCManager
,
lpDisplayNameW
,
lpServiceNameW
,
&
sizeW
))
{
if
(
*
lpcchBuffer
&&
lpServiceName
)
lpServiceName
[
0
]
=
0
;
*
lpcchBuffer
=
sizeW
*
2
;
/* we can only provide an upper estimation of string length */
goto
cleanup
;
}
if
(
!
WideCharToMultiByte
(
CP_ACP
,
0
,
lpServiceNameW
,
(
sizeW
+
1
),
lpServiceName
,
*
lpcchBuffer
,
NULL
,
NULL
))
{
if
(
*
lpcchBuffer
&&
lpServiceName
)
lpServiceName
[
0
]
=
0
;
*
lpcchBuffer
=
WideCharToMultiByte
(
CP_ACP
,
0
,
lpServiceNameW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
goto
cleanup
;
}
/* lpcchBuffer not updated - same as in GetServiceDisplayNameA */
ret
=
TRUE
;
cleanup:
HeapFree
(
GetProcessHeap
(),
0
,
lpServiceNameW
);
HeapFree
(
GetProcessHeap
(),
0
,
lpDisplayNameW
);
return
ret
;
}
/******************************************************************************
...
...
@@ -2145,8 +2181,31 @@ BOOL WINAPI GetServiceKeyNameA( SC_HANDLE hSCManager, LPCSTR lpDisplayName,
BOOL
WINAPI
GetServiceKeyNameW
(
SC_HANDLE
hSCManager
,
LPCWSTR
lpDisplayName
,
LPWSTR
lpServiceName
,
LPDWORD
lpcchBuffer
)
{
FIXME
(
"%p %s %p %p
\n
"
,
hSCManager
,
debugstr_w
(
lpDisplayName
),
lpServiceName
,
lpcchBuffer
);
return
FALSE
;
struct
sc_manager
*
hscm
;
DWORD
err
;
TRACE
(
"%p %s %p %p
\n
"
,
hSCManager
,
debugstr_w
(
lpServiceName
),
lpDisplayName
,
lpcchBuffer
);
hscm
=
sc_handle_get_handle_data
(
hSCManager
,
SC_HTYPE_MANAGER
);
if
(
!
hscm
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
if
(
!
lpDisplayName
)
{
SetLastError
(
ERROR_INVALID_ADDRESS
);
return
FALSE
;
}
err
=
svcctl_GetServiceKeyNameW
(
hscm
->
hdr
.
server_handle
,
lpDisplayName
,
lpServiceName
,
lpServiceName
?
*
lpcchBuffer
:
0
,
lpcchBuffer
);
if
(
err
)
SetLastError
(
err
);
return
err
==
ERROR_SUCCESS
;
}
/******************************************************************************
...
...
@@ -2195,6 +2254,8 @@ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
sizeW
=
*
lpcchBuffer
;
if
(
!
GetServiceDisplayNameW
(
hSCManager
,
lpServiceNameW
,
lpDisplayNameW
,
&
sizeW
))
{
if
(
*
lpcchBuffer
&&
lpDisplayName
)
lpDisplayName
[
0
]
=
0
;
*
lpcchBuffer
=
sizeW
*
2
;
/* we can only provide an upper estimation of string length */
goto
cleanup
;
}
...
...
@@ -2202,6 +2263,8 @@ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
if
(
!
WideCharToMultiByte
(
CP_ACP
,
0
,
lpDisplayNameW
,
(
sizeW
+
1
),
lpDisplayName
,
*
lpcchBuffer
,
NULL
,
NULL
))
{
if
(
*
lpcchBuffer
&&
lpDisplayName
)
lpDisplayName
[
0
]
=
0
;
*
lpcchBuffer
=
WideCharToMultiByte
(
CP_ACP
,
0
,
lpDisplayNameW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
goto
cleanup
;
}
...
...
@@ -2223,8 +2286,7 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
LPWSTR
lpDisplayName
,
LPDWORD
lpcchBuffer
)
{
struct
sc_manager
*
hscm
;
DWORD
type
,
size
;
LONG
ret
;
DWORD
err
;
TRACE
(
"%p %s %p %p
\n
"
,
hSCManager
,
debugstr_w
(
lpServiceName
),
lpDisplayName
,
lpcchBuffer
);
...
...
@@ -2242,56 +2304,12 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
return
FALSE
;
}
size
=
*
lpcchBuffer
*
sizeof
(
WCHAR
);
ret
=
RegGetValueW
(
hscm
->
hkey
,
lpServiceName
,
szDisplayName
,
RRF_RT_REG_SZ
,
&
type
,
lpDisplayName
,
&
size
);
if
(
!
ret
&&
!
lpDisplayName
&&
size
)
ret
=
ERROR_MORE_DATA
;
if
(
ret
)
{
if
(
lpDisplayName
&&
*
lpcchBuffer
)
*
lpDisplayName
=
0
;
err
=
svcctl_GetServiceDisplayNameW
(
hscm
->
hdr
.
server_handle
,
lpServiceName
,
lpDisplayName
,
lpDisplayName
?
*
lpcchBuffer
:
0
,
lpcchBuffer
);
if
(
ret
==
ERROR_MORE_DATA
)
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
*
lpcchBuffer
=
(
size
/
sizeof
(
WCHAR
))
-
1
;
}
else
if
(
ret
==
ERROR_FILE_NOT_FOUND
)
{
HKEY
hkey
;
if
(
!
RegOpenKeyW
(
hscm
->
hkey
,
lpServiceName
,
&
hkey
))
{
UINT
len
=
lstrlenW
(
lpServiceName
);
BOOL
r
=
FALSE
;
if
((
*
lpcchBuffer
<=
len
)
||
(
!
lpDisplayName
&&
*
lpcchBuffer
))
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
else
if
(
lpDisplayName
&&
*
lpcchBuffer
)
{
/* No displayname, but the service exists and the buffer
* is big enough. We should return the servicename.
*/
lstrcpyW
(
lpDisplayName
,
lpServiceName
);
r
=
TRUE
;
}
*
lpcchBuffer
=
len
;
RegCloseKey
(
hkey
);
return
r
;
}
else
SetLastError
(
ERROR_SERVICE_DOES_NOT_EXIST
);
}
else
SetLastError
(
ret
);
return
FALSE
;
}
/* Always return the correct needed size on success */
*
lpcchBuffer
=
(
size
/
sizeof
(
WCHAR
))
-
1
;
return
TRUE
;
if
(
err
)
SetLastError
(
err
);
return
err
==
ERROR_SUCCESS
;
}
/******************************************************************************
...
...
dlls/advapi32/tests/service.c
View file @
010dcb16
...
...
@@ -26,6 +26,7 @@
#include "winerror.h"
#include "winreg.h"
#include "winsvc.h"
#include "winnls.h"
#include "lmcons.h"
#include "wine/test.h"
...
...
@@ -614,45 +615,77 @@ static void test_get_servicekeyname(void)
SC_HANDLE
scm_handle
,
svc_handle
;
CHAR
servicename
[
4096
];
CHAR
displayname
[
4096
];
WCHAR
servicenameW
[
4096
];
WCHAR
displaynameW
[
4096
];
DWORD
servicesize
,
displaysize
,
tempsize
;
BOOL
ret
;
static
const
CHAR
deadbeef
[]
=
"Deadbeef"
;
static
const
WCHAR
deadbeefW
[]
=
{
'D'
,
'e'
,
'a'
,
'd'
,
'b'
,
'e'
,
'e'
,
'f'
,
0
};
/* Having NULL for the size of the buffer will crash on W2K3 */
SetLastError
(
0xdeadbeef
);
ret
=
GetServiceKeyNameA
(
NULL
,
NULL
,
NULL
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_HANDLE
,
"Expected ERROR_INVALID_HANDLE, got %d
\n
"
,
GetLastError
());
scm_handle
=
OpenSCManagerA
(
NULL
,
NULL
,
SC_MANAGER_CONNECT
);
servicesize
=
200
;
SetLastError
(
0xdeadbeef
);
ret
=
GetServiceKeyNameA
(
scm_handle
,
NULL
,
NULL
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */
||
GetLastError
()
==
ERROR_INVALID_PARAMETER
/* NT4 */
,
"Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
todo_wine
ok
(
servicesize
==
1
,
"Service size expected 1, got %d
\n
"
,
servicesize
);
/* Valid handle and buffer but no displayname */
servicesize
=
200
;
SetLastError
(
0xdeadbeef
);
ret
=
GetServiceKeyNameA
(
scm_handle
,
NULL
,
servicename
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */
||
GetLastError
()
==
ERROR_INVALID_PARAMETER
/* NT4 */
,
"Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
todo_wine
ok
(
servicesize
==
200
,
"Service size expected 1, got %d
\n
"
,
servicesize
);
/* Test for nonexistent displayname */
SetLastError
(
0xdeadbeef
);
ret
=
GetServiceKeyNameA
(
scm_handle
,
deadbeef
,
NULL
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_SERVICE_DOES_NOT_EXIST
,
"Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d
\n
"
,
GetLastError
());
todo_wine
ok
(
servicesize
==
1
,
"Service size expected 1, got %d
\n
"
,
servicesize
);
servicesize
=
15
;
strcpy
(
servicename
,
"ABC"
);
ret
=
GetServiceKeyNameA
(
scm_handle
,
deadbeef
,
servicename
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
servicesize
==
15
,
"Service size expected 15, got %d
\n
"
,
servicesize
);
ok
(
servicename
[
0
]
==
0
,
"Service name not empty
\n
"
);
servicesize
=
15
;
servicenameW
[
0
]
=
'A'
;
ret
=
GetServiceKeyNameW
(
scm_handle
,
deadbeefW
,
servicenameW
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
servicesize
==
15
,
"Service size expected 15, got %d
\n
"
,
servicesize
);
ok
(
servicenameW
[
0
]
==
0
,
"Service name not empty
\n
"
);
servicesize
=
0
;
strcpy
(
servicename
,
"ABC"
);
ret
=
GetServiceKeyNameA
(
scm_handle
,
deadbeef
,
servicename
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
servicesize
==
1
,
"Service size expected 1, got %d
\n
"
,
servicesize
);
ok
(
servicename
[
0
]
==
'A'
,
"Service name changed
\n
"
);
servicesize
=
0
;
servicenameW
[
0
]
=
'A'
;
ret
=
GetServiceKeyNameW
(
scm_handle
,
deadbeefW
,
servicenameW
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
servicesize
==
2
,
"Service size expected 2, got %d
\n
"
,
servicesize
);
ok
(
servicenameW
[
0
]
==
'A'
,
"Service name changed
\n
"
);
/* Check if 'Spooler' exists */
svc_handle
=
OpenServiceA
(
scm_handle
,
spooler
,
GENERIC_READ
);
...
...
@@ -673,7 +706,6 @@ static void test_get_servicekeyname(void)
servicesize
=
0
;
ret
=
GetServiceKeyNameA
(
scm_handle
,
displayname
,
NULL
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d
\n
"
,
GetLastError
());
...
...
@@ -682,7 +714,6 @@ static void test_get_servicekeyname(void)
tempsize
=
servicesize
;
servicesize
*=
2
;
ret
=
GetServiceKeyNameA
(
scm_handle
,
displayname
,
servicename
,
&
servicesize
);
todo_wine
ok
(
ret
,
"Expected success
\n
"
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
/* W2K3 */
||
GetLastError
()
==
ERROR_IO_PENDING
/* W2K */
||
...
...
@@ -693,8 +724,35 @@ static void test_get_servicekeyname(void)
ok
(
lstrlen
(
servicename
)
==
tempsize
/
2
,
"Expected the buffer to be twice the length of the string
\n
"
)
;
ok
(
!
lstrcmpi
(
servicename
,
spooler
),
"Expected %s, got %s
\n
"
,
spooler
,
servicename
);
ok
(
servicesize
==
(
tempsize
*
2
),
"Expected servicesize not to change if buffer not insufficient
\n
"
)
;
}
MultiByteToWideChar
(
CP_ACP
,
0
,
displayname
,
-
1
,
displaynameW
,
sizeof
(
displaynameW
)
/
2
);
SetLastError
(
0xdeadbeef
);
servicesize
*=
2
;
ret
=
GetServiceKeyNameW
(
scm_handle
,
displaynameW
,
servicenameW
,
&
servicesize
);
ok
(
ret
,
"Expected success
\n
"
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
/* W2K3 */
||
GetLastError
()
==
ERROR_IO_PENDING
/* W2K */
||
GetLastError
()
==
0xdeadbeef
/* NT4, XP, Vista */
,
"Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d
\n
"
,
GetLastError
());
if
(
ret
)
{
ok
(
lstrlen
(
servicename
)
==
tempsize
/
2
,
"Expected the buffer to be twice the length of the string
\n
"
)
;
ok
(
servicesize
==
lstrlenW
(
servicenameW
),
"Expected servicesize not to change if buffer not insufficient
\n
"
)
;
}
SetLastError
(
0xdeadbeef
);
servicesize
=
3
;
ret
=
GetServiceKeyNameW
(
scm_handle
,
displaynameW
,
servicenameW
,
&
servicesize
);
ok
(
!
ret
,
"Expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d
\n
"
,
GetLastError
());
ok
(
servicenameW
[
0
]
==
0
,
"Buffer not empty
\n
"
);
CloseServiceHandle
(
scm_handle
);
}
...
...
include/wine/svcctl.idl
View file @
010dcb16
...
...
@@ -127,4 +127,19 @@ cpp_quote("#endif")
[
in
]
SC_RPC_HANDLE
hService
,
[
out
]
QUERY_SERVICE_CONFIGW
*
config
)
;
/*
Compatible
with
Windows
function
0
x14
*/
DWORD
svcctl_GetServiceDisplayNameW
(
[
in
]
SC_RPC_HANDLE
hSCManager
,
[
in
]
LPCWSTR
lpServiceName
,
[
out
,
size_is
(
cchBufSize
)
]
WCHAR
lpBuffer
[]
,
[
in
]
DWORD
cchBufSize
,
[
out
]
DWORD
*
cchLength
)
;
/*
Compatible
with
Windows
function
0
x15
*/
DWORD
svcctl_GetServiceKeyNameW
(
[
in
]
SC_RPC_HANDLE
hSCManager
,
[
in
]
LPCWSTR
lpServiceDisplayName
,
[
out
,
size_is
(
cchBufSize
)
]
WCHAR
lpBuffer
[]
,
[
in
]
DWORD
cchBufSize
,
[
out
]
DWORD
*
cchLength
)
;
}
programs/services/rpc.c
View file @
010dcb16
...
...
@@ -183,6 +183,93 @@ static void SC_RPC_HANDLE_destroy(SC_RPC_HANDLE handle)
}
}
DWORD
svcctl_GetServiceDisplayNameW
(
SC_RPC_HANDLE
hSCManager
,
LPCWSTR
lpServiceName
,
WCHAR
*
lpBuffer
,
DWORD
cchBufSize
,
DWORD
*
cchLength
)
{
struct
sc_manager
*
manager
;
struct
service_entry
*
entry
;
DWORD
err
;
WINE_TRACE
(
"(%s, %d)
\n
"
,
wine_dbgstr_w
(
lpServiceName
),
cchBufSize
);
if
((
err
=
validate_scm_handle
(
hSCManager
,
0
,
&
manager
))
!=
ERROR_SUCCESS
)
return
err
;
lock_services
();
entry
=
find_service
(
lpServiceName
);
if
(
entry
!=
NULL
)
{
LPCWSTR
name
=
get_display_name
(
entry
);
*
cchLength
=
strlenW
(
name
);
if
(
*
cchLength
<
cchBufSize
)
{
err
=
ERROR_SUCCESS
;
lstrcpyW
(
lpBuffer
,
name
);
}
else
err
=
ERROR_INSUFFICIENT_BUFFER
;
}
else
{
*
cchLength
=
1
;
err
=
ERROR_SERVICE_DOES_NOT_EXIST
;
}
if
(
err
!=
ERROR_SUCCESS
&&
cchBufSize
>
0
)
lpBuffer
[
0
]
=
0
;
unlock_services
();
return
err
;
}
DWORD
svcctl_GetServiceKeyNameW
(
SC_RPC_HANDLE
hSCManager
,
LPCWSTR
lpServiceDisplayName
,
WCHAR
*
lpBuffer
,
DWORD
cchBufSize
,
DWORD
*
cchLength
)
{
struct
service_entry
*
entry
;
struct
sc_manager
*
manager
;
DWORD
err
;
WINE_TRACE
(
"(%s, %d)
\n
"
,
wine_dbgstr_w
(
lpServiceDisplayName
),
cchBufSize
);
if
((
err
=
validate_scm_handle
(
hSCManager
,
0
,
&
manager
))
!=
ERROR_SUCCESS
)
return
err
;
lock_services
();
entry
=
find_service_by_displayname
(
lpServiceDisplayName
);
if
(
entry
!=
NULL
)
{
*
cchLength
=
strlenW
(
entry
->
name
);
if
(
*
cchLength
<
cchBufSize
)
{
err
=
ERROR_SUCCESS
;
lstrcpyW
(
lpBuffer
,
entry
->
name
);
}
else
err
=
ERROR_INSUFFICIENT_BUFFER
;
}
else
{
*
cchLength
=
1
;
err
=
ERROR_SERVICE_DOES_NOT_EXIST
;
}
if
(
err
!=
ERROR_SUCCESS
&&
cchBufSize
>
0
)
lpBuffer
[
0
]
=
0
;
unlock_services
();
return
err
;
}
static
DWORD
create_handle_for_service
(
struct
service_entry
*
entry
,
DWORD
dwDesiredAccess
,
SC_RPC_HANDLE
*
phService
)
{
struct
sc_service
*
service
;
...
...
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