LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext;
BOOL bUnicode;
+ BOOL bOwnProcess;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
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);
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
lpService->ThreadParams.W.lpArgVector);
- if (lpService->ThreadParams.A.lpArgVector != NULL)
+ if (lpService->ThreadParams.W.lpArgVector != NULL)
{
HeapFree(GetProcessHeap(),
0,
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
- if (!WaitNamedPipeW(NtControlPipeName, 15000))
+ if (!WaitNamedPipeW(NtControlPipeName, 30000))
{
ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
*hPipe = CreateFileW(NtControlPipeName,
GENERIC_READ | GENERIC_WRITE,
- 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
{
LPWSTR *lpVector;
LPWSTR *lpArg;
+ LPWSTR pszServiceName;
+ DWORD cbServiceName;
+ DWORD cbTotal;
DWORD i;
+ if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
+ return ERROR_INVALID_PARAMETER;
+
*lpArgCount = 0;
*lpArgVector = NULL;
+ pszServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+ cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+ cbTotal = cbServiceName + sizeof(LPWSTR);
if (ControlPacket->dwArgumentsCount > 0)
- {
- lpVector = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
- if (lpVector == NULL)
- return ERROR_OUTOFMEMORY;
+ cbTotal += ControlPacket->dwSize - ControlPacket->dwArgumentsOffset;
+
+ lpVector = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ cbTotal);
+ if (lpVector == NULL)
+ return ERROR_OUTOFMEMORY;
+
+ lpArg = lpVector;
+ *lpArg = (LPWSTR)(lpArg + 1);
+ lpArg++;
- memcpy(lpVector,
+ memcpy(lpArg, pszServiceName, cbServiceName);
+ lpArg = (LPWSTR*)((ULONG_PTR)lpArg + cbServiceName);
+
+ if (ControlPacket->dwArgumentsCount > 0)
+ {
+ memcpy(lpArg,
((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset),
ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
- lpArg = lpVector;
for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
{
*lpArg = (LPWSTR)((ULONG_PTR)lpArg + (ULONG_PTR)*lpArg);
lpArg++;
}
-
- *lpArgCount = ControlPacket->dwArgumentsCount;
- *lpArgVector = lpVector;
}
+ *lpArgCount = ControlPacket->dwArgumentsCount + 1;
+ *lpArgVector = lpVector;
+
return ERROR_SUCCESS;
}
LPSTR *lpVector;
LPSTR *lpPtr;
LPWSTR lpUnicodeString;
+ LPWSTR pszServiceName;
LPSTR lpAnsiString;
+ DWORD cbServiceName;
DWORD dwVectorSize;
DWORD dwUnicodeSize;
- DWORD dwAnsiSize;
+ DWORD dwAnsiSize = 0;
+ DWORD dwAnsiNameSize = 0;
DWORD i;
+ if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
+ return ERROR_INVALID_PARAMETER;
+
*lpArgCount = 0;
*lpArgVector = NULL;
+ pszServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+ cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+ dwAnsiNameSize = WideCharToMultiByte(CP_ACP,
+ 0,
+ pszServiceName,
+ cbServiceName,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+
+ dwVectorSize = ControlPacket->dwArgumentsCount * sizeof(LPWSTR);
if (ControlPacket->dwArgumentsCount > 0)
{
- dwVectorSize = ControlPacket->dwArgumentsCount * sizeof(LPWSTR);
-
lpUnicodeString = (LPWSTR)((PBYTE)ControlPacket +
ControlPacket->dwArgumentsOffset +
dwVectorSize);
0,
NULL,
NULL);
+ }
+
+ dwVectorSize += sizeof(LPWSTR);
- lpVector = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- dwVectorSize + dwAnsiSize);
- if (lpVector == NULL)
- return ERROR_OUTOFMEMORY;
+ lpVector = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ dwVectorSize + dwAnsiNameSize + dwAnsiSize);
+ if (lpVector == NULL)
+ return ERROR_OUTOFMEMORY;
- lpPtr = (LPSTR*)lpVector;
- lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
+ lpPtr = (LPSTR*)lpVector;
+ lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
+
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ pszServiceName,
+ cbServiceName,
+ lpAnsiString,
+ dwAnsiNameSize,
+ NULL,
+ NULL);
+
+ if (ControlPacket->dwArgumentsCount > 0)
+ {
+ lpAnsiString = (LPSTR)((ULONG_PTR)lpAnsiString + dwAnsiNameSize);
WideCharToMultiByte(CP_ACP,
0,
dwAnsiSize,
NULL,
NULL);
+ }
- for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
- {
- *lpPtr = lpAnsiString;
-
- lpPtr++;
- lpAnsiString += (strlen(lpAnsiString) + 1);
- }
+ lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
+ for (i = 0; i < ControlPacket->dwArgumentsCount + 1; i++)
+ {
+ *lpPtr = lpAnsiString;
- *lpArgCount = ControlPacket->dwArgumentsCount;
- *lpArgVector = lpVector;
+ lpPtr++;
+ lpAnsiString += (strlen(lpAnsiString) + 1);
}
+ *lpArgCount = ControlPacket->dwArgumentsCount + 1;
+ *lpArgVector = lpVector;
+
return ERROR_SUCCESS;
}
DWORD ThreadId;
DWORD dwError;
+ if (lpService == NULL || ControlPacket == NULL)
+ return ERROR_INVALID_PARAMETER;
+
TRACE("ScStartService() called\n");
TRACE("Size: %lu\n", ControlPacket->dwSize);
TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
ScControlService(PACTIVE_SERVICE lpService,
PSCM_CONTROL_PACKET ControlPacket)
{
+ if (lpService == NULL || ControlPacket == NULL)
+ return ERROR_INVALID_PARAMETER;
+
TRACE("ScControlService() called\n");
TRACE("Size: %lu\n", ControlPacket->dwSize);
TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
static BOOL
ScServiceDispatcher(HANDLE hPipe,
- PUCHAR lpBuffer,
+ PSCM_CONTROL_PACKET ControlPacket,
DWORD dwBufferSize)
{
- PSCM_CONTROL_PACKET ControlPacket;
DWORD Count;
BOOL bResult;
DWORD dwRunningServices = 0;
TRACE("ScDispatcherLoop() called\n");
- ControlPacket = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- 1024);
- if (ControlPacket == NULL)
+ if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
return FALSE;
while (TRUE)
/* Read command from the control pipe */
bResult = ReadFile(hPipe,
ControlPacket,
- 1024,
+ dwBufferSize,
&Count,
NULL);
if (bResult == FALSE)
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:
- TRACE("Start command - recieved SERVICE_CONTROL_START\n");
+ case SERVICE_CONTROL_START_SHARE:
+ case SERVICE_CONTROL_START_OWN:
+ TRACE("Start command - received SERVICE_CONTROL_START\n");
dwError = ScStartService(lpService, ControlPacket);
if (dwError == ERROR_SUCCESS)
dwRunningServices++;
break;
case SERVICE_CONTROL_STOP:
- TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
+ TRACE("Stop command - received SERVICE_CONTROL_STOP\n");
dwError = ScControlService(lpService, ControlPacket);
if (dwError == ERROR_SUCCESS)
dwRunningServices--;
break;
}
- HeapFree(GetProcessHeap(),
- 0,
- ControlPacket);
-
return TRUE;
}
* @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");
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++)
{
lpActiveServices = NULL;
dwActiveServiceCount = 0;
- return TRUE;
+ return bRet;
}
* @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");
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++)
{
lpActiveServices = NULL;
dwActiveServiceCount = 0;
- return TRUE;
+ return bRet;
}
/* EOF */