diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 050efc85bc7..a107397e658 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -1680,6 +1680,7 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPWSTR lpDisplayName, LPDWORD lpcchBuffer) { DWORD err; + WCHAR buffer[2]; TRACE("%p %s %p %p\n", hSCManager, debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer); @@ -1690,10 +1691,20 @@ BOOL WINAPI GetServiceDisplayNameW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, return 0; } + /* provide a buffer if the caller didn't */ + if (!lpDisplayName || *lpcchBuffer < 2) + { + lpDisplayName = buffer; + /* A size of 1 would be enough, but tests show that Windows returns 2, + * probably because of a WCHAR/bytes mismatch in their code. + */ + *lpcchBuffer = 2; + } + __TRY { err = svcctl_GetServiceDisplayNameW(hSCManager, lpServiceName, lpDisplayName, - lpDisplayName ? *lpcchBuffer : 0, lpcchBuffer); + *lpcchBuffer, lpcchBuffer); } __EXCEPT(rpc_filter) { diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 625aff3be3e..451a21be087 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -476,7 +476,7 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); + ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); ok(displaynameW[0] == 0, "Service name not empty\n"); displaysize = 0; @@ -492,7 +492,7 @@ static void test_get_displayname(void) lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); ok(displaynameW[0] == 'A', "Service name changed\n"); @@ -510,10 +510,10 @@ static void test_get_displayname(void) lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaynameW[0] == 'A', "Service name changed\n"); + ok(displaynameW[0] == 'A', "Service name changed\n"); displaysize = 2; strcpy(displayname, "ABC"); @@ -521,14 +521,14 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); ok(displayname[0] == 0, "Service name not empty\n"); displaysize = 2; lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); ok(displaynameW[0] == 0, "Service name not empty\n"); diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl index 918c80eb679..36bf476e04e 100644 --- a/include/wine/svcctl.idl +++ b/include/wine/svcctl.idl @@ -232,7 +232,7 @@ typedef [switch_type(DWORD)] union [in] LPCWSTR lpServiceName, [out,size_is(cchBufSize)] WCHAR lpBuffer[], [in] DWORD cchBufSize, - [out] DWORD *cchLength); + [in,out] DWORD *cchLength); /* Compatible with Windows function 0x15 */ DWORD svcctl_GetServiceKeyNameW( diff --git a/programs/services/rpc.c b/programs/services/rpc.c index d88e148fdcd..cbb825e2cc9 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -215,10 +215,7 @@ DWORD svcctl_GetServiceDisplayNameW( service_unlock(entry); } else - { - *cchLength = 1; err = ERROR_SERVICE_DOES_NOT_EXIST; - } scmdatabase_unlock(manager->db);