mirror of
https://github.com/reactos/reactos.git
synced 2024-07-14 00:25:05 +00:00
[SERVICES]
Implement check for SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS type. Patch by Hermes Belusca. See issue #7179 for more details. svn path=/trunk/; revision=56900
This commit is contained in:
parent
cfc235a34b
commit
c27b9de07c
|
@ -1116,8 +1116,8 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
DPRINT("ScmSendStartCommand() called\n");
|
DPRINT("ScmSendStartCommand() called\n");
|
||||||
|
|
||||||
/* Calculate the total length of the start command line */
|
/* Calculate the total length of the start command line */
|
||||||
PacketSize = sizeof(SCM_CONTROL_PACKET);
|
PacketSize = sizeof(SCM_CONTROL_PACKET) +
|
||||||
PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
|
(wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
/* Calculate the required packet size for the start arguments */
|
/* Calculate the required packet size for the start arguments */
|
||||||
if (argc > 0 && argv != NULL)
|
if (argc > 0 && argv != NULL)
|
||||||
|
@ -1140,7 +1140,9 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
ControlPacket->dwSize = PacketSize;
|
ControlPacket->dwSize = PacketSize;
|
||||||
ControlPacket->dwControl = SERVICE_CONTROL_START;
|
ControlPacket->dwControl = (Service->Status.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
|
||||||
|
? SERVICE_CONTROL_START_OWN
|
||||||
|
: SERVICE_CONTROL_START_SHARE;
|
||||||
ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
|
ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
|
||||||
ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
|
ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct _ACTIVE_SERVICE
|
||||||
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
|
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
|
||||||
LPVOID HandlerContext;
|
LPVOID HandlerContext;
|
||||||
BOOL bUnicode;
|
BOOL bUnicode;
|
||||||
|
BOOL bOwnProcess;
|
||||||
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
|
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,6 +143,9 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
|
||||||
|
|
||||||
TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName);
|
TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName);
|
||||||
|
|
||||||
|
if (lpActiveServices[0].bOwnProcess)
|
||||||
|
return &lpActiveServices[0];
|
||||||
|
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
for (i = 0; i < dwActiveServiceCount; i++)
|
||||||
{
|
{
|
||||||
TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
|
TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
|
||||||
|
@ -488,10 +492,9 @@ ScControlService(PACTIVE_SERVICE lpService,
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
ScServiceDispatcher(HANDLE hPipe,
|
ScServiceDispatcher(HANDLE hPipe,
|
||||||
PUCHAR lpBuffer,
|
PSCM_CONTROL_PACKET ControlPacket,
|
||||||
DWORD dwBufferSize)
|
DWORD dwBufferSize)
|
||||||
{
|
{
|
||||||
PSCM_CONTROL_PACKET ControlPacket;
|
|
||||||
DWORD Count;
|
DWORD Count;
|
||||||
BOOL bResult;
|
BOOL bResult;
|
||||||
DWORD dwRunningServices = 0;
|
DWORD dwRunningServices = 0;
|
||||||
|
@ -502,18 +505,12 @@ ScServiceDispatcher(HANDLE hPipe,
|
||||||
|
|
||||||
TRACE("ScDispatcherLoop() called\n");
|
TRACE("ScDispatcherLoop() called\n");
|
||||||
|
|
||||||
ControlPacket = HeapAlloc(GetProcessHeap(),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
1024);
|
|
||||||
if (ControlPacket == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* Read command from the control pipe */
|
/* Read command from the control pipe */
|
||||||
bResult = ReadFile(hPipe,
|
bResult = ReadFile(hPipe,
|
||||||
ControlPacket,
|
ControlPacket,
|
||||||
1024,
|
dwBufferSize,
|
||||||
&Count,
|
&Count,
|
||||||
NULL);
|
NULL);
|
||||||
if (bResult == FALSE)
|
if (bResult == FALSE)
|
||||||
|
@ -525,13 +522,17 @@ ScServiceDispatcher(HANDLE hPipe,
|
||||||
lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
|
lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
|
||||||
TRACE("Service: %S\n", lpServiceName);
|
TRACE("Service: %S\n", lpServiceName);
|
||||||
|
|
||||||
|
if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
|
||||||
|
lpActiveServices[0].bOwnProcess = TRUE;
|
||||||
|
|
||||||
lpService = ScLookupServiceByServiceName(lpServiceName);
|
lpService = ScLookupServiceByServiceName(lpServiceName);
|
||||||
if (lpService != NULL)
|
if (lpService != NULL)
|
||||||
{
|
{
|
||||||
/* Execute command */
|
/* Execute command */
|
||||||
switch (ControlPacket->dwControl)
|
switch (ControlPacket->dwControl)
|
||||||
{
|
{
|
||||||
case SERVICE_CONTROL_START:
|
case SERVICE_CONTROL_START_SHARE:
|
||||||
|
case SERVICE_CONTROL_START_OWN:
|
||||||
TRACE("Start command - recieved SERVICE_CONTROL_START\n");
|
TRACE("Start command - recieved SERVICE_CONTROL_START\n");
|
||||||
dwError = ScStartService(lpService, ControlPacket);
|
dwError = ScStartService(lpService, ControlPacket);
|
||||||
if (dwError == ERROR_SUCCESS)
|
if (dwError == ERROR_SUCCESS)
|
||||||
|
@ -832,12 +833,14 @@ SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
HANDLE hPipe;
|
HANDLE hPipe;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
PUCHAR lpMessageBuffer;
|
PSCM_CONTROL_PACKET ControlPacket;
|
||||||
|
DWORD dwBufSize;
|
||||||
|
BOOL bRet = TRUE;
|
||||||
|
|
||||||
TRACE("StartServiceCtrlDispatcherA() called\n");
|
TRACE("StartServiceCtrlDispatcherA() called\n");
|
||||||
|
|
||||||
|
@ -864,50 +867,40 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
||||||
lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
||||||
lpActiveServices[i].hServiceStatus = 0;
|
lpActiveServices[i].hServiceStatus = 0;
|
||||||
lpActiveServices[i].bUnicode = FALSE;
|
lpActiveServices[i].bUnicode = FALSE;
|
||||||
|
lpActiveServices[i].bOwnProcess = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwError = ScConnectControlPipe(&hPipe);
|
dwError = ScConnectControlPipe(&hPipe);
|
||||||
if (dwError != ERROR_SUCCESS)
|
if (dwError != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Free the service table */
|
bRet = FALSE;
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
goto done;
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
|
|
||||||
}
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
|
|
||||||
lpActiveServices = NULL;
|
|
||||||
dwActiveServiceCount = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
dwBufSize = sizeof(SCM_CONTROL_PACKET) +
|
||||||
HEAP_ZERO_MEMORY,
|
(MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
|
||||||
256);
|
|
||||||
if (lpMessageBuffer == NULL)
|
ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
dwBufSize);
|
||||||
|
if (ControlPacket == NULL)
|
||||||
{
|
{
|
||||||
/* Free the service table */
|
bRet = FALSE;
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
goto done;
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
|
|
||||||
}
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
|
|
||||||
lpActiveServices = NULL;
|
|
||||||
dwActiveServiceCount = 0;
|
|
||||||
CloseHandle(hPipe);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScCreateStatusBinding();
|
ScCreateStatusBinding();
|
||||||
|
|
||||||
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
|
ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
|
||||||
|
|
||||||
ScDestroyStatusBinding();
|
ScDestroyStatusBinding();
|
||||||
|
|
||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
|
|
||||||
/* Free the message buffer */
|
/* Free the control packet */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
|
||||||
|
|
||||||
|
done:
|
||||||
/* Free the service table */
|
/* Free the service table */
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
for (i = 0; i < dwActiveServiceCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -917,7 +910,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
||||||
lpActiveServices = NULL;
|
lpActiveServices = NULL;
|
||||||
dwActiveServiceCount = 0;
|
dwActiveServiceCount = 0;
|
||||||
|
|
||||||
return TRUE;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -927,12 +920,14 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
|
StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
HANDLE hPipe;
|
HANDLE hPipe;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
PUCHAR lpMessageBuffer;
|
PSCM_CONTROL_PACKET ControlPacket;
|
||||||
|
DWORD dwBufSize;
|
||||||
|
BOOL bRet = TRUE;
|
||||||
|
|
||||||
TRACE("StartServiceCtrlDispatcherW() called\n");
|
TRACE("StartServiceCtrlDispatcherW() called\n");
|
||||||
|
|
||||||
|
@ -959,50 +954,40 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
|
||||||
lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
|
||||||
lpActiveServices[i].hServiceStatus = 0;
|
lpActiveServices[i].hServiceStatus = 0;
|
||||||
lpActiveServices[i].bUnicode = TRUE;
|
lpActiveServices[i].bUnicode = TRUE;
|
||||||
|
lpActiveServices[i].bOwnProcess = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwError = ScConnectControlPipe(&hPipe);
|
dwError = ScConnectControlPipe(&hPipe);
|
||||||
if (dwError != ERROR_SUCCESS)
|
if (dwError != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Free the service table */
|
bRet = FALSE;
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
goto done;
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
|
|
||||||
}
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
|
|
||||||
lpActiveServices = NULL;
|
|
||||||
dwActiveServiceCount = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
dwBufSize = sizeof(SCM_CONTROL_PACKET) +
|
||||||
HEAP_ZERO_MEMORY,
|
(MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
|
||||||
256);
|
|
||||||
if (lpMessageBuffer == NULL)
|
ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
dwBufSize);
|
||||||
|
if (ControlPacket == NULL)
|
||||||
{
|
{
|
||||||
/* Free the service table */
|
bRet = FALSE;
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
goto done;
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
|
|
||||||
}
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
|
|
||||||
lpActiveServices = NULL;
|
|
||||||
dwActiveServiceCount = 0;
|
|
||||||
CloseHandle(hPipe);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScCreateStatusBinding();
|
ScCreateStatusBinding();
|
||||||
|
|
||||||
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
|
ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
|
||||||
|
|
||||||
ScDestroyStatusBinding();
|
ScDestroyStatusBinding();
|
||||||
|
|
||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
|
|
||||||
/* Free the message buffer */
|
/* Free the control packet */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
|
||||||
|
|
||||||
|
done:
|
||||||
/* Free the service table */
|
/* Free the service table */
|
||||||
for (i = 0; i < dwActiveServiceCount; i++)
|
for (i = 0; i < dwActiveServiceCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -1012,7 +997,7 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
|
||||||
lpActiveServices = NULL;
|
lpActiveServices = NULL;
|
||||||
dwActiveServiceCount = 0;
|
dwActiveServiceCount = 0;
|
||||||
|
|
||||||
return TRUE;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -9,7 +9,15 @@
|
||||||
#ifndef __SERVICES_SERVICES_H__
|
#ifndef __SERVICES_SERVICES_H__
|
||||||
#define __SERVICES_SERVICES_H__
|
#define __SERVICES_SERVICES_H__
|
||||||
|
|
||||||
#define SERVICE_CONTROL_START 0
|
/*
|
||||||
|
* Internal control codes.
|
||||||
|
* Neither in the range of public control codes (1-10 and 11-14 or 16 or 32 or 64)
|
||||||
|
* nor in the range of user-defined control codes (128-255).
|
||||||
|
*/
|
||||||
|
/* Start a service that shares a process with other services */
|
||||||
|
#define SERVICE_CONTROL_START_SHARE 80
|
||||||
|
/* Start a service that runs in its own process */
|
||||||
|
#define SERVICE_CONTROL_START_OWN 81
|
||||||
|
|
||||||
typedef struct _SCM_CONTROL_PACKET
|
typedef struct _SCM_CONTROL_PACKET
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue