From 49c87ef97c214671de6b462596e4957b5afa587d Mon Sep 17 00:00:00 2001 From: Mikolaj Zalewski Date: Wed, 26 Sep 2007 15:48:03 -0700 Subject: [PATCH] advapi32: fix GetServiceDisplayName for cchBuffer == 0 --- dlls/advapi32/service.c | 51 +++++++++++++++++------------------------ dlls/advapi32/tests/service.c | 9 ++++++- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 4708506..6613416 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -2231,49 +2231,40 @@ BOOL WINAPI QueryServiceLockStatusW( SC_ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName, LPSTR lpDisplayName, LPDWORD lpcchBuffer) { - LPWSTR lpServiceNameW, lpDisplayNameW = NULL; - DWORD size, sizeW, GLE; - BOOL ret; + LPWSTR lpServiceNameW, lpDisplayNameW; + DWORD sizeW; + BOOL ret = FALSE; TRACE("%p %s %p %p\n", hSCManager, debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer); lpServiceNameW = SERV_dup(lpServiceName); - lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, *lpcchBuffer * sizeof(WCHAR)); - - size = sizeW = *lpcchBuffer; - ret = GetServiceDisplayNameW(hSCManager, lpServiceNameW, - lpDisplayName ? lpDisplayNameW : NULL, - &sizeW); - /* Last error will be set by GetServiceDisplayNameW and must be preserved */ - GLE = GetLastError(); + if (lpDisplayName) + lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, *lpcchBuffer * sizeof(WCHAR)); + else + lpDisplayNameW = NULL; - if (!lpDisplayName && *lpcchBuffer && !ret && (GLE == ERROR_INSUFFICIENT_BUFFER)) + sizeW = *lpcchBuffer; + if (!GetServiceDisplayNameW(hSCManager, lpServiceNameW, lpDisplayNameW, &sizeW)) { - /* Request for buffersize. - * - * Only set the size for ERROR_INSUFFICIENT_BUFFER - */ - size = sizeW * 2; + *lpcchBuffer = sizeW*2; /* we can only provide an upper estimation of string length */ + goto cleanup; } - else if (lpDisplayName && *lpcchBuffer && !ret) + + if (!WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, (sizeW + 1), lpDisplayName, + *lpcchBuffer, NULL, NULL )) { - /* Request for displayname. - * - * size only has to be set if this fails - */ - size = sizeW * 2; + *lpcchBuffer = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, NULL, 0, NULL, NULL); + goto cleanup; } - WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, (sizeW + 1), lpDisplayName, - *lpcchBuffer, NULL, NULL ); - - *lpcchBuffer = size; - + /* probably due to a bug GetServiceDisplayNameA doesn't modify lpcchBuffer on success. + * (but if the function succeeded it means that is a good upper estimation of the size) */ + ret = TRUE; + +cleanup: HeapFree(GetProcessHeap(), 0, lpDisplayNameW); HeapFree(GetProcessHeap(), 0, lpServiceNameW); - - SetLastError(GLE); return ret; } diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 79b4c3c..e932c64 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -444,10 +444,17 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + tempsize = displaysize; + + displaysize = 0; + ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize); /* Buffer is too small */ SetLastError(0xdeadbeef); - tempsize = displaysize; displaysize = (tempsize / 2); ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); ok(!ret, "Expected failure\n"); -- 1.4.1