📄 scm.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/advapi32/service/scm.c
* PURPOSE: Service control manager functions
* PROGRAMMER: Emanuele Aliberti
* Eric Kohl
* UPDATE HISTORY:
* 19990413 EA created
* 19990515 EA
*/
/* INCLUDES ******************************************************************/
#include <advapi32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
handle_t BindingHandle = NULL;
static VOID
HandleBind(VOID)
{
LPWSTR pszStringBinding;
RPC_STATUS status;
if (BindingHandle != NULL)
return;
status = RpcStringBindingComposeW(NULL,
L"ncacn_np",
NULL,
L"\\pipe\\ntsvcs",
NULL,
&pszStringBinding);
if (status)
{
DPRINT1("RpcStringBindingCompose returned 0x%x\n", status);
return;
}
/* Set the binding handle that will be used to bind to the server. */
status = RpcBindingFromStringBindingW(pszStringBinding,
&BindingHandle);
if (status)
{
DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status);
}
status = RpcStringFreeW(&pszStringBinding);
if (status)
{
DPRINT1("RpcStringFree returned 0x%x\n", status);
}
}
#if 0
static VOID
HandleUnbind(VOID)
{
RPC_STATUS status;
if (BindingHandle == NULL)
return;
status = RpcBindingFree(&BindingHandle);
if (status)
{
DPRINT1("RpcBindingFree returned 0x%x\n", status);
}
}
#endif
/**********************************************************************
* ChangeServiceConfig2A
*
* @implemented
*/
BOOL WINAPI
ChangeServiceConfig2A(SC_HANDLE hService,
DWORD dwInfoLevel,
LPVOID lpInfo)
{
DWORD lpInfoSize;
DWORD dwError;
DPRINT("ChangeServiceConfig2A() called\n");
/* Determine the length of the lpInfo parameter */
switch (dwInfoLevel)
{
case SERVICE_CONFIG_DESCRIPTION:
lpInfoSize = sizeof(SERVICE_DESCRIPTIONA);
break;
case SERVICE_CONFIG_FAILURE_ACTIONS:
lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSA);
break;
default:
DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (lpInfo == NULL)
return TRUE;
HandleBind();
dwError = ScmrChangeServiceConfig2A(BindingHandle,
(unsigned int)hService,
dwInfoLevel,
lpInfo,
lpInfoSize);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrChangeServiceConfig2A() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
return TRUE;
}
/**********************************************************************
* ChangeServiceConfig2W
*
* @implemented
*/
BOOL WINAPI
ChangeServiceConfig2W(SC_HANDLE hService,
DWORD dwInfoLevel,
LPVOID lpInfo)
{
DWORD lpInfoSize;
DWORD dwError;
DPRINT("ChangeServiceConfig2W() called\n");
/* Determine the length of the lpInfo parameter */
switch (dwInfoLevel)
{
case SERVICE_CONFIG_DESCRIPTION:
lpInfoSize = sizeof(SERVICE_DESCRIPTIONW);
break;
case SERVICE_CONFIG_FAILURE_ACTIONS:
lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSW);
break;
default:
DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (lpInfo == NULL)
return TRUE;
HandleBind();
dwError = ScmrChangeServiceConfig2W(BindingHandle,
(unsigned int)hService,
dwInfoLevel,
lpInfo,
lpInfoSize);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
return TRUE;
}
/**********************************************************************
* ChangeServiceConfigA
*
* @implemented
*/
BOOL STDCALL
ChangeServiceConfigA(SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCSTR lpBinaryPathName,
LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCSTR lpDependencies,
LPCSTR lpServiceStartName,
LPCSTR lpPassword,
LPCSTR lpDisplayName)
{
DWORD dwError;
DWORD dwDependenciesLength = 0;
DWORD dwLength;
LPSTR lpStr;
DPRINT("ChangeServiceConfigA() called\n");
/* Calculate the Dependencies length*/
if (lpDependencies != NULL)
{
lpStr = (LPSTR)lpDependencies;
while (*lpStr)
{
dwLength = strlen(lpStr) + 1;
dwDependenciesLength += dwLength;
lpStr = lpStr + dwLength;
}
dwDependenciesLength++;
}
/* FIXME: Encrypt the password */
HandleBind();
/* Call to services.exe using RPC */
dwError = ScmrChangeServiceConfigA(BindingHandle,
(unsigned int)hService,
dwServiceType,
dwStartType,
dwErrorControl,
(LPSTR)lpBinaryPathName,
(LPSTR)lpLoadOrderGroup,
lpdwTagId,
(LPSTR)lpDependencies,
dwDependenciesLength,
(LPSTR)lpServiceStartName,
NULL, /* FIXME: lpPassword */
0, /* FIXME: dwPasswordLength */
(LPSTR)lpDisplayName);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
return TRUE;
}
/**********************************************************************
* ChangeServiceConfigW
*
* @implemented
*/
BOOL STDCALL
ChangeServiceConfigW(SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCWSTR lpBinaryPathName,
LPCWSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCWSTR lpDependencies,
LPCWSTR lpServiceStartName,
LPCWSTR lpPassword,
LPCWSTR lpDisplayName)
{
DWORD dwError;
DWORD dwDependenciesLength = 0;
DWORD dwLength;
LPWSTR lpStr;
DPRINT("ChangeServiceConfigW() called\n");
/* Calculate the Dependencies length*/
if (lpDependencies != NULL)
{
lpStr = (LPWSTR)lpDependencies;
while (*lpStr)
{
dwLength = wcslen(lpStr) + 1;
dwDependenciesLength += dwLength;
lpStr = lpStr + dwLength;
}
dwDependenciesLength++;
}
/* FIXME: Encrypt the password */
HandleBind();
/* Call to services.exe using RPC */
dwError = ScmrChangeServiceConfigW(BindingHandle,
(unsigned int)hService,
dwServiceType,
dwStartType,
dwErrorControl,
(LPWSTR)lpBinaryPathName,
(LPWSTR)lpLoadOrderGroup,
lpdwTagId,
(LPWSTR)lpDependencies,
dwDependenciesLength,
(LPWSTR)lpServiceStartName,
NULL, /* FIXME: lpPassword */
0, /* FIXME: dwPasswordLength */
(LPWSTR)lpDisplayName);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
return TRUE;
}
/**********************************************************************
* CloseServiceHandle
*
* @implemented
*/
BOOL STDCALL
CloseServiceHandle(SC_HANDLE hSCObject)
{
DWORD dwError;
DPRINT("CloseServiceHandle() called\n");
HandleBind();
/* Call to services.exe using RPC */
dwError = ScmrCloseServiceHandle(BindingHandle,
(unsigned int)hSCObject);
if (dwError)
{
DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
DPRINT("CloseServiceHandle() done\n");
return TRUE;
}
/**********************************************************************
* ControlService
*
* @implemented
*/
BOOL STDCALL
ControlService(SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus)
{
DWORD dwError;
DPRINT("ControlService(%x, %x, %p)\n",
hService, dwControl, lpServiceStatus);
HandleBind();
/* Call to services.exe using RPC */
dwError = ScmrControlService(BindingHandle,
(unsigned int)hService,
dwControl,
lpServiceStatus);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
DPRINT("ControlService() done\n");
return TRUE;
}
/**********************************************************************
* ControlServiceEx
*
* @unimplemented
*/
BOOL STDCALL
ControlServiceEx(IN SC_HANDLE hService,
IN DWORD dwControl,
IN DWORD dwInfoLevel,
IN OUT PVOID pControlParams)
{
DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
hService, dwControl, dwInfoLevel, pControlParams);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/**********************************************************************
* CreateServiceA
*
* @implemented
*/
SC_HANDLE STDCALL
CreateServiceA(SC_HANDLE hSCManager,
LPCSTR lpServiceName,
LPCSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCSTR lpBinaryPathName,
LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCSTR lpDependencies,
LPCSTR lpServiceStartName,
LPCSTR lpPassword)
{
SC_HANDLE RetVal = NULL;
LPWSTR lpServiceNameW = NULL;
LPWSTR lpDisplayNameW = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -