[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:
Eric Kohl 2012-07-15 18:27:29 +00:00
parent cfc235a34b
commit c27b9de07c
3 changed files with 67 additions and 72 deletions

View file

@ -1116,8 +1116,8 @@ ScmSendStartCommand(PSERVICE Service,
DPRINT("ScmSendStartCommand() called\n");
/* Calculate the total length of the start command line */
PacketSize = sizeof(SCM_CONTROL_PACKET);
PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
PacketSize = sizeof(SCM_CONTROL_PACKET) +
(wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
/* Calculate the required packet size for the start arguments */
if (argc > 0 && argv != NULL)
@ -1140,7 +1140,9 @@ ScmSendStartCommand(PSERVICE Service,
return ERROR_NOT_ENOUGH_MEMORY;
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->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);

View file

@ -47,6 +47,7 @@ typedef struct _ACTIVE_SERVICE
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext;
BOOL bUnicode;
BOOL bOwnProcess;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
@ -142,6 +143,9 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName);
if (lpActiveServices[0].bOwnProcess)
return &lpActiveServices[0];
for (i = 0; i < dwActiveServiceCount; i++)
{
TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
@ -488,10 +492,9 @@ ScControlService(PACTIVE_SERVICE lpService,
static BOOL
ScServiceDispatcher(HANDLE hPipe,
PUCHAR lpBuffer,
PSCM_CONTROL_PACKET ControlPacket,
DWORD dwBufferSize)
{
PSCM_CONTROL_PACKET ControlPacket;
DWORD Count;
BOOL bResult;
DWORD dwRunningServices = 0;
@ -502,18 +505,12 @@ ScServiceDispatcher(HANDLE hPipe,
TRACE("ScDispatcherLoop() called\n");
ControlPacket = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
1024);
if (ControlPacket == NULL)
return FALSE;
while (TRUE)
{
/* Read command from the control pipe */
bResult = ReadFile(hPipe,
ControlPacket,
1024,
dwBufferSize,
&Count,
NULL);
if (bResult == FALSE)
@ -525,13 +522,17 @@ ScServiceDispatcher(HANDLE hPipe,
lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
TRACE("Service: %S\n", lpServiceName);
if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
lpActiveServices[0].bOwnProcess = TRUE;
lpService = ScLookupServiceByServiceName(lpServiceName);
if (lpService != NULL)
{
/* Execute command */
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");
dwError = ScStartService(lpService, ControlPacket);
if (dwError == ERROR_SUCCESS)
@ -832,12 +833,14 @@ SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
* @implemented
*/
BOOL WINAPI
StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
{
ULONG i;
HANDLE hPipe;
DWORD dwError;
PUCHAR lpMessageBuffer;
PSCM_CONTROL_PACKET ControlPacket;
DWORD dwBufSize;
BOOL bRet = TRUE;
TRACE("StartServiceCtrlDispatcherA() called\n");
@ -864,50 +867,40 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = FALSE;
lpActiveServices[i].bOwnProcess = FALSE;
}
dwError = ScConnectControlPipe(&hPipe);
if (dwError != ERROR_SUCCESS)
{
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return FALSE;
bRet = FALSE;
goto done;
}
lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
256);
if (lpMessageBuffer == NULL)
dwBufSize = sizeof(SCM_CONTROL_PACKET) +
(MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
dwBufSize);
if (ControlPacket == NULL)
{
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
CloseHandle(hPipe);
return FALSE;
bRet = FALSE;
goto done;
}
ScCreateStatusBinding();
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
ScDestroyStatusBinding();
CloseHandle(hPipe);
/* Free the message buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
/* Free the control packet */
RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
done:
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
@ -917,7 +910,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return TRUE;
return bRet;
}
@ -927,12 +920,14 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
* @implemented
*/
BOOL WINAPI
StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
{
ULONG i;
HANDLE hPipe;
DWORD dwError;
PUCHAR lpMessageBuffer;
PSCM_CONTROL_PACKET ControlPacket;
DWORD dwBufSize;
BOOL bRet = TRUE;
TRACE("StartServiceCtrlDispatcherW() called\n");
@ -959,50 +954,40 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = TRUE;
lpActiveServices[i].bOwnProcess = FALSE;
}
dwError = ScConnectControlPipe(&hPipe);
if (dwError != ERROR_SUCCESS)
{
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return FALSE;
bRet = FALSE;
goto done;
}
lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
256);
if (lpMessageBuffer == NULL)
dwBufSize = sizeof(SCM_CONTROL_PACKET) +
(MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
dwBufSize);
if (ControlPacket == NULL)
{
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
CloseHandle(hPipe);
return FALSE;
bRet = FALSE;
goto done;
}
ScCreateStatusBinding();
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
ScDestroyStatusBinding();
CloseHandle(hPipe);
/* Free the message buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
/* Free the control packet */
RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
done:
/* Free the service table */
for (i = 0; i < dwActiveServiceCount; i++)
{
@ -1012,7 +997,7 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return TRUE;
return bRet;
}
/* EOF */

View file

@ -9,7 +9,15 @@
#ifndef __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
{