forked from Mirrors/wine-wine
services: Move GetServiceDisplayName to services.exe and implement GetServiceKeyName.
parent
76d4eeebff
commit
010dcb168b
|
@ -2135,8 +2135,44 @@ EnumServicesStatusExW(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServ
|
||||||
BOOL WINAPI GetServiceKeyNameA( SC_HANDLE hSCManager, LPCSTR lpDisplayName,
|
BOOL WINAPI GetServiceKeyNameA( SC_HANDLE hSCManager, LPCSTR lpDisplayName,
|
||||||
LPSTR lpServiceName, LPDWORD lpcchBuffer )
|
LPSTR lpServiceName, LPDWORD lpcchBuffer )
|
||||||
{
|
{
|
||||||
FIXME("%p %s %p %p\n", hSCManager, debugstr_a(lpDisplayName), lpServiceName, lpcchBuffer);
|
LPWSTR lpDisplayNameW, lpServiceNameW;
|
||||||
return FALSE;
|
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,10 +2181,33 @@ BOOL WINAPI GetServiceKeyNameA( SC_HANDLE hSCManager, LPCSTR lpDisplayName,
|
||||||
BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName,
|
BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName,
|
||||||
LPWSTR lpServiceName, LPDWORD lpcchBuffer )
|
LPWSTR lpServiceName, LPDWORD lpcchBuffer )
|
||||||
{
|
{
|
||||||
FIXME("%p %s %p %p\n", hSCManager, debugstr_w(lpDisplayName), lpServiceName, lpcchBuffer);
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* QueryServiceLockStatusA [ADVAPI32.@]
|
* QueryServiceLockStatusA [ADVAPI32.@]
|
||||||
*/
|
*/
|
||||||
|
@ -2195,6 +2254,8 @@ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
|
||||||
sizeW = *lpcchBuffer;
|
sizeW = *lpcchBuffer;
|
||||||
if (!GetServiceDisplayNameW(hSCManager, lpServiceNameW, lpDisplayNameW, &sizeW))
|
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 */
|
*lpcchBuffer = sizeW*2; /* we can only provide an upper estimation of string length */
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -2202,6 +2263,8 @@ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
|
||||||
if (!WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, (sizeW + 1), lpDisplayName,
|
if (!WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, (sizeW + 1), lpDisplayName,
|
||||||
*lpcchBuffer, NULL, NULL ))
|
*lpcchBuffer, NULL, NULL ))
|
||||||
{
|
{
|
||||||
|
if (*lpcchBuffer && lpDisplayName)
|
||||||
|
lpDisplayName[0] = 0;
|
||||||
*lpcchBuffer = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, NULL, 0, NULL, NULL);
|
*lpcchBuffer = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, NULL, 0, NULL, NULL);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -2223,8 +2286,7 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
|
||||||
LPWSTR lpDisplayName, LPDWORD lpcchBuffer)
|
LPWSTR lpDisplayName, LPDWORD lpcchBuffer)
|
||||||
{
|
{
|
||||||
struct sc_manager *hscm;
|
struct sc_manager *hscm;
|
||||||
DWORD type, size;
|
DWORD err;
|
||||||
LONG ret;
|
|
||||||
|
|
||||||
TRACE("%p %s %p %p\n", hSCManager,
|
TRACE("%p %s %p %p\n", hSCManager,
|
||||||
debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer);
|
debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer);
|
||||||
|
@ -2242,56 +2304,12 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = *lpcchBuffer * sizeof(WCHAR);
|
err = svcctl_GetServiceDisplayNameW(hscm->hdr.server_handle,
|
||||||
ret = RegGetValueW(hscm->hkey, lpServiceName, szDisplayName, RRF_RT_REG_SZ, &type, lpDisplayName, &size);
|
lpServiceName, lpDisplayName, lpDisplayName ? *lpcchBuffer : 0, lpcchBuffer);
|
||||||
if (!ret && !lpDisplayName && size)
|
|
||||||
ret = ERROR_MORE_DATA;
|
|
||||||
|
|
||||||
if (ret)
|
if (err)
|
||||||
{
|
SetLastError(err);
|
||||||
if (lpDisplayName && *lpcchBuffer) *lpDisplayName = 0;
|
return err == ERROR_SUCCESS;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "winsvc.h"
|
#include "winsvc.h"
|
||||||
|
#include "winnls.h"
|
||||||
#include "lmcons.h"
|
#include "lmcons.h"
|
||||||
|
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
@ -614,45 +615,77 @@ static void test_get_servicekeyname(void)
|
||||||
SC_HANDLE scm_handle, svc_handle;
|
SC_HANDLE scm_handle, svc_handle;
|
||||||
CHAR servicename[4096];
|
CHAR servicename[4096];
|
||||||
CHAR displayname[4096];
|
CHAR displayname[4096];
|
||||||
|
WCHAR servicenameW[4096];
|
||||||
|
WCHAR displaynameW[4096];
|
||||||
DWORD servicesize, displaysize, tempsize;
|
DWORD servicesize, displaysize, tempsize;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
static const CHAR deadbeef[] = "Deadbeef";
|
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 */
|
/* Having NULL for the size of the buffer will crash on W2K3 */
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
|
ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
|
||||||
ok(!ret, "Expected failure\n");
|
ok(!ret, "Expected failure\n");
|
||||||
todo_wine
|
|
||||||
ok(GetLastError() == ERROR_INVALID_HANDLE,
|
ok(GetLastError() == ERROR_INVALID_HANDLE,
|
||||||
"Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
|
"Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
|
||||||
|
|
||||||
scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
|
scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
|
||||||
|
servicesize = 200;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
|
ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
|
||||||
ok(!ret, "Expected failure\n");
|
ok(!ret, "Expected failure\n");
|
||||||
todo_wine
|
|
||||||
ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
|
ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
|
||||||
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
|
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
|
||||||
"Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
"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 */
|
/* Valid handle and buffer but no displayname */
|
||||||
|
servicesize = 200;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
|
ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
|
||||||
ok(!ret, "Expected failure\n");
|
ok(!ret, "Expected failure\n");
|
||||||
todo_wine
|
|
||||||
ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
|
ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
|
||||||
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
|
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
|
||||||
"Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
"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 */
|
/* Test for nonexistent displayname */
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
|
ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
|
||||||
ok(!ret, "Expected failure\n");
|
ok(!ret, "Expected failure\n");
|
||||||
todo_wine
|
|
||||||
ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
|
ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
|
||||||
"Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
|
"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 */
|
/* Check if 'Spooler' exists */
|
||||||
svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
|
svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
|
||||||
|
@ -673,7 +706,6 @@ static void test_get_servicekeyname(void)
|
||||||
servicesize = 0;
|
servicesize = 0;
|
||||||
ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
|
ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
|
||||||
ok(!ret, "Expected failure\n");
|
ok(!ret, "Expected failure\n");
|
||||||
todo_wine
|
|
||||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
@ -682,7 +714,6 @@ static void test_get_servicekeyname(void)
|
||||||
tempsize = servicesize;
|
tempsize = servicesize;
|
||||||
servicesize *= 2;
|
servicesize *= 2;
|
||||||
ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
|
ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
|
||||||
todo_wine
|
|
||||||
ok(ret, "Expected success\n");
|
ok(ret, "Expected success\n");
|
||||||
ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
|
ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
|
||||||
GetLastError() == ERROR_IO_PENDING /* W2K */ ||
|
GetLastError() == ERROR_IO_PENDING /* W2K */ ||
|
||||||
|
@ -693,8 +724,35 @@ static void test_get_servicekeyname(void)
|
||||||
ok(lstrlen(servicename) == tempsize/2,
|
ok(lstrlen(servicename) == tempsize/2,
|
||||||
"Expected the buffer to be twice the length of the string\n") ;
|
"Expected the buffer to be twice the length of the string\n") ;
|
||||||
ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
|
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);
|
CloseServiceHandle(scm_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,4 +127,19 @@ cpp_quote("#endif")
|
||||||
[in] SC_RPC_HANDLE hService,
|
[in] SC_RPC_HANDLE hService,
|
||||||
[out] QUERY_SERVICE_CONFIGW *config);
|
[out] QUERY_SERVICE_CONFIGW *config);
|
||||||
|
|
||||||
|
/* Compatible with Windows function 0x14 */
|
||||||
|
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 0x15 */
|
||||||
|
DWORD svcctl_GetServiceKeyNameW(
|
||||||
|
[in] SC_RPC_HANDLE hSCManager,
|
||||||
|
[in] LPCWSTR lpServiceDisplayName,
|
||||||
|
[out,size_is(cchBufSize)] WCHAR lpBuffer[],
|
||||||
|
[in] DWORD cchBufSize,
|
||||||
|
[out] DWORD *cchLength);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
static DWORD create_handle_for_service(struct service_entry *entry, DWORD dwDesiredAccess, SC_RPC_HANDLE *phService)
|
||||||
{
|
{
|
||||||
struct sc_service *service;
|
struct sc_service *service;
|
||||||
|
|
Loading…
Reference in New Issue