Improvements to ScmrCreateServiceW:
- Allocate a service record for the new service.
- Fix registry value types and sizes.
- Fail if the new service already exists.
Modified: trunk/reactos/subsys/system/services/database.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
Modified: trunk/reactos/subsys/system/services/services.h

Modified: trunk/reactos/subsys/system/services/database.c
--- trunk/reactos/subsys/system/services/database.c	2005-10-23 01:06:59 UTC (rev 18692)
+++ trunk/reactos/subsys/system/services/database.c	2005-10-23 06:19:15 UTC (rev 18693)
@@ -186,11 +186,10 @@
 CreateServiceListEntry(LPWSTR lpServiceName)
 {
     RTL_QUERY_REGISTRY_TABLE QueryTable[6];
-    UNICODE_STRING ServiceName;
     PSERVICE Service = NULL;
     NTSTATUS Status;
 
-    DPRINT("Service: '%wZ'\n", ServiceName);
+    DPRINT("Service: '%S'\n", lpServiceName);
 
 
     /* Allocate service entry */
@@ -265,6 +264,42 @@
 }
 
 
+DWORD
+ScmCreateNewServiceRecord(LPWSTR lpServiceName,
+                          PSERVICE *lpServiceRecord)
+{
+    PSERVICE lpService = NULL;
+
+    DPRINT("Service: '%S'\n", lpServiceName);
+
+    /* Allocate service entry */
+    lpService = HeapAlloc(GetProcessHeap(),
+                          HEAP_ZERO_MEMORY,
+                          sizeof(SERVICE) + ((wcslen(lpServiceName) + 1) * sizeof(WCHAR)));
+    if (lpService == NULL)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    *lpServiceRecord = lpService;
+
+    /* Copy service name */
+    wcscpy(lpService->szServiceName, lpServiceName);
+    lpService->lpServiceName = lpService->szServiceName;
+
+    /* Append service entry */
+    InsertTailList(&ServiceListHead,
+                   &lpService->ServiceListEntry);
+
+    lpService->Status.dwCurrentState = SERVICE_STOPPED;
+    lpService->Status.dwControlsAccepted = 0;
+    lpService->Status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED;
+    lpService->Status.dwServiceSpecificExitCode = 0;
+    lpService->Status.dwCheckPoint = 0;
+    lpService->Status.dwWaitHint = 2000; /* 2 seconds */
+
+    return ERROR_SUCCESS;
+}
+
+
 NTSTATUS
 ScmCreateServiceDataBase(VOID)
 {

Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- trunk/reactos/subsys/system/services/rpcserver.c	2005-10-23 01:06:59 UTC (rev 18692)
+++ trunk/reactos/subsys/system/services/rpcserver.c	2005-10-23 06:19:15 UTC (rev 18693)
@@ -493,9 +493,9 @@
 #endif
 
 
-#if 0
 static DWORD
-CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey)
+CreateServiceKey(LPWSTR lpServiceName,
+                 PHKEY phKey)
 {
     HKEY hServicesKey = NULL;
     DWORD dwDisposition;
@@ -520,6 +520,7 @@
                               NULL,
                               phKey,
                               &dwDisposition);
+#if 0
     if ((dwError == ERROR_SUCCESS) &&
         (dwDisposition == REG_OPENED_EXISTING_KEY))
     {
@@ -527,12 +528,12 @@
         *phKey = NULL;
         dwError = ERROR_SERVICE_EXISTS;
     }
+#endif
 
     RegCloseKey(hServicesKey);
 
     return dwError;
 }
-#endif
 
 
 /* Function 12 */
@@ -557,10 +558,10 @@
 {
     PMANAGER_HANDLE hManager;
     DWORD dwError = ERROR_SUCCESS;
-#if 0
+    PSERVICE lpService = NULL;
+    SC_HANDLE hServiceHandle = NULL;
+    LPWSTR lpImagePath = NULL;
     HKEY hServiceKey = NULL;
-    LPWSTR lpImagePath = NULL;
-#endif
 
     DPRINT1("ScmrCreateServiceW() called\n");
     DPRINT1("lpServiceName = %S\n", lpServiceName);
@@ -588,15 +589,16 @@
         return ERROR_ACCESS_DENIED;
     }
 
-    /* FIXME: Fail if the service already exists! */
+    /* Fail if the service already exists! */
+    if (ScmGetServiceEntryByName(lpServiceName) != NULL)
+        return ERROR_SERVICE_EXISTS;
 
-#if 0
     if (dwServiceType & SERVICE_DRIVER)
     {
         /* FIXME: Adjust the image path */
         lpImagePath = HeapAlloc(GetProcessHeap(),
                                 HEAP_ZERO_MEMORY,
-                                wcslen(lpBinaryPathName) + sizeof(WCHAR));
+                                (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
         if (lpImagePath == NULL)
         {
             dwError = ERROR_NOT_ENOUGH_MEMORY;
@@ -605,14 +607,18 @@
         wcscpy(lpImagePath, lpBinaryPathName);
     }
 
-    /* FIXME: Allocate and fill a service entry */
-//    dwError = CreateNewServiceListEntry(lpServiceName,
-//                                        &lpServiceEntry)
+    /* Allocate a new service entry */
+    dwError = ScmCreateNewServiceRecord(lpServiceName,
+                                        &lpService);
+    if (dwError != ERROR_SUCCESS)
+        goto done;
 
-//    if (lpdwTagId != NULL)
-//        *lpdwTagId = 0;
+    /* Fill the new service entry */
+    lpService->Status.dwServiceType = dwServiceType;
+    lpService->dwStartType = dwStartType;
+    lpService->dwErrorControl = dwErrorControl;
 
-//    *hService = 0;
+    /* FIXME: set lpLoadOrderGroup, lpDependencies etc. */
 
 
     /* Write service data to the registry */
@@ -621,6 +627,7 @@
     if (dwError != ERROR_SUCCESS)
         goto done;
 
+    /* Set the display name */
     if (lpDisplayName != NULL && *lpDisplayName != 0)
     {
         RegSetValueExW(hServiceKey,
@@ -667,7 +674,7 @@
         dwError = RegSetValueExW(hServiceKey,
                                  L"ImagePath",
                                  0,
-                                 REG_SZ,
+                                 REG_EXPAND_SZ,
                                  (LPBYTE)lpBinaryPathName,
                                  (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
         if (dwError != ERROR_SUCCESS)
@@ -675,13 +682,12 @@
     }
     else if (dwServiceType & SERVICE_DRIVER)
     {
-        /* FIXME: Adjust the path name */
         dwError = RegSetValueExW(hServiceKey,
                                  L"ImagePath",
                                  0,
-                                 REG_SZ,
+                                 REG_EXPAND_SZ,
                                  (LPBYTE)lpImagePath,
-                                 (wcslen(lpImagePath) +  1) *sizeof(WCHAR));
+                                 (wcslen(lpImagePath) + 1) *sizeof(WCHAR));
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -699,6 +705,11 @@
             goto done;
     }
 
+    if (lpdwTagId != NULL)
+    {
+        /* FIXME: Write tag */
+    }
+
     if (lpDependencies != NULL && *lpDependencies != 0)
     {
         /* FIXME: Write dependencies */
@@ -709,13 +720,44 @@
         /* FIXME: Write password */
     }
 
+    dwError = ScmCreateServiceHandle(lpService,
+                                     &hServiceHandle);
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
+    dwError = ScmCheckAccess(hServiceHandle,
+                             dwDesiredAccess);
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
 done:;
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
+    if (dwError == ERROR_SUCCESS)
+    {
+        DPRINT1("hService %lx\n", hServiceHandle);
+        *hService = (unsigned int)hServiceHandle;
+
+        if (lpdwTagId != NULL)
+            *lpdwTagId = 0; /* FIXME */
+    }
+    else
+    {
+        if (hServiceHandle != NULL)
+        {
+            /* Remove the service handle */
+            HeapFree(GetProcessHeap(), 0, hServiceHandle);
+        }
+
+        if (lpService != NULL)
+        {
+            /* FIXME: remove the service entry */
+        }
+    }
+
     if (lpImagePath != NULL)
         HeapFree(GetProcessHeap(), 0, lpImagePath);
-#endif
 
     DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError);
 

Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/subsys/system/services/services.h	2005-10-23 01:06:59 UTC (rev 18692)
+++ trunk/reactos/subsys/system/services/services.h	2005-10-23 06:19:15 UTC (rev 18693)
@@ -44,6 +44,8 @@
 VOID ScmAutoStartServices(VOID);
 
 PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
+DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
+                                PSERVICE *lpServiceRecord);
 DWORD ScmMarkServiceForDelete(PSERVICE pService);