First shot at CreateServiceW. It crashes due to a bug (aka missing feature) in widl...
authorEric Kohl <eric.kohl@reactos.org>
Sun, 9 Oct 2005 20:24:00 +0000 (20:24 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 9 Oct 2005 20:24:00 +0000 (20:24 +0000)
svn path=/trunk/; revision=18383

reactos/include/idl/svcctl.idl
reactos/lib/advapi32/service/scm.c
reactos/subsys/system/services/database.c
reactos/subsys/system/services/rpcserver.c
reactos/subsys/system/services/services.c
reactos/subsys/system/services/services.h

index 1bd65c0..24436ea 100644 (file)
@@ -77,23 +77,23 @@ cpp_quote("#endif")
 \r
 \r
   /* Function 12 */\r
-//  DWORD ScmrCreateServiceW([in] handle_t BindingHandle,\r
-//                           [in] SC_HANDLE hSCManager,\r
-//                           [in, string, ref] LPCWSTR lpServiceName,\r
-//                           [in, string, ref] LPCWSTR lpDisplayName,\r
-//                           [in] DWORD dwDesiredAccess,\r
-//                           [in] DWORD dwServiceType,\r
-//                           [in] DWORD dwStartType,\r
-//                           [in] DWORD dwErrorControl,\r
-//                           [in, string, ref] LPCWSTR lpBinaryPathName,\r
-//                           [in, string, unique] LPCWSTR lpLoadOrderGroup,\r
-//                           [out] LPDWORD lpdwTagId,\r
-//                           [in, size_is(dwDepwndenciesLength), unique] LPCWSTR lpDependencies,\r
-//                           [in] DWORD dwDependenciesLength,\r
-//                           [in, string, unique] LPCWSTR lpServiceStartName,\r
-//                           [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword,\r
-//                           [in] DWORD dwPasswordLength,\r
-//                           [out] SC_HANDLE *hService);\r
+  DWORD ScmrCreateServiceW([in] handle_t BindingHandle,\r
+                           [in] SC_HANDLE hSCManager,\r
+                           [in, string, ref] LPCWSTR lpServiceName,\r
+                           [in, string, unique] LPCWSTR lpDisplayName,\r
+                           [in] DWORD dwDesiredAccess,\r
+                           [in] DWORD dwServiceType,\r
+                           [in] DWORD dwStartType,\r
+                           [in] DWORD dwErrorControl,\r
+                           [in, string, ref] LPCWSTR lpBinaryPathName,\r
+                           [in, string, unique] LPCWSTR lpLoadOrderGroup,\r
+                           [in, out, unique] LPDWORD lpdwTagId,\r
+                           [in, size_is(dwDependenciesLength), unique] LPCWSTR lpDependencies,\r
+                           [in] DWORD dwDependenciesLength,\r
+                           [in, string, unique] LPCWSTR lpServiceStartName,\r
+                           [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword,\r
+                           [in] DWORD dwPasswordLength,\r
+                           [out] SC_HANDLE *hService);\r
 \r
 \r
   /* Function 15 */\r
index 5e91b2f..47f7c4f 100644 (file)
@@ -245,25 +245,54 @@ CreateServiceA(
  *
  * @unimplemented
  */
-SC_HANDLE
-STDCALL
-CreateServiceW(
-    SC_HANDLE   hSCManager,
-    LPCWSTR     lpServiceName,
-    LPCWSTR     lpDisplayName,
-    DWORD       dwDesiredAccess,
-    DWORD       dwServiceType,
-    DWORD       dwStartType,
-    DWORD       dwErrorControl,
-    LPCWSTR     lpBinaryPathName,
-    LPCWSTR     lpLoadOrderGroup,
-    LPDWORD     lpdwTagId,
-    LPCWSTR     lpDependencies,
-    LPCWSTR     lpServiceStartName,
-    LPCWSTR     lpPassword)
-{
-    DPRINT1("CreateServiceW is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
-    return INVALID_HANDLE_VALUE;
+SC_HANDLE STDCALL
+CreateServiceW(SC_HANDLE hSCManager,
+               LPCWSTR lpServiceName,
+               LPCWSTR lpDisplayName,
+               DWORD dwDesiredAccess,
+               DWORD dwServiceType,
+               DWORD dwStartType,
+               DWORD dwErrorControl,
+               LPCWSTR lpBinaryPathName,
+               LPCWSTR lpLoadOrderGroup,
+               LPDWORD lpdwTagId,
+               LPCWSTR lpDependencies,
+               LPCWSTR lpServiceStartName,
+               LPCWSTR lpPassword)
+{
+    SC_HANDLE hService = NULL;
+    DWORD dwError;
+
+    DPRINT1("CreateServiceW() called\n");
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrCreateServiceW(BindingHandle,
+                                 (unsigned int)hSCManager,
+                                 (LPWSTR)lpServiceName,
+                                 (LPWSTR)lpDisplayName,
+                                 dwDesiredAccess,
+                                 dwServiceType,
+                                 dwStartType,
+                                 dwErrorControl,
+                                 (LPWSTR)lpBinaryPathName,
+                                 (LPWSTR)lpLoadOrderGroup,
+                                 lpdwTagId,
+                                 NULL,              /* FIXME: lpDependencies */
+                                 0,                 /* FIXME: dwDependenciesLength */
+                                 (LPWSTR)lpServiceStartName,
+                                 NULL,              /* FIXME: lpPassword */
+                                 0,                 /* FIXME: dwPasswordLength */
+                                 (unsigned int *)&hService);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    return hService;
 }
 
 
index c5d8e2c..8310327 100644 (file)
 
 /* INCLUDES *****************************************************************/
 
-#include "services.h"
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
 #include <services/services.h>
 
+#include "services.h"
+
 #define NDEBUG
 #include <debug.h>
 
@@ -46,13 +51,13 @@ typedef struct _SERVICE_GROUP
 } SERVICE_GROUP, *PSERVICE_GROUP;
 
 
-
-
 /* GLOBALS *******************************************************************/
 
 LIST_ENTRY GroupListHead;
 LIST_ENTRY ServiceListHead;
 
+static RTL_RESOURCE DatabaseLock;
+
 
 /* FUNCTIONS *****************************************************************/
 
@@ -66,18 +71,18 @@ ScmGetServiceEntryByName(PUNICODE_STRING ServiceName)
 
   ServiceEntry = ServiceListHead.Flink;
   while (ServiceEntry != &ServiceListHead)
-  {
-    CurrentService = CONTAINING_RECORD(ServiceEntry,
-                                       SERVICE,
-                                       ServiceListEntry);
-    if (RtlEqualUnicodeString(&CurrentService->ServiceName, ServiceName, TRUE))
     {
-      DPRINT("Found service: '%wZ'\n", &CurrentService->ServiceName);
-      return CurrentService;
-    }
+      CurrentService = CONTAINING_RECORD(ServiceEntry,
+                                        SERVICE,
+                                        ServiceListEntry);
+      if (RtlEqualUnicodeString(&CurrentService->ServiceName, ServiceName, TRUE))
+       {
+         DPRINT("Found service: '%wZ'\n", &CurrentService->ServiceName);
+         return CurrentService;
+       }
 
-    ServiceEntry = ServiceEntry->Flink;
-  }
+      ServiceEntry = ServiceEntry->Flink;
+    }
 
   DPRINT("Couldn't find a matching service\n");
 
@@ -87,48 +92,50 @@ ScmGetServiceEntryByName(PUNICODE_STRING ServiceName)
 
 static NTSTATUS STDCALL
 CreateGroupOrderListRoutine(PWSTR ValueName,
-                           ULONG ValueType,
-                           PVOID ValueData,
-                           ULONG ValueLength,
-                           PVOID Context,
-                           PVOID EntryContext)
+                            ULONG ValueType,
+                            PVOID ValueData,
+                            ULONG ValueLength,
+                            PVOID Context,
+                            PVOID EntryContext)
 {
-  PSERVICE_GROUP Group;
+    PSERVICE_GROUP Group;
 
-  DPRINT("IopGetGroupOrderList(%S, %x, %x, %x, %x, %x)\n",
-         ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
+    DPRINT("IopGetGroupOrderList(%S, %x, %x, %x, %x, %x)\n",
+           ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
 
-  if (ValueType == REG_BINARY &&
-      ValueData != NULL &&
-      ValueLength >= sizeof(DWORD) &&
-      ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
+    if (ValueType == REG_BINARY &&
+        ValueData != NULL &&
+        ValueLength >= sizeof(DWORD) &&
+        ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
     {
-      Group = (PSERVICE_GROUP)Context;
-      Group->TagCount = ((PULONG)ValueData)[0];
-      if (Group->TagCount > 0)
+        Group = (PSERVICE_GROUP)Context;
+        Group->TagCount = ((PULONG)ValueData)[0];
+        if (Group->TagCount > 0)
         {
-         if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
+            if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
             {
-              Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
-                                                 HEAP_ZERO_MEMORY,
-                                                 Group->TagCount * sizeof(DWORD));
-             if (Group->TagArray == NULL)
-               {
-                 Group->TagCount = 0;
-                 return STATUS_INSUFFICIENT_RESOURCES;
-               }
-             RtlCopyMemory(Group->TagArray,
-                           (PULONG)ValueData + 1,
-                           Group->TagCount * sizeof(DWORD));
-           }
-         else
-           {
-             Group->TagCount = 0;
-             return STATUS_UNSUCCESSFUL;
-           }
-       }
+                Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
+                                                    HEAP_ZERO_MEMORY,
+                                                    Group->TagCount * sizeof(DWORD));
+                if (Group->TagArray == NULL)
+                {
+                    Group->TagCount = 0;
+                    return STATUS_INSUFFICIENT_RESOURCES;
+                }
+
+                RtlCopyMemory(Group->TagArray,
+                              (PULONG)ValueData + 1,
+                              Group->TagCount * sizeof(DWORD));
+            }
+            else
+            {
+                Group->TagCount = 0;
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
     }
-  return STATUS_SUCCESS;
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -140,45 +147,44 @@ CreateGroupListRoutine(PWSTR ValueName,
                       PVOID Context,
                       PVOID EntryContext)
 {
-  PSERVICE_GROUP Group;
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  NTSTATUS Status;
+    PSERVICE_GROUP Group;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NTSTATUS Status;
 
-  if (ValueType == REG_SZ)
+    if (ValueType == REG_SZ)
     {
-      DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
+        DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
 
-      Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
-                                       HEAP_ZERO_MEMORY,
-                                       sizeof(SERVICE_GROUP));
-      if (Group == NULL)
-       {
-         return STATUS_INSUFFICIENT_RESOURCES;
-       }
-
-      if (!RtlCreateUnicodeString(&Group->GroupName,
-                                 (PWSTR)ValueData))
-       {
-         return STATUS_INSUFFICIENT_RESOURCES;
-       }
+        Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
+                                          HEAP_ZERO_MEMORY,
+                                          sizeof(SERVICE_GROUP));
+        if (Group == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
 
-      RtlZeroMemory(&QueryTable, sizeof(QueryTable));
-      QueryTable[0].Name = (PWSTR)ValueData;
-      QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
+        if (!RtlCreateUnicodeString(&Group->GroupName,
+                                    (PWSTR)ValueData))
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
 
-      Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                     L"GroupOrderList",
-                                     QueryTable,
-                                     (PVOID)Group,
-                                     NULL);
-      DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
+        RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+        QueryTable[0].Name = (PWSTR)ValueData;
+        QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
 
+        Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+                                        L"GroupOrderList",
+                                        QueryTable,
+                                        (PVOID)Group,
+                                        NULL);
+        DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
 
-      InsertTailList(&GroupListHead,
-                    &Group->GroupListEntry);
+        InsertTailList(&GroupListHead,
+                       &Group->GroupListEntry);
     }
 
-  return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 
@@ -296,7 +302,7 @@ ScmCreateServiceDataBase(VOID)
 {
   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
   OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING ServicesKeyName = 
+  UNICODE_STRING ServicesKeyName =
   RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
   UNICODE_STRING SubKeyName;
   HKEY ServicesKey;
@@ -313,6 +319,9 @@ ScmCreateServiceDataBase(VOID)
   InitializeListHead(&GroupListHead);
   InitializeListHead(&ServiceListHead);
 
+  /* Initialize the database lock */
+  RtlInitializeResource(&DatabaseLock);
+
   /* Build group order list */
   RtlZeroMemory(&QueryTable,
                sizeof(QueryTable));
@@ -328,6 +337,9 @@ ScmCreateServiceDataBase(VOID)
   if (!NT_SUCCESS(Status))
     return Status;
 
+  RtlInitUnicodeString(&ServicesKeyName,
+                      L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
+
   InitializeObjectAttributes(&ObjectAttributes,
                             &ServicesKeyName,
                             OBJ_CASE_INSENSITIVE,
@@ -926,4 +938,13 @@ ScmAutoStartServices(VOID)
     }
 }
 
+
+DWORD
+ScmMarkServiceForDelete(PSERVICE pService)
+{
+  DPRINT1("ScmMarkServiceForDelete() called\n");
+
+  return ERROR_SUCCESS;
+}
+
 /* EOF */
index 5edd4e0..d735dca 100644 (file)
@@ -4,6 +4,10 @@
 
 /* INCLUDES ****************************************************************/
 
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
 #include "services.h"
 #include "svcctl_s.h"
 
@@ -107,13 +111,13 @@ ScmStartRpcServer(VOID)
 
   DPRINT("ScmStartRpcServer() called");
 
-  Status = RpcServerUseProtseqEp(L"ncacn_np",
-                                 10,
-                                 L"\\pipe\\ntsvcs",
-                                 NULL);
+  Status = RpcServerUseProtseqEpW(L"ncacn_np",
+                                  10,
+                                  L"\\pipe\\ntsvcs",
+                                  NULL);
   if (Status != RPC_S_OK)
   {
-    DPRINT1("RpcServerUseProtseqEp() failed (Status %lx)\n", Status);
+    DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
     return;
   }
 
@@ -142,7 +146,7 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
                        SC_HANDLE *Handle)
 {
   PMANAGER_HANDLE Ptr;
-  
+
   if (lpDatabaseName == NULL)
     lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
 
@@ -325,6 +329,7 @@ ScmrDeleteService(handle_t BindingHandle,
 {
   PSERVICE_HANDLE hSvc;
   PSERVICE lpService;
+  DWORD dwError;
 
   DPRINT1("ScmrDeleteService() called\n");
 
@@ -343,9 +348,16 @@ ScmrDeleteService(handle_t BindingHandle,
     return ERROR_INVALID_HANDLE;
   }
 
-  /* FIXME: Mark service for delete */
+  /* FIXME: Acquire service database lock exclusively */
 
-  return ERROR_SUCCESS;
+  /* Mark service for delete */
+  dwError = ScmMarkServiceForDelete(lpService);
+
+  /* FIXME: Release service database lock */
+
+  DPRINT1("ScmrDeleteService() done\n");
+
+  return dwError;
 }
 
 
@@ -471,9 +483,49 @@ ScmrNotifyBootConfigStatus(handle_t BindingHandle,
 }
 
 
+#if 0
+static DWORD
+CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey)
+{
+    HKEY hServicesKey = NULL;
+    DWORD dwDisposition;
+    DWORD dwError;
+
+    *phKey = NULL;
+
+    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                            L"System\\CurrentControlSet\\Services",
+                            0,
+                            KEY_WRITE,
+                            &hServicesKey);
+    if (dwError != ERROR_SUCCESS)
+        return dwError;
+
+    dwError = RegCreateKeyExW(hServicesKey,
+                              lpServiceName,
+                              0,
+                              NULL,
+                              REG_OPTION_NON_VOLATILE,
+                              KEY_WRITE,
+                              NULL,
+                              phKey,
+                              &dwDisposition);
+    if ((dwError == ERROR_SUCCESS) &&
+        (dwDisposition == REG_OPENED_EXISTING_KEY))
+    {
+        RegCloseKey(*phKey);
+        *phKey = NULL;
+        dwError = ERROR_SERVICE_EXISTS;
+    }
+
+    RegCloseKey(hServicesKey);
+
+    return dwError;
+}
+#endif
+
 
 /* Function 12 */
-#if 0
 unsigned long
 ScmrCreateServiceW(handle_t BindingHandle,
                    unsigned int hSCManager,
@@ -485,18 +537,169 @@ ScmrCreateServiceW(handle_t BindingHandle,
                    unsigned long dwErrorControl,
                    wchar_t *lpBinaryPathName,
                    wchar_t *lpLoadOrderGroup,
-                   unsigned long *lpdwTagId,
+                   unsigned long *lpdwTagId, /* in, out */
                    wchar_t *lpDependencies,
+                   unsigned long dwDependenciesLength,
                    wchar_t *lpServiceStartName,
-                   wchar_t *lpPassword)
+                   wchar_t *lpPassword,
+                   unsigned long dwPasswordLength,
+                   unsigned int *hService) /* out */
 {
-  DPRINT1("ScmrCreateServiceW() called\n");
-  if (lpdwTagId != NULL)
-    *lpdwTagId = 0;
-  return ERROR_SUCCESS;
-}
+    PMANAGER_HANDLE hManager;
+    DWORD dwError = ERROR_SUCCESS;
+#if 0
+    HKEY hServiceKey = NULL;
+    LPWSTR lpImagePath = NULL;
 #endif
 
+    DPRINT1("ScmrCreateServiceW() called\n");
+    DPRINT1("lpServiceName = %S\n", lpServiceName);
+    DPRINT1("lpDisplayName = %S\n", lpDisplayName);
+    DPRINT1("dwDesiredAccess = %lx\n", dwDesiredAccess);
+    DPRINT1("dwServiceType = %lu\n", dwServiceType);
+    DPRINT1("dwStartType = %lu\n", dwStartType);
+    DPRINT1("dwErrorControl = %lu\n", dwErrorControl);
+    DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName);
+    DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+
+    hManager = (PMANAGER_HANDLE)hSCManager;
+    if (hManager->Handle.Tag != MANAGER_TAG)
+    {
+        DPRINT1("Invalid manager handle!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    /* Check access rights */
+    if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+                                  SC_MANAGER_CREATE_SERVICE))
+    {
+        DPRINT1("Insufficient access rights! 0x%lx\n",
+                hManager->Handle.DesiredAccess);
+        return ERROR_ACCESS_DENIED;
+    }
+
+    /* FIXME: Fail if the service already exists! */
+
+#if 0
+    if (dwServiceType & SERVICE_DRIVER)
+    {
+        /* FIXME: Adjust the image path */
+        lpImagePath = HeapAlloc(GetProcessHeap(),
+                                HEAP_ZERO_MEMORY,
+                                wcslen(lpBinaryPathName) + sizeof(WCHAR));
+        if (lpImagePath == NULL)
+        {
+            dwError = ERROR_NOT_ENOUGH_MEMORY;
+            goto done;
+        }
+        wcscpy(lpImagePath, lpBinaryPathName);
+    }
+
+    /* FIXME: Allocate and fill a service entry */
+
+//    if (lpdwTagId != NULL)
+//        *lpdwTagId = 0;
+
+//    *hService = 0;
+
+
+    /* Write service data to the registry */
+    /* Create the service key */
+    dwError = CreateServiceKey(lpServiceName, &hServiceKey);
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
+    if ((lpDisplayName != NULL) && (wcslen(lpDisplayName) > 0))
+    {
+        RegSetValueExW(hServiceKey,
+                       L"DisplayName",
+                       0,
+                       REG_SZ,
+                       (LPBYTE)lpDisplayName,
+                       (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+    }
+
+    /* Set the service type */
+    dwError = RegSetValueExW(hServiceKey,
+                             L"Type",
+                             0,
+                             REG_DWORD,
+                             (LPBYTE)&dwServiceType,
+                             sizeof(DWORD));
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
+    /* Set the start value */
+    dwError = RegSetValueExW(hServiceKey,
+                             L"Start",
+                             0,
+                             REG_DWORD,
+                             (LPBYTE)&dwStartType,
+                             sizeof(DWORD));
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
+    /* Set the error control value */
+    dwError = RegSetValueExW(hServiceKey,
+                             L"ErrorControl",
+                             0,
+                             REG_DWORD,
+                             (LPBYTE)&dwErrorControl,
+                             sizeof(DWORD));
+    if (dwError != ERROR_SUCCESS)
+        goto done;
+
+    /* Set the image path */
+    if (dwServiceType & SERVICE_WIN32)
+    {
+        dwError = RegSetValueExW(hServiceKey,
+                                 L"ImagePath",
+                                 0,
+                                 REG_SZ,
+                                 (LPBYTE)lpBinaryPathName,
+                                 (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
+        if (dwError != ERROR_SUCCESS)
+            goto done;
+    }
+    else if (dwServiceType & SERVICE_DRIVER)
+    {
+        /* FIXME: Adjust the path name */
+        dwError = RegSetValueExW(hServiceKey,
+                                 L"ImagePath",
+                                 0,
+                                 REG_SZ,
+                                 (LPBYTE)lpImagePath,
+                                 (wcslen(lpImagePath) +  1) *sizeof(WCHAR));
+        if (dwError != ERROR_SUCCESS)
+            goto done;
+    }
+
+    /* Set the group name */
+    if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+    {
+        dwError = RegSetValueExW(hServiceKey,
+                                 L"Group",
+                                 0,
+                                 REG_SZ,
+                                 (LPBYTE)lpLoadOrderGroup,
+                                 (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+        if (dwError != ERROR_SUCCESS)
+            goto done;
+    }
+
+done:;
+    if (hServiceKey != NULL)
+        RegCloseKey(hServiceKey);
+
+    if (lpImagePath != NULL)
+        HeapFree(GetProcessHeap(), 0, lpImagePath);
+#endif
+
+    DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError);
+
+    return dwError;
+}
+
 
 /* Function 15 */
 unsigned long
index 6a7eb53..8235c50 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * service control manager
  *
  * ReactOS Operating System
 
 /* INCLUDES *****************************************************************/
 
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
 #include "services.h"
 
 #define NDEBUG
index d2847f5..489343e 100644 (file)
@@ -1,12 +1,12 @@
+/*
+ * services.h
+ */
+
 #include <stdio.h>
 #include <windows.h>
 #define NTOS_MODE_USER
 #include <ndk/ntndk.h>
 
-/*
- * services.h
- */
-
 typedef struct _SERVICE
 {
   LIST_ENTRY ServiceListEntry;
@@ -45,8 +45,8 @@ NTSTATUS ScmCreateServiceDataBase(VOID);
 VOID ScmGetBootAndSystemDriverState(VOID);
 VOID ScmAutoStartServices(VOID);
 
-PSERVICE
-ScmGetServiceEntryByName(PUNICODE_STRING ServiceName);
+PSERVICE ScmGetServiceEntryByName(PUNICODE_STRING ServiceName);
+DWORD ScmMarkServiceForDelete(PSERVICE pService);
 
 
 /* rpcserver.c */