Author: fireball
Date: Sat Sep 18 08:41:06 2010
New Revision: 48800
URL:
http://svn.reactos.org/svn/reactos?rev=48800&view=rev
Log:
[SC]
- Roel Messiant: Fix a crash when running some operations in sc without providing
arguments. Also, provide usage information for the control and unknown commands.
- Aleksey Bragin: Take Ged Murphy's comments into account and change pointer
arithmetic to a convenient style.
See issue #5611 for more details.
Modified:
trunk/reactos/base/applications/sc/create.c
trunk/reactos/base/applications/sc/sc.c
trunk/reactos/base/applications/sc/sc.h
trunk/reactos/base/applications/sc/usage.c
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 [iso-8859-1] (original)
+++ trunk/reactos/base/applications/sc/create.c [iso-8859-1] Sat Sep 18 08:41:06 2010
@@ -4,86 +4,265 @@
* FILE: base/system/sc/create.c
* PURPOSE: Create a service
* COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * Roel Messiant <roelmessiant(a)gmail.com>
*
*/
#include "sc.h"
-BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
+
+typedef struct
+{
+ LPCTSTR lpOption;
+ DWORD dwValue;
+} OPTION_INFO;
+
+typedef struct
+{
+ LPCTSTR lpServiceName;
+ LPCTSTR lpDisplayName;
+ DWORD dwServiceType;
+ DWORD dwStartType;
+ DWORD dwErrorControl;
+ LPCTSTR lpBinaryPathName;
+ LPCTSTR lpLoadOrderGroup;
+ DWORD dwTagId;
+ LPCTSTR lpDependencies;
+ LPCTSTR lpServiceStartName;
+ LPCTSTR lpPassword;
+
+ BOOL bTagId;
+} SERVICE_CREATE_INFO, *LPSERVICE_CREATE_INFO;
+
+
+static const OPTION_INFO TypeOpts[] =
+{
+ { _T("own"), SERVICE_WIN32_OWN_PROCESS },
+ { _T("share"), SERVICE_WIN32_SHARE_PROCESS },
+ { _T("interact"), SERVICE_INTERACTIVE_PROCESS },
+ { _T("kernel"), SERVICE_KERNEL_DRIVER },
+ { _T("filesys"), SERVICE_FILE_SYSTEM_DRIVER },
+ { _T("rec"), SERVICE_RECOGNIZER_DRIVER }
+};
+
+static const OPTION_INFO StartOpts[] =
+{
+ { _T("boot"), SERVICE_BOOT_START },
+ { _T("system"), SERVICE_SYSTEM_START },
+ { _T("auto"), SERVICE_AUTO_START },
+ { _T("demand"), SERVICE_DEMAND_START },
+ { _T("disabled"), SERVICE_DISABLED }
+};
+
+static const OPTION_INFO ErrorOpts[] =
+{
+ { _T("normal"), SERVICE_ERROR_NORMAL },
+ { _T("severe"), SERVICE_ERROR_SEVERE },
+ { _T("critical"), SERVICE_ERROR_CRITICAL },
+ { _T("ignore"), SERVICE_ERROR_IGNORE }
+};
+
+static const OPTION_INFO TagOpts[] =
+{
+ { _T("yes"), TRUE },
+ { _T("no"), FALSE }
+};
+
+
+static BOOL ParseCreateArguments(
+ LPCTSTR *ServiceArgs,
+ INT ArgCount,
+ OUT LPSERVICE_CREATE_INFO lpServiceInfo
+)
+{
+ INT i, ArgIndex = 1;
+
+ if (ArgCount < 1)
+ return FALSE;
+
+ ZeroMemory(lpServiceInfo, sizeof(SERVICE_CREATE_INFO));
+
+ lpServiceInfo->lpServiceName = ServiceArgs[0];
+
+ ArgCount--;
+
+ while (ArgCount > 1)
+ {
+ if (!lstrcmpi(ServiceArgs[ArgIndex], _T("type=")))
+ {
+ for (i = 0; i < sizeof(TypeOpts) / sizeof(TypeOpts[0]); i++)
+ if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TypeOpts[i].lpOption))
+ {
+ lpServiceInfo->dwServiceType |= TypeOpts[i].dwValue;
+ break;
+ }
+
+ if (i == sizeof(TypeOpts) / sizeof(TypeOpts[0]))
+ break;
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("start=")))
+ {
+ for (i = 0; i < sizeof(StartOpts) / sizeof(StartOpts[0]); i++)
+ if (!lstrcmpi(ServiceArgs[ArgIndex + 1], StartOpts[i].lpOption))
+ {
+ lpServiceInfo->dwStartType = StartOpts[i].dwValue;
+ break;
+ }
+
+ if (i == sizeof(StartOpts) / sizeof(StartOpts[0]))
+ break;
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("error=")))
+ {
+ for (i = 0; i < sizeof(ErrorOpts) / sizeof(ErrorOpts[0]); i++)
+ if (!lstrcmpi(ServiceArgs[ArgIndex + 1], ErrorOpts[i].lpOption))
+ {
+ lpServiceInfo->dwErrorControl = ErrorOpts[i].dwValue;
+ break;
+ }
+
+ if (i == sizeof(ErrorOpts) / sizeof(ErrorOpts[0]))
+ break;
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("tag=")))
+ {
+ for (i = 0; i < sizeof(TagOpts) / sizeof(TagOpts[0]); i++)
+ if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TagOpts[i].lpOption))
+ {
+ lpServiceInfo->bTagId = TagOpts[i].dwValue;
+ break;
+ }
+
+ if (i == sizeof(TagOpts) / sizeof(TagOpts[0]))
+ break;
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("binpath=")))
+ {
+ lpServiceInfo->lpBinaryPathName = ServiceArgs[ArgIndex + 1];
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("group=")))
+ {
+ lpServiceInfo->lpLoadOrderGroup = ServiceArgs[ArgIndex + 1];
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("depend=")))
+ {
+ lpServiceInfo->lpDependencies = ServiceArgs[ArgIndex + 1];
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("obj=")))
+ {
+ lpServiceInfo->lpServiceStartName = ServiceArgs[ArgIndex + 1];
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("displayname=")))
+ {
+ lpServiceInfo->lpDisplayName = ServiceArgs[ArgIndex + 1];
+ }
+ else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("password=")))
+ {
+ lpServiceInfo->lpPassword = ServiceArgs[ArgIndex + 1];
+ }
+
+ ArgIndex += 2;
+ ArgCount -= 2;
+ }
+
+ return (ArgCount == 0);
+}
+
+BOOL Create(LPCTSTR *ServiceArgs, INT ArgCount)
{
SC_HANDLE hSCManager;
SC_HANDLE hSc;
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;
- DWORD dwTagId = 0;
- 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"), dwTagId);
- _tprintf(_T("dependincies - %s\n"), lpDependencies);
- _tprintf(_T("account start name - %s\n"), lpServiceStartName);
- _tprintf(_T("account password - %s\n"), lpPassword);
-#endif
-
- if (!ServiceName)
+ INT i;
+ INT Length;
+ LPTSTR lpBuffer = NULL;
+ SERVICE_CREATE_INFO ServiceInfo;
+
+ if (!ParseCreateArguments(ServiceArgs, ArgCount, &ServiceInfo))
{
CreateUsage();
return FALSE;
}
- hSCManager = OpenSCManager(NULL,
- NULL,
- SC_MANAGER_CREATE_SERVICE);
- if (hSCManager == NULL)
- {
+ if (!ServiceInfo.dwServiceType)
+ ServiceInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+
+ if (!ServiceInfo.dwStartType)
+ ServiceInfo.dwStartType = SERVICE_DEMAND_START;
+
+ if (!ServiceInfo.dwErrorControl)
+ ServiceInfo.dwErrorControl = SERVICE_ERROR_NORMAL;
+
+ if (ServiceInfo.lpDependencies)
+ {
+ Length = lstrlen(ServiceInfo.lpDependencies);
+
+ lpBuffer = HeapAlloc(GetProcessHeap(),
+ 0,
+ (Length + 2) * sizeof(TCHAR));
+
+ for (i = 0; i < Length; i++)
+ if (ServiceInfo.lpDependencies[i] == _T('/'))
+ lpBuffer[i] = 0;
+ else
+ lpBuffer[i] = ServiceInfo.lpDependencies[i];
+
+ lpBuffer[Length] = 0;
+ lpBuffer[Length + 1] = 0;
+
+ ServiceInfo.lpDependencies = lpBuffer;
+ }
+
+#ifdef SCDBG
+ _tprintf(_T("service name - %s\n"), ServiceInfo.lpServiceName);
+ _tprintf(_T("display name - %s\n"), ServiceInfo.lpDisplayName);
+ _tprintf(_T("service type - %lu\n"), ServiceInfo.dwServiceType);
+ _tprintf(_T("start type - %lu\n"), ServiceInfo.dwStartType);
+ _tprintf(_T("error control - %lu\n"), ServiceInfo.dwErrorControl);
+ _tprintf(_T("Binary path - %s\n"), ServiceInfo.lpBinaryPathName);
+ _tprintf(_T("load order group - %s\n"), ServiceInfo.lpLoadOrderGroup);
+ _tprintf(_T("tag - %lu\n"), ServiceInfo.dwTagId);
+ _tprintf(_T("dependencies - %s\n"), ServiceInfo.lpDependencies);
+ _tprintf(_T("account start name - %s\n"), ServiceInfo.lpServiceStartName);
+ _tprintf(_T("account password - %s\n"), ServiceInfo.lpPassword);
+#endif
+
+ hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+
+ if (hSCManager != NULL)
+ {
+ hSc = CreateService(hSCManager,
+ ServiceInfo.lpServiceName,
+ ServiceInfo.lpDisplayName,
+ SERVICE_ALL_ACCESS,
+ ServiceInfo.dwServiceType,
+ ServiceInfo.dwStartType,
+ ServiceInfo.dwErrorControl,
+ ServiceInfo.lpBinaryPathName,
+ ServiceInfo.lpLoadOrderGroup,
+ ServiceInfo.bTagId ? &ServiceInfo.dwTagId : NULL,
+ ServiceInfo.lpDependencies,
+ ServiceInfo.lpServiceStartName,
+ ServiceInfo.lpPassword);
+
+ if (hSc != NULL)
+ {
+ _tprintf(_T("[SC] CreateService SUCCESS\n"));
+
+ CloseServiceHandle(hSc);
+ bRet = TRUE;
+ }
+ else
+ ReportLastError();
+
+ CloseServiceHandle(hSCManager);
+ }
+ else
ReportLastError();
- return FALSE;
- }
-
- hSc = CreateService(hSCManager,
- ServiceName,
- ServiceName,
- SERVICE_ALL_ACCESS,
- dwServiceType,
- dwStartType,
- dwErrorControl,
- lpBinaryPathName,
- lpLoadOrderGroup,
- &dwTagId,
- lpDependencies,
- lpServiceStartName,
- lpPassword);
-
- if (hSc == NULL)
- {
- ReportLastError();
- CloseServiceHandle(hSCManager);
- }
- else
- {
- _tprintf(_T("[SC] CreateService SUCCESS\n"));
-
- CloseServiceHandle(hSc);
- CloseServiceHandle(hSCManager);
- bRet = TRUE;
- }
+
+ if (lpBuffer != NULL)
+ HeapFree(GetProcessHeap(), 0, lpBuffer);
return bRet;
}
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 [iso-8859-1] (original)
+++ trunk/reactos/base/applications/sc/sc.c [iso-8859-1] Sat Sep 18 08:41:06 2010
@@ -67,11 +67,11 @@
}
else if (!lstrcmpi(Command, _T("start")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Start(ServiceName,
ServiceArgs,
ArgCount);
@@ -81,11 +81,11 @@
}
else if (!lstrcmpi(Command, _T("pause")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Control(SERVICE_CONTROL_PAUSE,
ServiceName,
ServiceArgs,
@@ -96,11 +96,11 @@
}
else if (!lstrcmpi(Command, _T("interrogate")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Control(SERVICE_CONTROL_INTERROGATE,
ServiceName,
ServiceArgs,
@@ -111,11 +111,11 @@
}
else if (!lstrcmpi(Command, _T("stop")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Control(SERVICE_CONTROL_STOP,
ServiceName,
ServiceArgs,
@@ -126,11 +126,11 @@
}
else if (!lstrcmpi(Command, _T("continue")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Control(SERVICE_CONTROL_CONTINUE,
ServiceName,
ServiceArgs,
@@ -141,51 +141,49 @@
}
else if (!lstrcmpi(Command, _T("delete")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
+ if (ArgCount > 0)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
Delete(ServiceName);
+ }
else
DeleteUsage();
}
else if (!lstrcmpi(Command, _T("create")))
{
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- if (*ServiceArgs)
- Create(ServiceName,
- ServiceArgs);
- else
- CreateUsage();
+ Create(ServiceArgs, ArgCount);
}
else if (!lstrcmpi(Command, _T("control")))
{
INT CtlValue;
- ServiceName = *ServiceArgs++;
- ArgCount--;
-
- CtlValue = _ttoi(ServiceArgs[0]);
- ServiceArgs++;
- ArgCount--;
-
- if (ServiceName)
- {
- if ((CtlValue >=128) && CtlValue <= 255)
- {
+ if (ArgCount > 1)
+ {
+ ServiceName = *ServiceArgs++;
+ ArgCount--;
+
+ CtlValue = _ttoi(ServiceArgs[0]);
+ ServiceArgs++;
+ ArgCount--;
+
+ if ((CtlValue >= 128) && (CtlValue <= 255))
Control(CtlValue,
ServiceName,
ServiceArgs,
ArgCount);
-
- return 0;
- }
- }
-
- ContinueUsage();
- }
+ else
+ ControlUsage();
+ }
+ else
+ ControlUsage();
+ }
+ else
+ {
+ MainUsage();
+ }
+
return 0;
}
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 [iso-8859-1] (original)
+++ trunk/reactos/base/applications/sc/sc.h [iso-8859-1] Sat Sep 18 08:41:06 2010
@@ -7,7 +7,7 @@
/* control functions */
BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount);
-BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs);
+BOOL Create(LPCTSTR *ServiceArgs, INT ArgCount);
BOOL Delete(LPCTSTR ServiceName);
BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount);
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended);
@@ -29,3 +29,4 @@
VOID DescriptionUsage(VOID);
VOID DeleteUsage(VOID);
VOID CreateUsage(VOID);
+VOID ControlUsage(VOID);
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 [iso-8859-1] (original)
+++ trunk/reactos/base/applications/sc/usage.c [iso-8859-1] Sat Sep 18 08:41:06 2010
@@ -118,7 +118,7 @@
VOID StopUsage(VOID)
{
_tprintf(_T("DESCRIPTION:\n")
- _T(" Sends an STOP control request to a service.\n")
+ _T(" Sends a STOP control request to a service.\n")
_T("USAGE:\n")
_T(" sc <server> stop [service name]\n"));
}
@@ -126,7 +126,7 @@
VOID ContinueUsage(VOID)
{
_tprintf(_T("DESCRIPTION:\n")
- _T(" Sends an CONTINUE control request to a
service.\n")
+ _T(" Sends a CONTINUE control request to a service.\n")
_T("USAGE:\n")
_T(" sc <server> continue [service name]\n"));
}
@@ -179,3 +179,11 @@
_T(" DisplayName= <display name>\n")
_T(" password= <password>\n"));
}
+
+VOID ControlUsage(VOID)
+{
+ _tprintf(_T("DESCRIPTION:\n")
+ _T(" Sends a CONTROL control request to a service.\n")
+ _T("USAGE:\n")
+ _T(" sc <server> control [service name]
<value>\n"));
+}