From de7220e2553764afd5cf8d463110d4ec5b1a6696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= Date: Wed, 11 Oct 2017 15:36:16 +0200 Subject: [PATCH] advapi32: Fix ChangeServiceConfig2 when given a null description. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Übelacker Signed-off-by: Alexandre Julliard --- dlls/advapi32/tests/service.c | 66 +++++++++++++++++++++++++++++++++++ programs/services/rpc.c | 3 ++ 2 files changed, 69 insertions(+) diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index ab7ae2e8fe7..405cef7662c 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -36,6 +36,7 @@ static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms static CHAR selfname[MAX_PATH]; static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID); +static BOOL (WINAPI *pChangeServiceConfig2W)(SC_HANDLE,DWORD,LPVOID); static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD, LPDWORD, LPCSTR); @@ -57,6 +58,7 @@ static void init_function_pointers(void) HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A"); + pChangeServiceConfig2W = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2W"); pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA"); pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW"); pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo"); @@ -1954,6 +1956,7 @@ static void test_queryconfig2(void) DWORD expected, needed; BYTE buffer[MAX_PATH]; LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer; + LPSERVICE_DESCRIPTIONW pConfigW = (LPSERVICE_DESCRIPTIONW)buffer; SERVICE_PRESHUTDOWN_INFO preshutdown_info; static const CHAR servicename [] = "Winetest"; static const CHAR displayname [] = "Winetest dummy service"; @@ -1961,6 +1964,9 @@ static void test_queryconfig2(void) static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0"; static const CHAR password [] = ""; static const CHAR description [] = "Description"; + static const CHAR description_empty[] = ""; + static const WCHAR descriptionW [] = {'D','e','s','c','r','i','p','t','i','o','n','W',0}; + static const WCHAR descriptionW_empty[] = {0}; if(!pQueryServiceConfig2A) { @@ -2121,6 +2127,66 @@ static void test_queryconfig2(void) ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed); ok(ret, "expected QueryServiceConfig2W to succeed\n"); + pConfig->lpDescription = (LPSTR)description; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = NULL; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), + "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); + + pConfig->lpDescription = NULL; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = NULL; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), + "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); + + pConfig->lpDescription = (LPSTR)description_empty; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = (void*)0xdeadbeef; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(!pConfig->lpDescription, + "expected lpDescription to be null, got %s\n", pConfig->lpDescription); + + pConfigW->lpDescription = (LPWSTR)descriptionW; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = NULL; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), + "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); + + pConfigW->lpDescription = NULL; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = NULL; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), + "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); + + pConfigW->lpDescription = (LPWSTR)descriptionW_empty; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = (void*)0xdeadbeef; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(!pConfigW->lpDescription, + "expected lpDescription to be null, got %s\n", wine_dbgstr_w(pConfigW->lpDescription)); + SetLastError(0xdeadbeef); ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 8c95b7eb77e..4435af935d7 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -826,6 +826,9 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, SC_RPC_CONFI { WCHAR *descr = NULL; + if (!config.u.descr->lpDescription) + break; + if (config.u.descr->lpDescription[0]) { if (!(descr = strdupW( config.u.descr->lpDescription )))