advapi32/service: Check for duplicate displayname.

oldstable
Paul Vriens 2007-07-18 20:17:35 +02:00 committed by Alexandre Julliard
parent a80e952ac0
commit f8f6340a69
2 changed files with 50 additions and 15 deletions

View File

@ -1309,6 +1309,9 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
struct reg_value val[10];
int n = 0;
DWORD new_mask = dwDesiredAccess;
DWORD index = 0;
WCHAR buffer[MAX_PATH];
BOOL displayname_exists = FALSE;
TRACE("%p %s %s\n", hSCManager,
debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
@ -1385,15 +1388,57 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
return NULL;
}
/* Loop through the registry to check if the service already exists and to
* check if we can use the given displayname.
* FIXME: Should we use EnumServicesStatusEx?
*/
len = sizeof(buffer);
while (RegEnumKeyExW(hscm->hkey, index, buffer, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY service_key;
/* The service already exists, so bail out */
if(!lstrcmpiW(lpServiceName, buffer))
{
SetLastError(ERROR_SERVICE_EXISTS);
return NULL;
}
/* The given displayname matches the found servicename. We don't bail out
* as servicename is checked before a duplicate displayname
*/
if(!lstrcmpiW(lpDisplayName, buffer))
displayname_exists = TRUE;
if (RegOpenKeyExW(hscm->hkey, buffer, 0, KEY_READ, &service_key) == ERROR_SUCCESS)
{
WCHAR name[MAX_PATH];
DWORD size = sizeof(name);
if (RegQueryValueExW(service_key, szDisplayName, NULL, NULL, (LPBYTE)name, &size) == ERROR_SUCCESS)
{
/* The given displayname matches the found displayname */
if (!lstrcmpiW(lpDisplayName, name))
displayname_exists = TRUE;
}
RegCloseKey(service_key);
}
index++;
len = sizeof(buffer);
}
if (lpDisplayName && displayname_exists)
{
SetLastError(ERROR_DUPLICATE_SERVICE_NAME);
return NULL;
}
r = RegCreateKeyExW(hscm->hkey, lpServiceName, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp);
if (r!=ERROR_SUCCESS)
return NULL;
if (dp != REG_CREATED_NEW_KEY)
{
SetLastError(ERROR_SERVICE_EXISTS);
goto error;
/* FIXME: Should we set an error? */
return NULL;
}
if( lpDisplayName )

View File

@ -315,24 +315,14 @@ static void test_create_delete_svc(void)
{
svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
todo_wine
{
ok(!svc_handle1, "Expected failure\n");
ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
"Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
}
}
}
else
skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
/* FIXME: Remove this when Wine is fixed */
if (svc_handle1)
{
DeleteService(svc_handle1);
CloseServiceHandle(svc_handle1);
}
CloseServiceHandle(scm_handle);
}