- 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
svn path=/trunk/; revision=23848
/*
- * 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@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@gmail.com>
*
*/
#include "sc.h"
-/*
- * handles the following commands:
- * control, continue, interrogate, pause, stop
- */
-
-BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args)
+BOOL
+Control(DWORD Control,
+ LPCTSTR ServiceName,
+ LPCTSTR *Args,
+ INT ArgCount)
{
- SC_HANDLE hSc;
+ SC_HANDLE hSCManager = NULL;
+ SC_HANDLE hSc = NULL;
SERVICE_STATUS Status;
+ DWORD dwDesiredAccess = 0;
-#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)
+#ifdef SCDBG
+{
+ 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);
-
- if (hSc == NULL)
+ switch (Control)
{
- _tprintf(_T("openService failed\n"));
- ReportLastError();
- return FALSE;
+ case SERVICE_CONTROL_STOP:
+ dwDesiredAccess = SERVICE_STOP;
+ break;
+
+ 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);
- CloseServiceHandle(hSc);
-
- /* print the status information */
-
- return TRUE;
+ return TRUE;
+ }
+ }
+ else
+ _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError());
+ }
+ ReportLastError();
+ if (hSc) CloseServiceHandle(hSc);
+ if (hSCManager) CloseServiceHandle(hSCManager);
+ return FALSE;
}
/*
- * 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@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@gmail.com>
*
*/
BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
{
+ SC_HANDLE hSCManager;
SC_HANDLE hSc;
- LPCTSTR BinaryPathName = *++ServiceArgs;
-// LPCTSTR *Options = ++ServiceArgs;
-
- if ((! ServiceName) || (! BinaryPathName))
- return CreateUsage();
-
-#ifdef SCDBG
- /* testing */
- printf("service to create - %s\n", ServiceName);
- printf("Binary path - %s\n", BinaryPathName);
- printf("Arguments :\n");
- while (*Options)
+ BOOL bRet = FALSE;
+
+ 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;
}
/*
- * 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@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@gmail.com>
*
*/
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);
-
- if (hSc == NULL)
+ hSCManager = OpenSCManager(NULL,
+ NULL,
+ SC_MANAGER_CONNECT);
+ if (hSCManager != NULL)
{
- _tprintf(_T("openService failed\n"));
- ReportLastError();
- return FALSE;
- }
+ hSc = OpenService(hSCManager, ServiceName, DELETE);
+ if (hSc != NULL)
+ {
+ if (DeleteService(hSc))
+ {
+ _tprintf(_T("[SC] DeleteService SUCCESS\n"));
- if (! DeleteService(hSc))
- {
- _tprintf(_T("DeleteService failed\n"));
- ReportLastError();
- return FALSE;
+ CloseServiceHandle(hSc);
+ CloseServiceHandle(hSCManager);
+
+ return TRUE;
+ }
+ }
}
- _tprintf(_T("[SC] DeleteService SUCCESS\n"));
- CloseServiceHandle(hSc);
- return TRUE;
+ ReportLastError();
+
+ if (hSc) CloseServiceHandle(hSc);
+ if (hSCManager) CloseServiceHandle(hSCManager);
+
+ return FALSE;
}
--- /dev/null
+#include "sc.h"\r
+\r
+\r
+VOID\r
+PrintServiceEx(LPCTSTR lpServiceName,\r
+ LPSERVICE_STATUS_PROCESS pStatusEx)\r
+{\r
+ SERVICE_STATUS Status;\r
+\r
+ /*FIXME: quick hack, assign values 1 by 1 */\r
+ CopyMemory(&Status, pStatusEx, sizeof(SERVICE_STATUS));\r
+\r
+ PrintService(lpServiceName,\r
+ &Status);\r
+\r
+ _tprintf(_T("\tPID : %lu\n"),\r
+ pStatusEx->dwProcessId);\r
+ _tprintf(_T("\tFLAGS : %lu\n"),\r
+ pStatusEx->dwServiceFlags);\r
+}\r
+\r
+\r
+VOID\r
+PrintService(LPCTSTR lpServiceName,\r
+ LPSERVICE_STATUS pStatus)\r
+{\r
+ _tprintf(_T("SERVICE_NAME: %s\n"), lpServiceName);\r
+\r
+ _tprintf(_T("\tTYPE : %x "),\r
+ (unsigned int)pStatus->dwServiceType);\r
+ switch (pStatus->dwServiceType)\r
+ {\r
+ case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;\r
+ case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;\r
+ case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;\r
+ case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;\r
+ default : _tprintf(_T("\n")); break;\r
+ }\r
+\r
+ _tprintf(_T("\tSTATE : %x "),\r
+ (unsigned int)pStatus->dwCurrentState);\r
+\r
+ switch (pStatus->dwCurrentState)\r
+ {\r
+ case 1 : _tprintf(_T("STOPPED\n")); break;\r
+ case 2 : _tprintf(_T("START_PENDING\n")); break;\r
+ case 3 : _tprintf(_T("STOP_PENDING\n")); break;\r
+ case 4 : _tprintf(_T("RUNNING\n")); break;\r
+ case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;\r
+ case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;\r
+ case 7 : _tprintf(_T("PAUSED\n")); break;\r
+ default : _tprintf(_T("\n")); break;\r
+ }\r
+\r
+ _tprintf(_T("\t\t\t\t("));\r
+\r
+ if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP)\r
+ _tprintf(_T("STOPPABLE,"));\r
+ else\r
+ _tprintf(_T("NOT_STOPPABLE,"));\r
+\r
+ if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE)\r
+ _tprintf(_T("PAUSABLE,"));\r
+ else\r
+ _tprintf(_T("NOT_PAUSABLE,"));\r
+\r
+ if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN)\r
+ _tprintf(_T("???"));\r
+ else\r
+ _tprintf(_T("IGNORES_SHUTDOWN"));\r
+\r
+ _tprintf(_T(")\n"));\r
+\r
+ _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),\r
+ (unsigned int)pStatus->dwWin32ExitCode,\r
+ (unsigned int)pStatus->dwWin32ExitCode);\r
+ _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),\r
+ (unsigned int)pStatus->dwServiceSpecificExitCode,\r
+ (unsigned int)pStatus->dwServiceSpecificExitCode);\r
+ _tprintf(_T("\tCHECKPOINT : 0x%x\n"),\r
+ (unsigned int)pStatus->dwCheckPoint);\r
+ _tprintf(_T("\tWAIT_HINT : 0x%x\n"),\r
+ (unsigned int)pStatus->dwWaitHint);\r
+}\r
#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);
{
/* 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)
_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)
{
_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=")))
{
QueryService(ServiceName, bExtended);
}
-
+
return TRUE;
}
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);
if (hSc == NULL)
}
}
-
+
_tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
_tprintf(_T("\tTYPE : %x "),
_tprintf(_T("\tFLAGS : %lu\n"),
pServiceInfo->dwServiceFlags);
}
-
+
HeapFree(GetProcessHeap(), 0, pServiceInfo);
return TRUE;
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,
SC_ENUM_PROCESS_INFO,
VOID
-PrintService(BOOL bExtended)
+PrintService2(BOOL bExtended)
{
DWORD i;
-
+
for (i=0; i < NumServices; i++)
{
_tprintf(_T("\n"));
}
-
+
_tprintf(_T("number : %lu\n"), NumServices);
}
/*
- * 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@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@gmail.com>
*
*/
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 |
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
+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
{
- /* count trailing arguments */
- ArgCount -= 3;
-
- if (MachineName)
+ 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)
+
+ if (!lstrcmpi(Command, _T("query")))
{
- _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError());
- ReportLastError();
- return -1;
+ Query(ServiceName,
+ ServiceArgs,
+ FALSE);
}
-
- /* 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)
+ else if (!lstrcmpi(Command, _T("queryex")))
+ {
+ Query(ServiceName,
+ ServiceArgs,
+ TRUE);
+ }
+ else if (!lstrcmpi(Command, _T("start")))
{
if (ServiceName)
- Start(ServiceName, ServiceArgs, ArgCount);
+ {
+ Start(ServiceName,
+ ServiceArgs,
+ ArgCount);
+ }
else
StartUsage();
}
- else if (_tcsicmp(Command, _T("pause")) == 0)
+ else if (!lstrcmpi(Command, _T("pause")))
{
if (ServiceName)
- Control(SERVICE_CONTROL_PAUSE, ServiceName, ServiceArgs);
+ {
+ Control(SERVICE_CONTROL_PAUSE,
+ ServiceName,
+ ServiceArgs,
+ ArgCount);
+ }
else
PauseUsage();
}
- else if (_tcsicmp(Command, _T("interrogate")) == 0)
+ else if (!lstrcmpi(Command, _T("interrogate")))
{
if (ServiceName)
- Control(SERVICE_CONTROL_INTERROGATE, ServiceName, ServiceArgs);
+ {
+ Control(SERVICE_CONTROL_INTERROGATE,
+ ServiceName,
+ ServiceArgs,
+ ArgCount);
+ }
else
InterrogateUsage();
}
- else if (_tcsicmp(Command, _T("stop")) == 0)
+ else if (!lstrcmpi(Command, _T("stop")))
{
if (ServiceName)
- Control(SERVICE_CONTROL_STOP, ServiceName, ServiceArgs);
+ {
+ Control(SERVICE_CONTROL_STOP,
+ ServiceName,
+ ServiceArgs,
+ ArgCount);
+ }
else
StopUsage();
}
- else if (_tcsicmp(Command, _T("continue")) == 0)
+ else if (!lstrcmpi(Command, _T("continue")))
{
if (ServiceName)
- Control(SERVICE_CONTROL_CONTINUE, ServiceName, ServiceArgs);
+ {
+ 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)
+ else if (!lstrcmpi(Command, _T("control")))
{
+ INT CtlValue;
+
+ CtlValue = _ttoi(ServiceArgs[0]);
+ ServiceArgs++;
+ ArgCount--;
+
if (ServiceName)
- Control(0, ServiceName, ServiceArgs);
- else
- ContinueUsage();
+ {
+ if ((CtlValue >=128) && CtlValue <= 255)
+ {
+ Control(CtlValue,
+ ServiceName,
+ ServiceArgs,
+ ArgCount);
+
+ return 0;
+ }
+ }
+
+ ContinueUsage();
}
return 0;
}
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();
+ {
+ MainUsage();
+ return -1;
+ }
- _tcscpy(MachineName, argv[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);
}
}
}
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++)
{
}
free(argvW);
}
-
+
return Ret;
}
#endif
#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);
<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>
+#include <windows.h>\r
+#include <commctrl.h>\r
+#include "resource.h"\r
+\r
#define REACTOS_STR_FILE_DESCRIPTION "Services control application\0"\r
#define REACTOS_STR_INTERNAL_NAME "sc\0"\r
#define REACTOS_STR_ORIGINAL_FILENAME "sc.exe\0"\r
#include <reactos/version.rc>\r
+\r
+//#include "En.rc"\r
/*
- * 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@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@gmail.com>
*
*/
BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
{
- SC_HANDLE hSc;
- SERVICE_STATUS_PROCESS ServiceStatus, ServiceStatus2;
- DWORD BytesNeeded;
-
-#ifdef SCDBG
- /* testing */
- _tprintf(_T("service to start - %s\n\n"), ServiceName);
- _tprintf(_T("Arguments :\n"));
- while (*ServiceArgs)
+ SC_HANDLE hSCManager = NULL;
+ SC_HANDLE hSc = NULL;
+ LPSERVICE_STATUS_PROCESS pServiceInfo = NULL;
+ DWORD BufSiz = 0;
+ DWORD BytesNeeded = 0;
+ DWORD Ret;
+
+#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 */
+
+ hSCManager = OpenSCManager(NULL,
+ NULL,
+ SC_MANAGER_CONNECT);
+ if (hSCManager == NULL)
+ goto fail;
- /* get a handle to the service requested for starting */
- hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS);
+ 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);
-
- 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;
- }
+ CloseServiceHandle(hSCManager);
+
+ return TRUE;
+
+fail:
+ ReportLastError();
+ if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo);
+ if (hSc) CloseServiceHandle(hSc);
+ if (hSCManager) CloseServiceHandle(hSCManager);
+ return FALSE;
+
}
*/
#include "sc.h"
-INT MainUsage(VOID)
+VOID MainUsage(VOID)
{
INT c;
_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")
_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")
_T(" (default = LocalSystem)\n")
_T(" DisplayName= <display name>\n")
_T(" password= <password>\n"));
-
- return 0;
}