mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
268 lines
7.9 KiB
C
268 lines
7.9 KiB
C
/*
|
|
* 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>
|
|
* Roel Messiant <roelmessiant@gmail.com>
|
|
*
|
|
*/
|
|
|
|
#include "sc.h"
|
|
|
|
|
|
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;
|
|
|
|
INT i;
|
|
INT Length;
|
|
LPTSTR lpBuffer = NULL;
|
|
SERVICE_CREATE_INFO ServiceInfo;
|
|
|
|
if (!ParseCreateArguments(ServiceArgs, ArgCount, &ServiceInfo))
|
|
{
|
|
CreateUsage();
|
|
return FALSE;
|
|
}
|
|
|
|
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();
|
|
|
|
if (lpBuffer != NULL)
|
|
HeapFree(GetProcessHeap(), 0, lpBuffer);
|
|
|
|
return bRet;
|
|
}
|