Commit 1c89dacf authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

services: svcctl_GetServiceDisplayNameW and svcctl_GetServiceKeyNameW should…

services: svcctl_GetServiceDisplayNameW and svcctl_GetServiceKeyNameW should have string attribute on output buffer. They also should not have two parameters for specifying the size of the buffer. The buffer size should also not include in the nul-terminating character.
parent b9587e69
...@@ -1568,6 +1568,7 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName, ...@@ -1568,6 +1568,7 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName,
{ {
DWORD err; DWORD err;
WCHAR buffer[2]; WCHAR buffer[2];
DWORD size;
TRACE("%p %s %p %p\n", hSCManager, TRACE("%p %s %p %p\n", hSCManager,
debugstr_w(lpDisplayName), lpServiceName, lpcchBuffer); debugstr_w(lpDisplayName), lpServiceName, lpcchBuffer);
...@@ -1588,10 +1589,14 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName, ...@@ -1588,10 +1589,14 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName,
*lpcchBuffer = 2; *lpcchBuffer = 2;
} }
/* RPC call takes size excluding nul-terminator, whereas *lpcchBuffer
* includes the nul-terminator on input. */
size = *lpcchBuffer - 1;
__TRY __TRY
{ {
err = svcctl_GetServiceKeyNameW(hSCManager, lpDisplayName, lpServiceName, err = svcctl_GetServiceKeyNameW(hSCManager, lpDisplayName, lpServiceName,
*lpcchBuffer, lpcchBuffer); &size);
} }
__EXCEPT(rpc_filter) __EXCEPT(rpc_filter)
{ {
...@@ -1599,6 +1604,10 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName, ...@@ -1599,6 +1604,10 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName,
} }
__ENDTRY __ENDTRY
/* The value of *lpcchBuffer excludes nul-terminator on output. */
if (err == ERROR_SUCCESS || err == ERROR_INSUFFICIENT_BUFFER)
*lpcchBuffer = size;
if (err) if (err)
SetLastError(err); SetLastError(err);
return err == ERROR_SUCCESS; return err == ERROR_SUCCESS;
...@@ -1682,6 +1691,7 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, ...@@ -1682,6 +1691,7 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
LPWSTR lpDisplayName, LPDWORD lpcchBuffer) LPWSTR lpDisplayName, LPDWORD lpcchBuffer)
{ {
DWORD err; DWORD err;
DWORD size;
WCHAR buffer[2]; WCHAR buffer[2];
TRACE("%p %s %p %p\n", hSCManager, TRACE("%p %s %p %p\n", hSCManager,
...@@ -1703,10 +1713,14 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, ...@@ -1703,10 +1713,14 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
*lpcchBuffer = 2; *lpcchBuffer = 2;
} }
/* RPC call takes size excluding nul-terminator, whereas *lpcchBuffer
* includes the nul-terminator on input. */
size = *lpcchBuffer - 1;
__TRY __TRY
{ {
err = svcctl_GetServiceDisplayNameW(hSCManager, lpServiceName, lpDisplayName, err = svcctl_GetServiceDisplayNameW(hSCManager, lpServiceName, lpDisplayName,
*lpcchBuffer, lpcchBuffer); &size);
} }
__EXCEPT(rpc_filter) __EXCEPT(rpc_filter)
{ {
...@@ -1714,6 +1728,10 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, ...@@ -1714,6 +1728,10 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
} }
__ENDTRY __ENDTRY
/* The value of *lpcchBuffer excludes nul-terminator on output. */
if (err == ERROR_SUCCESS || err == ERROR_INSUFFICIENT_BUFFER)
*lpcchBuffer = size;
if (err) if (err)
SetLastError(err); SetLastError(err);
return err == ERROR_SUCCESS; return err == ERROR_SUCCESS;
......
...@@ -257,17 +257,15 @@ typedef [switch_type(DWORD)] union ...@@ -257,17 +257,15 @@ typedef [switch_type(DWORD)] union
DWORD svcctl_GetServiceDisplayNameW( DWORD svcctl_GetServiceDisplayNameW(
[in] SC_RPC_HANDLE hSCManager, [in] SC_RPC_HANDLE hSCManager,
[in] LPCWSTR lpServiceName, [in] LPCWSTR lpServiceName,
[out,size_is(cchBufSize)] WCHAR lpBuffer[], [out,string,size_is(*cchBufSize+1)] WCHAR lpBuffer[],
[in] DWORD cchBufSize, [in,out] DWORD *cchBufSize);
[in,out] DWORD *cchLength);
/* Compatible with Windows function 0x15 */ /* Compatible with Windows function 0x15 */
DWORD svcctl_GetServiceKeyNameW( DWORD svcctl_GetServiceKeyNameW(
[in] SC_RPC_HANDLE hSCManager, [in] SC_RPC_HANDLE hSCManager,
[in] LPCWSTR lpServiceDisplayName, [in] LPCWSTR lpServiceDisplayName,
[out,size_is(cchBufSize)] WCHAR lpBuffer[], [out,string,size_is(*cchBufSize+1)] WCHAR lpBuffer[],
[in] DWORD cchBufSize, [in,out] DWORD *cchBufSize);
[in,out] DWORD *cchLength);
/* Not compatible with Windows function 0x16 */ /* Not compatible with Windows function 0x16 */
DWORD svcctl_SCSetServiceBitsA(/* FIXME */); DWORD svcctl_SCSetServiceBitsA(/* FIXME */);
......
...@@ -184,14 +184,13 @@ DWORD svcctl_GetServiceDisplayNameW( ...@@ -184,14 +184,13 @@ DWORD svcctl_GetServiceDisplayNameW(
SC_RPC_HANDLE hSCManager, SC_RPC_HANDLE hSCManager,
LPCWSTR lpServiceName, LPCWSTR lpServiceName,
WCHAR *lpBuffer, WCHAR *lpBuffer,
DWORD cchBufSize, DWORD *cchBufSize)
DWORD *cchLength)
{ {
struct sc_manager_handle *manager; struct sc_manager_handle *manager;
struct service_entry *entry; struct service_entry *entry;
DWORD err; DWORD err;
WINE_TRACE("(%s, %d)\n", wine_dbgstr_w(lpServiceName), cchBufSize); WINE_TRACE("(%s, %d)\n", wine_dbgstr_w(lpServiceName), *cchBufSize);
if ((err = validate_scm_handle(hSCManager, 0, &manager)) != ERROR_SUCCESS) if ((err = validate_scm_handle(hSCManager, 0, &manager)) != ERROR_SUCCESS)
return err; return err;
...@@ -202,16 +201,18 @@ DWORD svcctl_GetServiceDisplayNameW( ...@@ -202,16 +201,18 @@ DWORD svcctl_GetServiceDisplayNameW(
if (entry != NULL) if (entry != NULL)
{ {
LPCWSTR name; LPCWSTR name;
int len;
service_lock_shared(entry); service_lock_shared(entry);
name = get_display_name(entry); name = get_display_name(entry);
*cchLength = strlenW(name); len = strlenW(name);
if (*cchLength < cchBufSize) if (len <= *cchBufSize)
{ {
err = ERROR_SUCCESS; err = ERROR_SUCCESS;
lstrcpyW(lpBuffer, name); memcpy(lpBuffer, name, (len + 1)*sizeof(*name));
} }
else else
err = ERROR_INSUFFICIENT_BUFFER; err = ERROR_INSUFFICIENT_BUFFER;
*cchBufSize = len;
service_unlock(entry); service_unlock(entry);
} }
else else
...@@ -219,7 +220,7 @@ DWORD svcctl_GetServiceDisplayNameW( ...@@ -219,7 +220,7 @@ DWORD svcctl_GetServiceDisplayNameW(
scmdatabase_unlock(manager->db); scmdatabase_unlock(manager->db);
if (err != ERROR_SUCCESS && cchBufSize > 0) if (err != ERROR_SUCCESS)
lpBuffer[0] = 0; lpBuffer[0] = 0;
return err; return err;
...@@ -229,14 +230,13 @@ DWORD svcctl_GetServiceKeyNameW( ...@@ -229,14 +230,13 @@ DWORD svcctl_GetServiceKeyNameW(
SC_RPC_HANDLE hSCManager, SC_RPC_HANDLE hSCManager,
LPCWSTR lpServiceDisplayName, LPCWSTR lpServiceDisplayName,
WCHAR *lpBuffer, WCHAR *lpBuffer,
DWORD cchBufSize, DWORD *cchBufSize)
DWORD *cchLength)
{ {
struct service_entry *entry; struct service_entry *entry;
struct sc_manager_handle *manager; struct sc_manager_handle *manager;
DWORD err; DWORD err;
WINE_TRACE("(%s, %d)\n", wine_dbgstr_w(lpServiceDisplayName), cchBufSize); WINE_TRACE("(%s, %d)\n", wine_dbgstr_w(lpServiceDisplayName), *cchBufSize);
if ((err = validate_scm_handle(hSCManager, 0, &manager)) != ERROR_SUCCESS) if ((err = validate_scm_handle(hSCManager, 0, &manager)) != ERROR_SUCCESS)
return err; return err;
...@@ -246,15 +246,17 @@ DWORD svcctl_GetServiceKeyNameW( ...@@ -246,15 +246,17 @@ DWORD svcctl_GetServiceKeyNameW(
entry = scmdatabase_find_service_by_displayname(manager->db, lpServiceDisplayName); entry = scmdatabase_find_service_by_displayname(manager->db, lpServiceDisplayName);
if (entry != NULL) if (entry != NULL)
{ {
int len;
service_lock_shared(entry); service_lock_shared(entry);
*cchLength = strlenW(entry->name); len = strlenW(entry->name);
if (*cchLength < cchBufSize) if (len <= *cchBufSize)
{ {
err = ERROR_SUCCESS; err = ERROR_SUCCESS;
lstrcpyW(lpBuffer, entry->name); memcpy(lpBuffer, entry->name, (len + 1)*sizeof(*entry->name));
} }
else else
err = ERROR_INSUFFICIENT_BUFFER; err = ERROR_INSUFFICIENT_BUFFER;
*cchBufSize = len;
service_unlock(entry); service_unlock(entry);
} }
else else
...@@ -262,7 +264,7 @@ DWORD svcctl_GetServiceKeyNameW( ...@@ -262,7 +264,7 @@ DWORD svcctl_GetServiceKeyNameW(
scmdatabase_unlock(manager->db); scmdatabase_unlock(manager->db);
if (err != ERROR_SUCCESS && cchBufSize > 0) if (err != ERROR_SUCCESS)
lpBuffer[0] = 0; lpBuffer[0] = 0;
return err; return err;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment