mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[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. svn path=/trunk/; revision=48800
This commit is contained in:
parent
2c10fb5d07
commit
becc9ed282
4 changed files with 290 additions and 104 deletions
|
@ -4,86 +4,265 @@
|
|||
* FILE: base/system/sc/create.c
|
||||
* PURPOSE: Create a service
|
||||
* COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
|
||||
* Roel Messiant <roelmessiant@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;
|
||||
INT i;
|
||||
INT Length;
|
||||
LPTSTR lpBuffer = NULL;
|
||||
SERVICE_CREATE_INFO ServiceInfo;
|
||||
|
||||
/* 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)
|
||||
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)
|
||||
{
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
hSc = CreateService(hSCManager,
|
||||
ServiceName,
|
||||
ServiceName,
|
||||
SERVICE_ALL_ACCESS,
|
||||
dwServiceType,
|
||||
dwStartType,
|
||||
dwErrorControl,
|
||||
lpBinaryPathName,
|
||||
lpLoadOrderGroup,
|
||||
&dwTagId,
|
||||
lpDependencies,
|
||||
lpServiceStartName,
|
||||
lpPassword);
|
||||
#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
|
||||
|
||||
if (hSc == NULL)
|
||||
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
if (hSCManager != NULL)
|
||||
{
|
||||
ReportLastError();
|
||||
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
|
||||
{
|
||||
_tprintf(_T("[SC] CreateService SUCCESS\n"));
|
||||
ReportLastError();
|
||||
|
||||
CloseServiceHandle(hSc);
|
||||
CloseServiceHandle(hSCManager);
|
||||
bRet = TRUE;
|
||||
}
|
||||
if (lpBuffer != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpBuffer);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
|
|
@ -67,11 +67,11 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
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 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
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 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
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 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
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 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
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 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("delete")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
if (ArgCount > 0)
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
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 (ArgCount > 1)
|
||||
{
|
||||
if ((CtlValue >=128) && CtlValue <= 255)
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
CtlValue = _ttoi(ServiceArgs[0]);
|
||||
ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if ((CtlValue >= 128) && (CtlValue <= 255))
|
||||
Control(CtlValue,
|
||||
ServiceName,
|
||||
ServiceArgs,
|
||||
ArgCount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
ControlUsage();
|
||||
}
|
||||
|
||||
ContinueUsage();
|
||||
else
|
||||
ControlUsage();
|
||||
}
|
||||
else
|
||||
{
|
||||
MainUsage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ConfigUsage(VOID);
|
|||
VOID DescriptionUsage(VOID);
|
||||
VOID DeleteUsage(VOID);
|
||||
VOID CreateUsage(VOID);
|
||||
VOID ControlUsage(VOID);
|
||||
|
|
|
@ -118,7 +118,7 @@ VOID InterrogateUsage(VOID)
|
|||
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 StopUsage(VOID)
|
|||
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 @@ VOID CreateUsage(VOID)
|
|||
_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"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue