Author: ekohl
Date: Thu Aug 31 21:16:19 2006
New Revision: 23846
URL: 
http://svn.reactos.org/svn/reactos?rev=23846&view=rev
Log:
Pass additional arguments to a service when it is started by a call to StartService.
Modified:
    trunk/reactos/base/system/services/database.c
    trunk/reactos/base/system/services/driver.c
    trunk/reactos/base/system/services/rpcserver.c
    trunk/reactos/base/system/services/services.h
    trunk/reactos/dll/win32/advapi32/service/sctrl.c
    trunk/reactos/include/reactos/wine/winnt.h
Modified: trunk/reactos/base/system/services/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c (original)
+++ trunk/reactos/base/system/services/database.c Thu Aug 31 21:16:19 2006
@@ -528,14 +528,14 @@
 }
-static NTSTATUS
-ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
+static DWORD
+ScmSendStartCommand(PSERVICE Service,
+                    LPWSTR Arguments)
 {
     PSCM_START_PACKET StartPacket;
     DWORD TotalLength;
-#if 0
+    DWORD ArgsLength = 0;
     DWORD Length;
-#endif
     PWSTR Ptr;
     DWORD Count;
@@ -543,7 +543,6 @@
     /* Calculate the total length of the start command line */
     TotalLength = wcslen(Service->lpServiceName) + 1;
-#if 0
     if (Arguments != NULL)
     {
         Ptr = Arguments;
@@ -551,18 +550,20 @@
         {
             Length = wcslen(Ptr) + 1;
             TotalLength += Length;
+            ArgsLength += Length;
             Ptr += Length;
-        }
-    }
-#endif
+            DPRINT("Arg: %S\n", Ptr);
+        }
+    }
     TotalLength++;
+    DPRINT("ArgsLength: %ld\nTotalLength: %ld\n\n", ArgsLength, TotalLength);
     /* Allocate start command packet */
     StartPacket = HeapAlloc(GetProcessHeap(),
                             HEAP_ZERO_MEMORY,
                             sizeof(SCM_START_PACKET) + (TotalLength - 1) *
sizeof(WCHAR));
     if (StartPacket == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
+        return ERROR_NOT_ENOUGH_MEMORY;
     StartPacket->Command = SCM_START_COMMAND;
     StartPacket->Size = TotalLength;
@@ -570,8 +571,14 @@
     wcscpy(Ptr, Service->lpServiceName);
     Ptr += (wcslen(Service->lpServiceName) + 1);
-    /* FIXME: Copy argument list */
-
+    /* Copy argument list */
+    if (Arguments != NULL)
+    {
+        memcpy(Ptr, Arguments, ArgsLength);
+        Ptr += ArgsLength;
+    }
+
+    /* Terminate the argument list */
     *Ptr = 0;
     /* Send the start command */
@@ -583,18 +590,20 @@
     /* FIXME: Read the reply */
+    /* Release the start command packet */
     HeapFree(GetProcessHeap(),
              0,
              StartPacket);
     DPRINT("ScmSendStartCommand() done\n");
-    return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-ScmStartUserModeService(PSERVICE Service)
+    return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScmStartUserModeService(PSERVICE Service,
+                        LPWSTR lpArgs)
 {
     RTL_QUERY_REGISTRY_TABLE QueryTable[3];
     PROCESS_INFORMATION ProcessInformation;
@@ -603,6 +612,7 @@
     ULONG Type;
     BOOL Result;
     NTSTATUS Status;
+    DWORD dwError = ERROR_SUCCESS;
     RtlInitUnicodeString(&ImagePath, NULL);
@@ -626,7 +636,7 @@
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
-        return Status;
+        return RtlNtStatusToDosError(Status);
     }
     DPRINT("ImagePath: '%S'\n", ImagePath.Buffer);
     DPRINT("Type: %lx\n", Type);
@@ -644,7 +654,7 @@
     if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
     {
         DPRINT1("Failed to create control pipe!\n");
-        return STATUS_UNSUCCESSFUL;
+        return GetLastError();
     }
     StartupInfo.cb = sizeof(StartupInfo);
@@ -669,12 +679,13 @@
     if (!Result)
     {
+        dwError = GetLastError();
         /* Close control pipe */
         CloseHandle(Service->ControlPipeHandle);
         Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
         DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
-        return STATUS_UNSUCCESSFUL;
+        return dwError;
     }
     DPRINT("Process Id: %lu  Handle %lx\n",
@@ -706,20 +717,21 @@
                       &dwRead,
                       NULL))
         {
+            dwError = GetLastError();
             DPRINT1("Reading the service control pipe failed (Error %lu)\n",
-                    GetLastError());
-            Status = STATUS_UNSUCCESSFUL;
+                    dwError);
         }
         else
         {
             DPRINT("Received process id %lu\n", dwProcessId);
             /* Send start command */
-            Status = ScmSendStartCommand(Service, NULL);
+            dwError = ScmSendStartCommand(Service, lpArgs);
         }
     }
     else
     {
+        dwError = GetLastError();
         DPRINT("Connecting control pipe failed!\n");
         /* Close control pipe */
@@ -727,22 +739,21 @@
         Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
         Service->ProcessId = 0;
         Service->ThreadId = 0;
-        Status = STATUS_UNSUCCESSFUL;
     }
     /* Close process and thread handle */
     CloseHandle(ProcessInformation.hThread);
     CloseHandle(ProcessInformation.hProcess);
-    return Status;
-}
-
-
-NTSTATUS
-ScmStartService(PSERVICE Service)
+    return dwError;
+}
+
+
+DWORD
+ScmStartService(PSERVICE Service, LPWSTR lpArgs)
 {
     PSERVICE_GROUP Group = Service->lpGroup;
-    NTSTATUS Status;
+    DWORD dwError = ERROR_SUCCESS;
     DPRINT("ScmStartService() called\n");
@@ -752,19 +763,19 @@
     if (Service->Status.dwServiceType & SERVICE_DRIVER)
     {
         /* Load driver */
-        Status = ScmLoadDriver(Service);
-        if (Status == STATUS_SUCCESS)
+        dwError = ScmLoadDriver(Service);
+        if (dwError == ERROR_SUCCESS)
             Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
     }
     else
     {
         /* Start user-mode service */
-        Status = ScmStartUserModeService(Service);
-    }
-
-    DPRINT("ScmStartService() done (Status %lx)\n", Status);
-
-    if (NT_SUCCESS(Status))
+        dwError = ScmStartUserModeService(Service, lpArgs);
+    }
+
+    DPRINT("ScmStartService() done (Error %lu)\n", dwError);
+
+    if (dwError == ERROR_SUCCESS)
     {
         if (Group != NULL)
         {
@@ -802,7 +813,7 @@
     }
 #endif
-    return Status;
+    return dwError;
 }
@@ -846,7 +857,7 @@
                     (CurrentService->dwTag == CurrentGroup->TagArray[i]))
                 {
                     CurrentService->ServiceVisited = TRUE;
-                    ScmStartService(CurrentService);
+                    ScmStartService(CurrentService, NULL);
                 }
                 ServiceEntry = ServiceEntry->Flink;
@@ -864,7 +875,7 @@
                 (CurrentService->ServiceVisited == FALSE))
             {
                 CurrentService->ServiceVisited = TRUE;
-                ScmStartService(CurrentService);
+                ScmStartService(CurrentService, NULL);
             }
             ServiceEntry = ServiceEntry->Flink;
@@ -884,7 +895,7 @@
             (CurrentService->ServiceVisited == FALSE))
         {
             CurrentService->ServiceVisited = TRUE;
-            ScmStartService(CurrentService);
+            ScmStartService(CurrentService, NULL);
         }
         ServiceEntry = ServiceEntry->Flink;
@@ -901,7 +912,7 @@
             (CurrentService->ServiceVisited == FALSE))
         {
             CurrentService->ServiceVisited = TRUE;
-            ScmStartService(CurrentService);
+            ScmStartService(CurrentService, NULL);
         }
         ServiceEntry = ServiceEntry->Flink;
Modified: trunk/reactos/base/system/services/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/drive…
==============================================================================
--- trunk/reactos/base/system/services/driver.c (original)
+++ trunk/reactos/base/system/services/driver.c Thu Aug 31 21:16:19 2006
@@ -11,12 +11,13 @@
 /* FUNCTIONS ****************************************************************/
-NTSTATUS
+DWORD
 ScmLoadDriver(PSERVICE lpService)
 {
     WCHAR szDriverPath[MAX_PATH];
     UNICODE_STRING DriverPath;
     NTSTATUS Status;
+    DWORD dwError = ERROR_SUCCESS;
     /* Build the driver path */
     wcscpy(szDriverPath,
@@ -34,7 +35,12 @@
     /* FIXME: Release privilege */
-    return Status;
+    if (!NT_SUCCESS(Status))
+    {
+        dwError = RtlNtStatusToDosError(Status);
+    }
+
+    return dwError;
 }
Modified: trunk/reactos/base/system/services/rpcserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcse…
==============================================================================
--- trunk/reactos/base/system/services/rpcserver.c (original)
+++ trunk/reactos/base/system/services/rpcserver.c Thu Aug 31 21:16:19 2006
@@ -1755,7 +1755,6 @@
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
-    NTSTATUS Status;
     DPRINT1("ScmrStartServiceW() called\n");
@@ -1790,12 +1789,7 @@
         return ERROR_SERVICE_MARKED_FOR_DELETE;
     /* Start the service */
-    Status = ScmStartService(lpService);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("ScmStartService failed!\n");
-        return RtlNtStatusToDosError(Status);
-    }
+    dwError = ScmStartService(lpService, (LPWSTR)lpServiceArgBuffer);
     return dwError;
 }
@@ -2099,7 +2093,6 @@
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
-    NTSTATUS Status;
     DPRINT1("ScmrStartServiceA() called\n");
@@ -2136,9 +2129,9 @@
     /* FIXME: Convert argument vector to Unicode */
     /* Start the service */
-    Status = ScmStartService(lpService);
-    if (!NT_SUCCESS(Status))
-        return RtlNtStatusToDosError(Status);
+    dwError = ScmStartService(lpService, NULL);
+
+    /* FIXME: Free argument vector */
     return dwError;
 }
Modified: trunk/reactos/base/system/services/services.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servi…
==============================================================================
--- trunk/reactos/base/system/services/services.h (original)
+++ trunk/reactos/base/system/services/services.h Thu Aug 31 21:16:19 2006
@@ -88,6 +88,8 @@
 DWORD ScmCreateServiceDatabase(VOID);
 VOID ScmGetBootAndSystemDriverState(VOID);
 VOID ScmAutoStartServices(VOID);
+DWORD ScmStartService(PSERVICE Service,
+                      LPWSTR lpArgs);
 PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
 PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
@@ -99,7 +101,7 @@
 /* driver.c */
-NTSTATUS ScmLoadDriver(PSERVICE lpService);
+DWORD ScmLoadDriver(PSERVICE lpService);
 DWORD ScmUnloadDriver(PSERVICE lpService);
 DWORD ScmControlDriver(PSERVICE lpService,
                        DWORD dwControl,
@@ -121,8 +123,6 @@
 /* services.c */
 VOID PrintString(LPCSTR fmt, ...);
-NTSTATUS ScmStartService(PSERVICE Service);
-
 /* EOF */
Modified: trunk/reactos/dll/win32/advapi32/service/sctrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/sctrl.c (original)
+++ trunk/reactos/dll/win32/advapi32/service/sctrl.c Thu Aug 31 21:16:19 2006
@@ -90,17 +90,24 @@
   PACTIVE_SERVICE lpService;
   DWORD dwArgCount = 0;
   DWORD dwLength = 0;
+  DWORD dwLen;
+  LPWSTR lpPtr;
   lpService = (PACTIVE_SERVICE)Context;
   DPRINT("ScServiceMainStub() called\n");
   /* Count arguments */
-  while (lpService->Arguments[dwLength])
-    {
-      dwLength += wcslen(&lpService->Arguments[dwLength]) + 1;
+  lpPtr = lpService->Arguments;
+  while (*lpPtr)
+    {
+      DPRINT("arg: %S\n", *lpPtr);
+      dwLen = wcslen(lpPtr) + 1;
       dwArgCount++;
-    }
+      dwLength += dwLen;
+      lpPtr += dwLen;
+    }
+  DPRINT("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
   /* Build the argument vector and call the main service routine */
   if (lpService->bUnicode)
@@ -241,6 +248,7 @@
   PACTIVE_SERVICE lpService;
   HANDLE ThreadHandle;
+  DPRINT("ScStartService() called\n");
   DPRINT("Size: %lu\n", StartPacket->Size);
   DPRINT("Service: %S\n", &StartPacket->Arguments[0]);
Modified: trunk/reactos/include/reactos/wine/winnt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/wine/winnt…
==============================================================================
--- trunk/reactos/include/reactos/wine/winnt.h (original)
+++ trunk/reactos/include/reactos/wine/winnt.h Thu Aug 31 21:16:19 2006
@@ -38,6 +38,8 @@
 #define LANG_RHAETO_ROMANCE 0x17
 #define LANG_SAAMI          0x3b
 #define LANG_SORBIAN        0x2e
+#define LANG_LOWER_SORBIAN  0x2e
+#define LANG_UPPER_SORBIAN  0x2e
 #define LANG_SUTU           0x30
 #define LANG_TSONGA         0x31
 #define LANG_TSWANA         0x32