diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index f3ed2e5faca..050efc85bc7 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -1565,6 +1565,7 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName, LPWSTR lpServiceName, LPDWORD lpcchBuffer ) { DWORD err; + WCHAR buffer[2]; TRACE("%p %s %p %p\n", hSCManager, debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer); @@ -1575,10 +1576,20 @@ BOOL WINAPI GetServiceKeyNameW( SC_HANDLE hSCManager, LPCWSTR lpDisplayName, return 0; } + /* provide a buffer if the caller didn't */ + if (!lpServiceName || *lpcchBuffer < 2) + { + lpServiceName = 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_GetServiceKeyNameW(hSCManager, lpDisplayName, lpServiceName, - lpServiceName ? *lpcchBuffer : 0, lpcchBuffer); + *lpcchBuffer, lpcchBuffer); } __EXCEPT(rpc_filter) { diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 936978a3862..625aff3be3e 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -760,7 +760,7 @@ static void test_get_servicekeyname(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(servicesize == 15, "Service size expected 15, got %d\n", servicesize); + ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize); ok(servicenameW[0] == 0, "Service name not empty\n"); servicesize = 0; @@ -776,7 +776,7 @@ static void test_get_servicekeyname(void) lstrcpyW( servicenameW, abcW ); 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(servicesize == 2, "Service size expected 2, got %d\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); ok(servicenameW[0] == 'A', "Service name changed\n"); @@ -794,10 +794,10 @@ static void test_get_servicekeyname(void) lstrcpyW( servicenameW, abcW ); 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(servicesize == 2, "Service size expected 2, got %d\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicenameW[0] == 'A', "Service name changed\n"); + ok(servicenameW[0] == 'A', "Service name changed\n"); servicesize = 2; strcpy(servicename, "ABC"); @@ -805,14 +805,14 @@ static void test_get_servicekeyname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); + todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); ok(servicename[0] == 0, "Service name not empty\n"); servicesize = 2; lstrcpyW( servicenameW, abcW ); 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(servicesize == 2, "Service size expected 2, got %d\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); ok(servicenameW[0] == 0, "Service name not empty\n"); diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl index d04da08bfcb..918c80eb679 100644 --- a/include/wine/svcctl.idl +++ b/include/wine/svcctl.idl @@ -240,7 +240,7 @@ typedef [switch_type(DWORD)] union [in] LPCWSTR lpServiceDisplayName, [out,size_is(cchBufSize)] WCHAR lpBuffer[], [in] DWORD cchBufSize, - [out] DWORD *cchLength); + [in,out] DWORD *cchLength); /* Not compatible with Windows function 0x16 */ DWORD svcctl_SCSetServiceBitsA(/* FIXME */); diff --git a/programs/services/rpc.c b/programs/services/rpc.c index b6014aab6fa..d88e148fdcd 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -261,10 +261,7 @@ DWORD svcctl_GetServiceKeyNameW( service_unlock(entry); } else - { - *cchLength = 1; err = ERROR_SERVICE_DOES_NOT_EXIST; - } scmdatabase_unlock(manager->db);