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