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/contr…
==============================================================================
--- 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(a)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(a)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/creat…
==============================================================================
--- 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(a)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(a)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/delet…
==============================================================================
--- 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(a)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(a)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…
==============================================================================
--- 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…
==============================================================================
--- 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?…
==============================================================================
--- 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(a)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(a)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?…
==============================================================================
--- 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.rb…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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(a)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(a)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…
==============================================================================
--- 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;
}