[ros-diffs] [gedmurphy] 23848: first commit of an overhaul of sc.exe - establish a connection to the SCM for each separate request, allowing the minimum privlidges required, instead of a generic (over privlidged) one. - start to move service printing to separate functions and reduce code duplication - make output 100% as per Windows - fix some commands, e.g. 'interrogate' - improve error checking - improve code structure

gedmurphy at svn.reactos.org gedmurphy at svn.reactos.org
Thu Aug 31 19:59:03 CEST 2006


Author: gedmurphy
Date: Thu Aug 31 21:59:02 2006
New Revision: 23848

URL: http://svn.reactos.org/svn/reactos?rev=23848&view=rev
Log:
first commit of an overhaul of sc.exe
- establish a connection to the SCM for each separate request, allowing the minimum privlidges required, instead of a generic (over privlidged) one.
- start to move service printing to separate functions and reduce code duplication
- make output 100% as per Windows
- fix some commands, e.g. 'interrogate'
- improve error checking
- improve code structure

Added:
    trunk/reactos/base/applications/sc/print.c
Modified:
    trunk/reactos/base/applications/sc/control.c
    trunk/reactos/base/applications/sc/create.c
    trunk/reactos/base/applications/sc/delete.c
    trunk/reactos/base/applications/sc/query.c
    trunk/reactos/base/applications/sc/sc.c
    trunk/reactos/base/applications/sc/sc.h
    trunk/reactos/base/applications/sc/sc.rbuild
    trunk/reactos/base/applications/sc/sc.rc
    trunk/reactos/base/applications/sc/start.c
    trunk/reactos/base/applications/sc/usage.c

Modified: trunk/reactos/base/applications/sc/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/control.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/control.c (original)
+++ trunk/reactos/base/applications/sc/control.c Thu Aug 31 21:59:02 2006
@@ -1,61 +1,95 @@
 /*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS SC utility
- * FILE:        subsys/system/sc/control.c
- * PURPOSE:     control ReactOS services
- * PROGRAMMERS: Ged Murphy (gedmurphy at gmail.com)
- * REVISIONS:
- *           Ged Murphy 20/10/05 Created
+ * PROJECT:     ReactOS Services
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/system/sc/control.c
+ * PURPOSE:     Stops, pauses and resumes a service
+ * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy at gmail.com>
  *
  */
 
 #include "sc.h"
 
-/*
- * handles the following commands:
- * control, continue, interrogate, pause, stop
- */
+BOOL
+Control(DWORD Control,
+        LPCTSTR ServiceName,
+        LPCTSTR *Args,
+        INT ArgCount)
+{
+    SC_HANDLE hSCManager = NULL;
+    SC_HANDLE hSc = NULL;
+    SERVICE_STATUS Status;
+    DWORD dwDesiredAccess = 0;
 
-BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args)
+#ifdef SCDBG
 {
-    SC_HANDLE hSc;
-    SERVICE_STATUS Status;
-
-#ifdef SCDBG    
-    /* testing */
-    _tprintf(_T("service to control - %s\n\n"), ServiceName);
-    _tprintf(_T("command - %lu\n\n"), Control);
-    _tprintf(_T("Arguments :\n"));
-    while (*Args)
+    LPCTSTR *TmpArgs = Args;
+    INT TmpCnt = ArgCount;
+    _tprintf(_T("service to control - %s\n"), ServiceName);
+    _tprintf(_T("command - %lu\n"), Control);
+    _tprintf(_T("Arguments:\n"));
+    while (TmpCnt)
     {
-        printf("%s\n", *Args);
-        Args++;
+        _tprintf(_T("  %s\n"), *TmpArgs);
+        TmpArgs++;
+        TmpCnt--;
     }
+    _tprintf(_T("\n"));
+}
 #endif /* SCDBG */
 
-    hSc = OpenService(hSCManager, ServiceName,
-                      SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE |
-                      SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL |
-                      SERVICE_QUERY_STATUS);
+    switch (Control)
+    {
+        case SERVICE_CONTROL_STOP:
+            dwDesiredAccess = SERVICE_STOP;
+            break;
 
-    if (hSc == NULL)
-    {
-        _tprintf(_T("openService failed\n"));
-        ReportLastError();
-        return FALSE;
+        case SERVICE_CONTROL_PAUSE:
+            dwDesiredAccess = SERVICE_PAUSE_CONTINUE;
+            break;
+
+        case SERVICE_CONTROL_CONTINUE:
+            dwDesiredAccess = SERVICE_PAUSE_CONTINUE;
+            break;
+
+        case SERVICE_CONTROL_INTERROGATE:
+            dwDesiredAccess = SERVICE_INTERROGATE;
+            break;
+
+        case SERVICE_CONTROL_SHUTDOWN:
+            dwDesiredAccess = -1;
+            break;
+
     }
 
-    if (! ControlService(hSc, Control, &Status))
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_CONNECT);
+    if (hSCManager != NULL)
     {
-		_tprintf(_T("[SC] controlService FAILED %lu:\n\n"), GetLastError());
-        ReportLastError();
-        return FALSE;
+        hSc = OpenService(hSCManager,
+                          ServiceName,
+                          dwDesiredAccess);
+        if (hSc != NULL)
+        {
+            if (ControlService(hSc,
+                               Control,
+                               &Status))
+            {
+                PrintService(ServiceName,
+                             &Status);
+
+                CloseServiceHandle(hSc);
+                CloseServiceHandle(hSCManager);
+
+                return TRUE;
+            }
+        }
+        else
+            _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError());
     }
 
-    CloseServiceHandle(hSc);
-    
-    /* print the status information */
-    
-    return TRUE;
-
+    ReportLastError();
+    if (hSc) CloseServiceHandle(hSc);
+    if (hSCManager) CloseServiceHandle(hSCManager);
+    return FALSE;
 }

Modified: trunk/reactos/base/applications/sc/create.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/create.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/create.c (original)
+++ trunk/reactos/base/applications/sc/create.c Thu Aug 31 21:59:02 2006
@@ -1,11 +1,9 @@
 /*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS SC utility
- * FILE:        subsys/system/sc/create.c
- * PURPOSE:     control ReactOS services
- * PROGRAMMERS: Ged Murphy (gedmurphy at gmail.com)
- * REVISIONS:
- *           Ged Murphy 20/10/05 Created
+ * PROJECT:     ReactOS Services
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/system/sc/create.c
+ * PURPOSE:     Create a service
+ * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy at gmail.com>
  *
  */
 
@@ -13,46 +11,81 @@
 
 BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
 {
+    SC_HANDLE hSCManager;
     SC_HANDLE hSc;
-    LPCTSTR BinaryPathName = *++ServiceArgs;
-//    LPCTSTR *Options = ++ServiceArgs;
-    
-    if ((! ServiceName) || (! BinaryPathName))
-        return CreateUsage();
+    BOOL bRet = FALSE;
 
-#ifdef SCDBG  
-    /* testing */
-    printf("service to create - %s\n", ServiceName);
-    printf("Binary path - %s\n", BinaryPathName);
-    printf("Arguments :\n");
-    while (*Options)
+    DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+    DWORD dwStartType = SERVICE_DEMAND_START;
+    DWORD dwErrorControl = SERVICE_ERROR_NORMAL;
+    LPCTSTR lpBinaryPathName = NULL;
+    LPCTSTR lpLoadOrderGroup = NULL;
+    LPDWORD lpdwTagId = NULL;
+    LPCTSTR lpDependencies = NULL;
+    LPCTSTR lpServiceStartName = NULL;
+    LPCTSTR lpPassword = NULL;
+
+    /* quick hack to get it working */
+    lpBinaryPathName = *ServiceArgs;
+
+#ifdef SCDBG
+{
+    _tprintf(_T("service name - %s\n"), ServiceName);
+    _tprintf(_T("display name - %s\n"), ServiceName);
+    _tprintf(_T("service type - %lu\n"), dwServiceType);
+    _tprintf(_T("start type - %lu\n"), dwStartType);
+    _tprintf(_T("error control - %lu\n"), dwErrorControl);
+    _tprintf(_T("Binary path - %s\n"), lpBinaryPathName);
+    _tprintf(_T("load order group - %s\n"), lpLoadOrderGroup);
+    _tprintf(_T("tag - %lu\n"), lpdwTagId);
+    _tprintf(_T("dependincies - %s\n"), lpDependencies);
+    _tprintf(_T("account start name - %s\n"), lpServiceStartName);
+    _tprintf(_T("account password - %s\n"), lpPassword);
+}
+#endif
+
+    if (!ServiceName)
     {
-        printf("%s\n", *Options);
-        Options++;
+        CreateUsage();
+        return FALSE;
     }
-#endif 
+
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_CREATE_SERVICE);
+    if (hSCManager == NULL)
+    {
+        ReportLastError();
+        return FALSE;
+    }
+
     hSc = CreateService(hSCManager,
                         ServiceName,
                         ServiceName,
                         SERVICE_ALL_ACCESS,
-                        SERVICE_WIN32_OWN_PROCESS,
-                        SERVICE_DEMAND_START,
-                        SERVICE_ERROR_NORMAL,
-                        BinaryPathName,
-                        NULL,
-                        NULL,
-                        NULL,
-                        NULL,
-                        NULL);
+                        dwServiceType,
+                        dwStartType,
+                        dwErrorControl,
+                        lpBinaryPathName,
+                        lpLoadOrderGroup,
+                        lpdwTagId,
+                        lpDependencies,
+                        lpServiceStartName,
+                        lpPassword);
 
     if (hSc == NULL)
     {
-        _tprintf(_T("CreateService failed\n"));
         ReportLastError();
-        return FALSE;
+        CloseServiceHandle(hSCManager);
+    }
+    else
+    {
+        _tprintf(_T("[SC] CreateService SUCCESS\n"));
+
+        CloseServiceHandle(hSc);
+        CloseServiceHandle(hSCManager);
+        bRet = TRUE;
     }
 
-	_tprintf(_T("[SC] CreateService SUCCESS\n"));
-    CloseServiceHandle(hSc);
-    return TRUE;
+    return bRet;
 }

Modified: trunk/reactos/base/applications/sc/delete.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/delete.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/delete.c (original)
+++ trunk/reactos/base/applications/sc/delete.c Thu Aug 31 21:59:02 2006
@@ -1,11 +1,9 @@
 /*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS SC utility
- * FILE:        subsys/system/sc/delete.c
- * PURPOSE:     control ReactOS services
- * PROGRAMMERS: Ged Murphy (gedmurphy at gmail.com)
- * REVISIONS:
- *           Ged Murphy 20/10/05 Created
+ * PROJECT:     ReactOS Services
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/system/sc/delete.c
+ * PURPOSE:     Delete a service
+ * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy at gmail.com>
  *
  */
 
@@ -13,30 +11,39 @@
 
 BOOL Delete(LPCTSTR ServiceName)
 {
-    SC_HANDLE hSc;
+    SC_HANDLE hSCManager = NULL;
+    SC_HANDLE hSc = NULL;
 
-#ifdef SCDBG  
-    /* testing */
-    printf("service to delete - %s\n\n", ServiceName);
+#ifdef SCDBG
+{
+    _tprintf(_T("service to delete - %s\n\n"), ServiceName);
+}
 #endif
 
-    hSc = OpenService(hSCManager, ServiceName, DELETE);
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_CONNECT);
+    if (hSCManager != NULL)
+    {
+        hSc = OpenService(hSCManager, ServiceName, DELETE);
+        if (hSc != NULL)
+        {
+            if (DeleteService(hSc))
+            {
+                _tprintf(_T("[SC] DeleteService SUCCESS\n"));
 
-    if (hSc == NULL)
-    {
-        _tprintf(_T("openService failed\n"));
-        ReportLastError();
-        return FALSE;
+                CloseServiceHandle(hSc);
+                CloseServiceHandle(hSCManager);
+
+                return TRUE;
+            }
+        }
     }
 
-    if (! DeleteService(hSc))
-    {
-        _tprintf(_T("DeleteService failed\n"));
-        ReportLastError();
-        return FALSE;
-    }
+    ReportLastError();
 
-	_tprintf(_T("[SC] DeleteService SUCCESS\n"));
-    CloseServiceHandle(hSc);
-    return TRUE;
+    if (hSc) CloseServiceHandle(hSc);
+    if (hSCManager) CloseServiceHandle(hSCManager);
+
+    return FALSE;
 }

Added: trunk/reactos/base/applications/sc/print.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/print.c?rev=23848&view=auto
==============================================================================
--- trunk/reactos/base/applications/sc/print.c (added)
+++ trunk/reactos/base/applications/sc/print.c Thu Aug 31 21:59:02 2006
@@ -1,0 +1,84 @@
+#include "sc.h"
+
+
+VOID
+PrintServiceEx(LPCTSTR lpServiceName,
+               LPSERVICE_STATUS_PROCESS pStatusEx)
+{
+    SERVICE_STATUS Status;
+
+    /*FIXME: quick hack, assign values 1 by 1 */
+    CopyMemory(&Status, pStatusEx, sizeof(SERVICE_STATUS));
+
+    PrintService(lpServiceName,
+                 &Status);
+
+    _tprintf(_T("\tPID                : %lu\n"),
+        pStatusEx->dwProcessId);
+    _tprintf(_T("\tFLAGS              : %lu\n"),
+        pStatusEx->dwServiceFlags);
+}
+
+
+VOID
+PrintService(LPCTSTR lpServiceName,
+             LPSERVICE_STATUS pStatus)
+{
+    _tprintf(_T("SERVICE_NAME: %s\n"), lpServiceName);
+
+    _tprintf(_T("\tTYPE               : %x  "),
+        (unsigned int)pStatus->dwServiceType);
+    switch (pStatus->dwServiceType)
+    {
+        case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
+        case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
+        case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
+        case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
+        default : _tprintf(_T("\n")); break;
+    }
+
+    _tprintf(_T("\tSTATE              : %x  "),
+        (unsigned int)pStatus->dwCurrentState);
+
+    switch (pStatus->dwCurrentState)
+    {
+        case 1 : _tprintf(_T("STOPPED\n")); break;
+        case 2 : _tprintf(_T("START_PENDING\n")); break;
+        case 3 : _tprintf(_T("STOP_PENDING\n")); break;
+        case 4 : _tprintf(_T("RUNNING\n")); break;
+        case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
+        case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
+        case 7 : _tprintf(_T("PAUSED\n")); break;
+        default : _tprintf(_T("\n")); break;
+    }
+
+    _tprintf(_T("\t\t\t\t("));
+
+    if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP)
+        _tprintf(_T("STOPPABLE,"));
+    else
+        _tprintf(_T("NOT_STOPPABLE,"));
+
+    if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE)
+        _tprintf(_T("PAUSABLE,"));
+    else
+        _tprintf(_T("NOT_PAUSABLE,"));
+
+    if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN)
+        _tprintf(_T("???"));
+    else
+        _tprintf(_T("IGNORES_SHUTDOWN"));
+
+    _tprintf(_T(")\n"));
+
+    _tprintf(_T("\tWIN32_EXIT_CODE    : %d  (0x%x)\n"),
+        (unsigned int)pStatus->dwWin32ExitCode,
+        (unsigned int)pStatus->dwWin32ExitCode);
+    _tprintf(_T("\tSERVICE_EXIT_CODE  : %d  (0x%x)\n"),
+        (unsigned int)pStatus->dwServiceSpecificExitCode,
+        (unsigned int)pStatus->dwServiceSpecificExitCode);
+    _tprintf(_T("\tCHECKPOINT         : 0x%x\n"),
+        (unsigned int)pStatus->dwCheckPoint);
+    _tprintf(_T("\tWAIT_HINT          : 0x%x\n"),
+        (unsigned int)pStatus->dwWaitHint);
+}

Modified: trunk/reactos/base/applications/sc/query.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/query.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/query.c (original)
+++ trunk/reactos/base/applications/sc/query.c Thu Aug 31 21:59:02 2006
@@ -17,7 +17,7 @@
 #include "sc.h"
 
 /* local function decs */
-VOID PrintService(BOOL bExtended);
+VOID PrintService2(BOOL bExtended);
 BOOL EnumServices(DWORD ServiceType, DWORD ServiceState);
 BOOL QueryService(LPCTSTR ServiceName, BOOL bExtended);
 
@@ -33,14 +33,14 @@
     {
         /* get default values */
         EnumServices(SERVICE_WIN32, SERVICE_ACTIVE);
-        
+
         /* print default values */
-        PrintService(bExtended);
+        PrintService2(bExtended);
     }
     else if (_tcsicmp(ServiceName, _T("type=")) == 0)
     {
         LPCTSTR Type = *ServiceArgs;
-        
+
         if (_tcsicmp(Type, _T("driver")) == 0)
             EnumServices(SERVICE_DRIVER, SERVICE_ACTIVE);
         else if (_tcsicmp(Type, _T("service")) == 0)
@@ -52,8 +52,8 @@
             _tprintf(_T("\nERROR following \"type=\"!\n"));
             _tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n"));
         }
-        
-        PrintService(bExtended);
+
+        PrintService2(bExtended);
     }
     else if(_tcsicmp(ServiceName, _T("state=")) == 0)
     {
@@ -68,8 +68,8 @@
             _tprintf(_T("\nERROR following \"state=\"!\n"));
             _tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n"));
         }
-            
-        PrintService(bExtended);
+
+        PrintService2(bExtended);
     }
 /*
     else if(_tcsicmp(ServiceName, _T("bufsize=")))
@@ -82,7 +82,7 @@
     {
         QueryService(ServiceName, bExtended);
     }
-    
+
     return TRUE;
 }
 
@@ -90,11 +90,21 @@
 BOOL
 QueryService(LPCTSTR ServiceName, BOOL bExtended)
 {
+    SC_HANDLE hSCManager;
     SERVICE_STATUS_PROCESS *pServiceInfo = NULL;
     SC_HANDLE hSc;
     DWORD BufSiz = 0;
     DWORD BytesNeeded = 0;
     DWORD Ret;
+
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_CONNECT);
+    if (hSCManager == NULL)
+    {
+        ReportLastError();
+        return FALSE;
+    }
 
     hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS);
 
@@ -143,7 +153,7 @@
         }
     }
 
-    
+
     _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
 
     _tprintf(_T("\tTYPE               : %x  "),
@@ -193,7 +203,7 @@
         _tprintf(_T("\tFLAGS              : %lu\n"),
             pServiceInfo->dwServiceFlags);
     }
-    
+
     HeapFree(GetProcessHeap(), 0, pServiceInfo);
 
     return TRUE;
@@ -203,10 +213,20 @@
 BOOL
 EnumServices(DWORD ServiceType, DWORD ServiceState)
 {
+    SC_HANDLE hSCManager;
     DWORD BufSize = 0;
     DWORD BytesNeeded = 0;
     DWORD ResumeHandle = 0;
     DWORD Ret;
+
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_ENUMERATE_SERVICE);
+    if (hSCManager == NULL)
+    {
+        ReportLastError();
+        return FALSE;
+    }
 
     /* determine required buffer size */
     Ret = EnumServicesStatusEx(hSCManager,
@@ -262,10 +282,10 @@
 
 
 VOID
-PrintService(BOOL bExtended)
+PrintService2(BOOL bExtended)
 {
     DWORD i;
-    
+
     for (i=0; i < NumServices; i++)
     {
 
@@ -322,6 +342,6 @@
 
             _tprintf(_T("\n"));
     }
-    
+
     _tprintf(_T("number : %lu\n"), NumServices);
 }

Modified: trunk/reactos/base/applications/sc/sc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/sc.c (original)
+++ trunk/reactos/base/applications/sc/sc.c Thu Aug 31 21:59:02 2006
@@ -1,11 +1,9 @@
 /*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS SC utility
- * FILE:        subsys/system/sc/sc.c
- * PURPOSE:     control ReactOS services
- * PROGRAMMERS: Ged Murphy (gedmurphy at gmail.com)
- * REVISIONS:
- *           Ged Murphy 20/10/05 Created
+ * PROJECT:     ReactOS Services
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/system/sc/sc.c
+ * PURPOSE:     parse command line
+ * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy at gmail.com>
  *
  */
 
@@ -13,13 +11,14 @@
 
 SC_HANDLE hSCManager;
 
-DWORD ReportLastError(VOID)
+VOID
+ReportLastError(VOID)
 {
     LPVOID lpMsgBuf;
     DWORD RetVal;
 
     DWORD ErrorCode = GetLastError();
-    if (ErrorCode != ERROR_SUCCESS) 
+    if (ErrorCode != ERROR_SUCCESS)
     {
         RetVal = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                FORMAT_MESSAGE_FROM_SYSTEM |
@@ -34,106 +33,133 @@
         if (RetVal != 0)
         {
             _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
-
             LocalFree(lpMsgBuf);
-            /* return number of TCHAR's stored in output buffer
-             * excluding '\0' - as FormatMessage does*/
-            return RetVal;
-        }
-    }
-    return 0;
-}
-
-
-INT ScControl(LPTSTR MachineName,   // remote machine name
-              LPCTSTR Command,      // sc command
-              LPCTSTR ServiceName,  // name of service
-              LPCTSTR *ServiceArgs, // any options
-              DWORD ArgCount)       // argument counter
-{
-    /* count trailing arguments */
-    ArgCount -= 3;
-
-    if (MachineName)
+        }
+    }
+}
+
+
+static INT
+ScControl(LPCTSTR Server,       // remote machine name
+          LPCTSTR Command,      // sc command
+          LPCTSTR ServiceName,  // name of service
+          LPCTSTR *ServiceArgs, // any options
+          DWORD ArgCount)       // argument counter
+{
+    if (Server)
     {
         _tprintf(_T("Remote service control is not yet implemented\n"));
         return 2;
     }
-    
-    /* if we are emurating the services, we don't need administrator access */
-    if ( (_tcsicmp(Command, _T("query")) == 0) || (_tcsicmp(Command, _T("queryex")) == 0) )
-        hSCManager = OpenSCManager(MachineName, NULL, SC_MANAGER_ENUMERATE_SERVICE);
-    else
-        hSCManager = OpenSCManager(MachineName, NULL, SC_MANAGER_ALL_ACCESS);
-    if (hSCManager == NULL)
-    {
-        _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError());
-        ReportLastError();
-        return -1;
-    }
-
-    /* emurate command */
-    if (_tcsicmp(Command, _T("query")) == 0)
-        Query(ServiceName, ServiceArgs, FALSE);
-        
-    else if (_tcsicmp(Command, _T("queryex")) == 0)
-        Query(ServiceName, ServiceArgs, TRUE);
-        
-    else if (_tcsicmp(Command, _T("start")) == 0)
-    {
-        if (ServiceName)
-            Start(ServiceName, ServiceArgs, ArgCount);
+
+    if (!lstrcmpi(Command, _T("query")))
+    {
+        Query(ServiceName,
+              ServiceArgs,
+              FALSE);
+    }
+    else if (!lstrcmpi(Command, _T("queryex")))
+    {
+        Query(ServiceName,
+              ServiceArgs,
+              TRUE);
+    }
+    else if (!lstrcmpi(Command, _T("start")))
+    {
+        if (ServiceName)
+        {
+            Start(ServiceName,
+                  ServiceArgs,
+                  ArgCount);
+        }
         else
             StartUsage();
     }
-    else if (_tcsicmp(Command, _T("pause")) == 0)
-    {
-        if (ServiceName)
-            Control(SERVICE_CONTROL_PAUSE, ServiceName, ServiceArgs);
+    else if (!lstrcmpi(Command, _T("pause")))
+    {
+        if (ServiceName)
+        {
+            Control(SERVICE_CONTROL_PAUSE,
+                    ServiceName,
+                    ServiceArgs,
+                    ArgCount);
+        }
         else
             PauseUsage();
     }
-    else if (_tcsicmp(Command, _T("interrogate")) == 0)
-    {
-        if (ServiceName)
-            Control(SERVICE_CONTROL_INTERROGATE, ServiceName, ServiceArgs);
+    else if (!lstrcmpi(Command, _T("interrogate")))
+    {
+        if (ServiceName)
+        {
+            Control(SERVICE_CONTROL_INTERROGATE,
+                    ServiceName,
+                    ServiceArgs,
+                    ArgCount);
+        }
         else
             InterrogateUsage();
     }
-    else if (_tcsicmp(Command, _T("stop")) == 0)
-    {
-        if (ServiceName)
-            Control(SERVICE_CONTROL_STOP, ServiceName, ServiceArgs);
+    else if (!lstrcmpi(Command, _T("stop")))
+    {
+        if (ServiceName)
+        {
+            Control(SERVICE_CONTROL_STOP,
+                    ServiceName,
+                    ServiceArgs,
+                    ArgCount);
+        }
         else
             StopUsage();
     }
-    else if (_tcsicmp(Command, _T("continue")) == 0)
-    {
-        if (ServiceName)
-            Control(SERVICE_CONTROL_CONTINUE, ServiceName, ServiceArgs);
+    else if (!lstrcmpi(Command, _T("continue")))
+    {
+        if (ServiceName)
+        {
+            Control(SERVICE_CONTROL_CONTINUE,
+                    ServiceName,
+                    ServiceArgs,
+                    ArgCount);
+        }
         else
             ContinueUsage();
     }
-    else if (_tcsicmp(Command, _T("delete")) == 0)
+    else if (!lstrcmpi(Command, _T("delete")))
     {
         if (ServiceName)
             Delete(ServiceName);
         else
             DeleteUsage();
     }
-    else if (_tcsicmp(Command, _T("create")) == 0)
+    else if (!lstrcmpi(Command, _T("create")))
     {
         if (*ServiceArgs)
-            Create(ServiceName, ServiceArgs);
+            Create(ServiceName,
+                   ServiceArgs);
         else
             CreateUsage();
     }
-    else if (_tcsicmp(Command, _T("control")) == 0)
-    {
-        if (ServiceName)
-            Control(0, ServiceName, ServiceArgs);
-        else
-            ContinueUsage();
+    else if (!lstrcmpi(Command, _T("control")))
+    {
+        INT CtlValue;
+
+        CtlValue = _ttoi(ServiceArgs[0]);
+        ServiceArgs++;
+        ArgCount--;
+
+        if (ServiceName)
+        {
+            if ((CtlValue >=128) && CtlValue <= 255)
+            {
+                Control(CtlValue,
+                        ServiceName,
+                        ServiceArgs,
+                        ArgCount);
+
+                return 0;
+            }
+        }
+
+        ContinueUsage();
     }
     return 0;
 }
@@ -144,31 +170,47 @@
 
 int _tmain(int argc, LPCTSTR argv[])
 {
-	LPTSTR MachineName = NULL;   // remote machine
-    LPCTSTR Command = NULL;      // sc command
-    LPCTSTR ServiceName = NULL;  // Name of service
+	LPCTSTR Server = NULL;      // remote machine
+    LPCTSTR Command = NULL;     // sc command
+    LPCTSTR ServiceName = NULL; // name of service
 
     if (argc < 2)
-        return MainUsage();
+    {
+        MainUsage();
+        return -1;
+    }
 
     /* get server name */
     if ((argv[1][0] == '\\') && (argv[1][1] == '\\'))
     {
         if (argc < 3)
-            return MainUsage();
-
-        _tcscpy(MachineName, argv[1]);
+        {
+            MainUsage();
+            return -1;
+        }
+
+        Server = argv[1];
         Command = argv[2];
         if (argc > 3)
             ServiceName = argv[3];
-        return ScControl(MachineName, Command, ServiceName,  &argv[4], argc);
+
+        return ScControl(Server,
+                         Command,
+                         ServiceName,
+                         &argv[4],
+                         argc-4);
     }
     else
     {
         Command = argv[1];
         if (argc > 2)
             ServiceName = argv[2];
-        return ScControl(MachineName, Command, ServiceName, &argv[3], argc);
+
+        return ScControl(Server,
+                         Command,
+                         ServiceName,
+                         &argv[3],
+                         argc-3);
     }
 }
 
@@ -191,13 +233,13 @@
             }
             swprintf(argvW[i], L"%hs", argv[i]);
         }
-        
+
         if (j == 0)
         {
             /* no error converting the parameters, call wmain() */
             Ret = wmain(argc, (LPCTSTR *)argvW);
         }
-        
+
         /* free the arguments */
         for (i = 0; i < argc; i++)
         {
@@ -206,7 +248,7 @@
         }
         free(argvW);
     }
-    
+
     return Ret;
 }
 #endif

Modified: trunk/reactos/base/applications/sc/sc.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.h?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/sc.h (original)
+++ trunk/reactos/base/applications/sc/sc.h Thu Aug 31 21:59:02 2006
@@ -3,28 +3,29 @@
 #include <stdio.h>
 #include <tchar.h>
 
-extern SC_HANDLE hSCManager; // declared in sc.c
+#define SCDBG
 
-//#define SCDBG
+VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS pStatus);
+VOID PrintServiceEx(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus);
 
 /* control functions */
 BOOL Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended);
 BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount);
 BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs);
 BOOL Delete(LPCTSTR ServiceName);
-BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args);
+BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount);
 
 /* print and error functions */
-DWORD ReportLastError(VOID);
+VOID ReportLastError(VOID);
 
 /* usage functions */
-INT MainUsage(VOID);
-INT StartUsage(VOID);
-INT PauseUsage(VOID);
-INT InterrogateUsage(VOID);
-INT ContinueUsage(VOID);
-INT StopUsage(VOID);
-INT ConfigUsage(VOID);
-INT DescriptionUsage(VOID);
-INT DeleteUsage(VOID);
-INT CreateUsage(VOID);
+VOID MainUsage(VOID);
+VOID StartUsage(VOID);
+VOID PauseUsage(VOID);
+VOID InterrogateUsage(VOID);
+VOID ContinueUsage(VOID);
+VOID StopUsage(VOID);
+VOID ConfigUsage(VOID);
+VOID DescriptionUsage(VOID);
+VOID DeleteUsage(VOID);
+VOID CreateUsage(VOID);

Modified: trunk/reactos/base/applications/sc/sc.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.rbuild?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/sc.rbuild (original)
+++ trunk/reactos/base/applications/sc/sc.rbuild Thu Aug 31 21:59:02 2006
@@ -7,12 +7,13 @@
 	<define name="_UNICODE" />
 	<library>kernel32</library>
 	<library>advapi32</library>
-	<file>sc.c</file>
-	<file>start.c</file>
-	<file>query.c</file>
 	<file>control.c</file>
 	<file>create.c</file>
 	<file>delete.c</file>
+	<file>print.c</file>
+	<file>query.c</file>
+	<file>sc.c</file>
+	<file>start.c</file>	
 	<file>usage.c</file>
 	<file>sc.rc</file>
 	<pch>sc.h</pch>

Modified: trunk/reactos/base/applications/sc/sc.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.rc?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/sc.rc (original)
+++ trunk/reactos/base/applications/sc/sc.rc Thu Aug 31 21:59:02 2006
@@ -1,4 +1,10 @@
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+
 #define REACTOS_STR_FILE_DESCRIPTION	"Services control application\0"
 #define REACTOS_STR_INTERNAL_NAME	"sc\0"
 #define REACTOS_STR_ORIGINAL_FILENAME	"sc.exe\0"
 #include <reactos/version.rc>
+
+//#include "En.rc"

Modified: trunk/reactos/base/applications/sc/start.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/start.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/start.c (original)
+++ trunk/reactos/base/applications/sc/start.c Thu Aug 31 21:59:02 2006
@@ -1,11 +1,9 @@
 /*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS SC utility
- * FILE:        subsys/system/sc/start.c
- * PURPOSE:     control ReactOS services
- * PROGRAMMERS: Ged Murphy (gedmurphy at gmail.com)
- * REVISIONS:
- *           Ged Murphy 20/10/05 Created
+ * PROJECT:     ReactOS Services
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/system/sc/start.c
+ * PURPOSE:     Start a service
+ * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy at gmail.com>
  *
  */
 
@@ -13,99 +11,91 @@
 
 BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
 {
-    SC_HANDLE hSc;
-    SERVICE_STATUS_PROCESS ServiceStatus, ServiceStatus2;
-    DWORD BytesNeeded;
+    SC_HANDLE hSCManager = NULL;
+    SC_HANDLE hSc = NULL;
+    LPSERVICE_STATUS_PROCESS pServiceInfo = NULL;
+    DWORD BufSiz = 0;
+    DWORD BytesNeeded = 0;
+    DWORD Ret;
 
-#ifdef SCDBG  
-    /* testing */
-    _tprintf(_T("service to start - %s\n\n"), ServiceName);
-    _tprintf(_T("Arguments :\n"));
-    while (*ServiceArgs)
+#ifdef SCDBG
+{
+    LPCTSTR *TmpArgs = ServiceArgs;
+    INT TmpCnt = ArgCount;
+    _tprintf(_T("service to control - %s\n"), ServiceName);
+    _tprintf(_T("Arguments:\n"));
+    while (TmpCnt)
     {
-        printf("%s\n", *ServiceArgs);
-        ServiceArgs++;
+        _tprintf(_T("  %s\n"), *TmpArgs);
+        TmpArgs++;
+        TmpCnt--;
     }
-#endif    
+    _tprintf(_T("\n"));
+}
+#endif /* SCDBG */
 
-    /* get a handle to the service requested for starting */
-    hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS);
+    hSCManager = OpenSCManager(NULL,
+                               NULL,
+                               SC_MANAGER_CONNECT);
+    if (hSCManager == NULL)
+        goto fail;
+
+    hSc = OpenService(hSCManager,
+                      ServiceName,
+                      SERVICE_START | SERVICE_QUERY_STATUS);
 
     if (hSc == NULL)
     {
         _tprintf(_T("openService failed\n"));
-        ReportLastError();
-        return FALSE;
+        goto fail;
     }
 
-    /* start the service opened */
-    if (! StartService(hSc, ArgCount, ServiceArgs))
+    if (! StartService(hSc,
+                       ArgCount,
+                       ServiceArgs))
     {
 		_tprintf(_T("[SC] StartService FAILED %lu:\n\n"), GetLastError());
-        ReportLastError();
-        return FALSE;
-    }
-    
-    if (! QueryServiceStatusEx(
-            hSc,
-            SC_STATUS_PROCESS_INFO,
-            (LPBYTE)&ServiceStatus,
-            sizeof(SERVICE_STATUS_PROCESS),
-            &BytesNeeded))
-    {
-        _tprintf(_T("QueryServiceStatusEx 1 failed\n"));
-        ReportLastError();
-        return FALSE;
+        goto fail;
     }
 
-    
-    while (ServiceStatus.dwCurrentState == SERVICE_START_PENDING)
+    Ret = QueryServiceStatusEx(hSc,
+                               SC_STATUS_PROCESS_INFO,
+                               NULL,
+                               BufSiz,
+                               &BytesNeeded);
+    if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) //FIXME: check this
+        goto fail;
+
+
+    pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(),
+                                                       0,
+                                                       BytesNeeded);
+    if (pServiceInfo == NULL)
+        goto fail;
+
+    if (!QueryServiceStatusEx(hSc,
+                              SC_STATUS_PROCESS_INFO,
+                              (LPBYTE)pServiceInfo,
+                              BytesNeeded,
+                              &BytesNeeded))
     {
-        /* wait before checking status */
-        Sleep(ServiceStatus.dwWaitHint);
-        
-        /* check status again */
-        if (! QueryServiceStatusEx(
-                hSc,
-                SC_STATUS_PROCESS_INFO,
-                (LPBYTE)&ServiceStatus,
-                sizeof(SERVICE_STATUS_PROCESS),
-                &BytesNeeded))
-        {
-            _tprintf(_T("QueryServiceStatusEx 2 failed\n"));
-            ReportLastError();
-            return FALSE;
-        }
+        goto fail;
     }
 
-	QueryServiceStatusEx(hSc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus2, 
-		sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded);
+    PrintServiceEx(ServiceName,
+                   pServiceInfo);
 
+    HeapFree(GetProcessHeap(), 0, pServiceInfo);
     CloseServiceHandle(hSc);
-    
-    if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
-    {
-        _tprintf(_T("\nSERVICE_NAME: %s\n"), ServiceName);
-        _tprintf(_T("\tTYPE               : %lu\n"), ServiceStatus2.dwServiceType);
-        _tprintf(_T("\tSTATE              : %lu\n"), ServiceStatus2.dwCurrentState);
-		_tprintf(_T("\tWIN32_EXIT_CODE    : %lu\n"), ServiceStatus2.dwWin32ExitCode);
-		_tprintf(_T("\tCHECKPOINT         : %lu\n"), ServiceStatus2.dwCheckPoint);
-		_tprintf(_T("\tWAIT_HINT          : %lu\n"), ServiceStatus2.dwWaitHint);
-		_tprintf(_T("\tPID                : %lu\n"), ServiceStatus2.dwProcessId);
-		_tprintf(_T("\tFLAGS              : %lu\n"), ServiceStatus2.dwServiceFlags);
+    CloseServiceHandle(hSCManager);
 
-        return TRUE;
-    }
-    else
-    {
-        _tprintf(_T("Failed to start %s\n"), ServiceName);
-        _tprintf(_T("Curent state: %lu\n"), ServiceStatus.dwCurrentState);
-        _tprintf(_T("Exit code: %lu\n"), ServiceStatus.dwWin32ExitCode);
-        _tprintf(_T("Service Specific exit code: %lu\n"),
-                ServiceStatus.dwServiceSpecificExitCode);
-        _tprintf(_T("Check point: %lu\n"), ServiceStatus.dwCheckPoint);
-        _tprintf(_T("Wait hint: %lu\n"), ServiceStatus.dwWaitHint);
-        
-        return FALSE;
-    }
+    return TRUE;
+
+fail:
+    ReportLastError();
+    if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo);
+    if (hSc) CloseServiceHandle(hSc);
+    if (hSCManager) CloseServiceHandle(hSCManager);
+    return FALSE;
+
 }

Modified: trunk/reactos/base/applications/sc/usage.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/usage.c?rev=23848&r1=23847&r2=23848&view=diff
==============================================================================
--- trunk/reactos/base/applications/sc/usage.c (original)
+++ trunk/reactos/base/applications/sc/usage.c Thu Aug 31 21:59:02 2006
@@ -10,7 +10,7 @@
  */
 #include "sc.h"
 
-INT MainUsage(VOID)
+VOID MainUsage(VOID)
 {
     INT c;
 
@@ -88,84 +88,67 @@
         _T("sc query type= service type= interact - Enumerates all interactive services\n"));
 //        _T("sc query type= driver group= NDIS     - Enumerates all NDIS drivers\n"));
     }
-
-
-    return 0;
 }
 
 
-INT StartUsage(VOID)
+VOID StartUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Starts a service running.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> start [service name] <arg1> <arg2> ...\n"));
-
-    return 0;
 }
 
 
-INT PauseUsage(VOID)
+VOID PauseUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Sends a PAUSE control request to a service.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> pause [service name]\n"));
-
-    return 0;
 }
 
-INT InterrogateUsage(VOID)
+VOID InterrogateUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Sends an INTERROGATE control request to a service.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> interrogate [service name]\n"));
-
-    return 0;
 }
 
 
-INT StopUsage(VOID)
+VOID StopUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Sends an STOP control request to a service.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> stop [service name]\n"));
-
-    return 0;
 }
 
-INT ContinueUsage(VOID)
+VOID ContinueUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Sends an CONTINUE control request to a service.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> continue [service name]\n"));
-
-    return 0;
 }
 
 
-INT ConfigUsage(VOID)
+VOID ConfigUsage(VOID)
 {
     _tprintf(_T("not yet implemented\n"));
-
-    return 0;
 }
 
 
-INT DescriptionUsage(VOID)
+VOID DescriptionUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Sets the description string for a service.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> description [service name]\n"));
-
-    return 0;
 }
 
-INT DeleteUsage(VOID)
+VOID DeleteUsage(VOID)
 {
     _tprintf(_T("DESCRIPTION:\n")
                 _T("        Deletes a service entry from the registry.\n")
@@ -174,11 +157,9 @@
                 _T("        for deletion.\n")
                 _T("USAGE:\n")
                 _T("        sc <server> delete [service name]\n"));
-
-    return 0;
 }
 
-INT CreateUsage(VOID)
+VOID CreateUsage(VOID)
 {
     _tprintf(_T("Creates a service entry in the registry and Service Database.\n")
                 _T("SYNTAX:\n")
@@ -199,6 +180,4 @@
                 _T("       (default = LocalSystem)\n")
                 _T(" DisplayName= <display name>\n")
                 _T(" password= <password>\n"));
-
-    return 0;
 }




More information about the Ros-diffs mailing list