Paul Vriens : advapi32/service: Check for duplicate displayname.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 19 07:59:42 CDT 2007
Module: wine
Branch: master
Commit: f8f6340a692afc199f171edd03fd295fe3fb0a7f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f8f6340a692afc199f171edd03fd295fe3fb0a7f
Author: Paul Vriens <paul.vriens.wine at gmail.com>
Date: Wed Jul 18 20:17:35 2007 +0200
advapi32/service: Check for duplicate displayname.
---
dlls/advapi32/service.c | 55 +++++++++++++++++++++++++++++++++++++---
dlls/advapi32/tests/service.c | 10 -------
2 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 3fbd242..76f8290 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -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 )
diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c
index ff38d79..0547686 100644
--- a/dlls/advapi32/tests/service.c
+++ b/dlls/advapi32/tests/service.c
@@ -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);
}
More information about the wine-cvs
mailing list