/* INCLUDES ******************************************************************/
#include <advapi32.h>
+#include "wine/debug.h"
-#define NDEBUG
-#include <debug.h>
+WINE_DEFAULT_DEBUG_CHANNEL(advapi);
/* TYPES *********************************************************************/
-VOID HandleBind(VOID);
-
typedef struct _ACTIVE_SERVICE
{
- CLIENT_HANDLE hService;
+ SERVICE_STATUS_HANDLE hServiceStatus;
UNICODE_STRING ServiceName;
union
{
LPHANDLER_FUNCTION HandlerFunction;
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext;
- SERVICE_STATUS ServiceStatus;
BOOL bUnicode;
LPWSTR Arguments;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
/* GLOBALS *******************************************************************/
-extern handle_t BindingHandle;
static DWORD dwActiveServiceCount = 0;
static PACTIVE_SERVICE lpActiveServices = NULL;
+static handle_t hStatusBinding = NULL;
/* FUNCTIONS *****************************************************************/
+handle_t __RPC_USER
+RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
+{
+ return hStatusBinding;
+}
+
+
+void __RPC_USER
+RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus,
+ handle_t hBinding)
+{
+}
+
+
+static RPC_STATUS
+ScCreateStatusBinding(VOID)
+{
+ LPWSTR pszStringBinding;
+ RPC_STATUS status;
+
+ TRACE("ScCreateStatusBinding() called\n");
+
+ status = RpcStringBindingComposeW(NULL,
+ L"ncacn_np",
+ NULL,
+ L"\\pipe\\ntsvcs",
+ NULL,
+ &pszStringBinding);
+ if (status != RPC_S_OK)
+ {
+ ERR("RpcStringBindingCompose returned 0x%x\n", status);
+ return status;
+ }
+
+ /* Set the binding handle that will be used to bind to the server. */
+ status = RpcBindingFromStringBindingW(pszStringBinding,
+ &hStatusBinding);
+ if (status != RPC_S_OK)
+ {
+ ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
+ }
+
+ status = RpcStringFreeW(&pszStringBinding);
+ if (status != RPC_S_OK)
+ {
+ ERR("RpcStringFree returned 0x%x\n", status);
+ }
+
+ return status;
+}
+
+
+static RPC_STATUS
+ScDestroyStatusBinding(VOID)
+{
+ RPC_STATUS status;
+
+ TRACE("ScDestroyStatusBinding() called\n");
+
+ if (hStatusBinding == NULL)
+ return RPC_S_OK;
+
+ status = RpcBindingFree(&hStatusBinding);
+ if (status != RPC_S_OK)
+ {
+ ERR("RpcBindingFree returned 0x%x\n", status);
+ }
+ else
+ {
+ hStatusBinding = NULL;
+ }
+
+ return status;
+}
+
+
static PACTIVE_SERVICE
ScLookupServiceByServiceName(LPCWSTR lpServiceName)
{
lpService = (PACTIVE_SERVICE)Context;
- DPRINT("ScServiceMainStub() called\n");
+ TRACE("ScServiceMainStub() called\n");
/* Count arguments */
lpPtr = lpService->Arguments;
while (*lpPtr)
{
- DPRINT("arg: %S\n", lpPtr);
+ TRACE("arg: %S\n", lpPtr);
dwLen = wcslen(lpPtr) + 1;
dwArgCount++;
dwLength += dwLen;
lpPtr += dwLen;
}
- DPRINT("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
+ TRACE("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
/* Build the argument vector and call the main service routine */
if (lpService->bUnicode)
NTSTATUS Status;
WCHAR NtControlPipeName[MAX_PATH + 1];
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ DWORD dwProcessId;
/* Get the service number and create the named pipe */
RtlZeroMemory(&QueryTable,
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
return RtlNtStatusToDosError(Status);
}
if (!WaitNamedPipeW(NtControlPipeName, 15000))
{
- DPRINT1("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
+ ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
}
NULL);
if (*hPipe == INVALID_HANDLE_VALUE)
{
- DPRINT1("CreateFileW() failed (Error %lu)\n", GetLastError());
+ ERR("CreateFileW() failed for pipe %S (Error %lu)\n", NtControlPipeName, GetLastError());
return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
}
return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
}
- /* Share the SERVICE_HANDLE handle with the SCM */
+ /* Pass the ProcessId to the SCM */
+ dwProcessId = GetCurrentProcessId();
WriteFile(*hPipe,
- (DWORD *)&lpActiveServices->hService,
- sizeof(CLIENT_HANDLE),
+ &dwProcessId,
+ sizeof(DWORD),
&dwBytesWritten,
NULL);
- DPRINT("Sent SERVICE_HANDLE %lu\n", lpActiveServices->hService);
+ TRACE("Sent Process ID %lu\n", dwProcessId);
return ERROR_SUCCESS;
}
static DWORD
-ScStartService(PSCM_CONTROL_PACKET ControlPacket)
+ScStartService(PACTIVE_SERVICE lpService,
+ PSCM_CONTROL_PACKET ControlPacket)
{
- PACTIVE_SERVICE lpService;
HANDLE ThreadHandle;
DWORD ThreadId;
- DPRINT("ScStartService() called\n");
- DPRINT("client handle: %lu\n", ControlPacket->hClient);
- DPRINT("Size: %lu\n", ControlPacket->dwSize);
- DPRINT("Service: %S\n", &ControlPacket->szArguments[0]);
+ TRACE("ScStartService() called\n");
+ TRACE("Size: %lu\n", ControlPacket->dwSize);
+ TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
- lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
- if (lpService == NULL)
- {
- DPRINT1("Service not found\n");
- return ERROR_SERVICE_DOES_NOT_EXIST;
- }
+ /* Set the service status handle */
+ lpService->hServiceStatus = ControlPacket->hServiceStatus;
lpService->Arguments = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
- ControlPacket->dwSize * sizeof(WCHAR));
+ (ControlPacket->dwSize + 1) * sizeof(WCHAR));
if (lpService->Arguments == NULL)
return ERROR_OUTOFMEMORY;
static DWORD
-ScControlService(PSCM_CONTROL_PACKET ControlPacket)
+ScControlService(PACTIVE_SERVICE lpService,
+ PSCM_CONTROL_PACKET ControlPacket)
{
- PACTIVE_SERVICE lpService;
-
- DPRINT("ScControlService() called\n");
- DPRINT("Size: %lu\n", ControlPacket->dwSize);
- DPRINT("Service: %S\n", &ControlPacket->szArguments[0]);
-
- lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
- if (lpService == NULL)
- {
- DPRINT1("Service not found\n");
- return ERROR_SERVICE_DOES_NOT_EXIST;
- }
+ TRACE("ScControlService() called\n");
+ TRACE("Size: %lu\n", ControlPacket->dwSize);
+ TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
if (lpService->HandlerFunction)
{
lpService->Arguments);
}
- DPRINT("ScControlService() done\n");
+ TRACE("ScControlService() done\n");
return ERROR_SUCCESS;
}
DWORD Count;
BOOL bResult;
DWORD dwRunningServices = 0;
+ LPWSTR lpServiceName;
+ PACTIVE_SERVICE lpService;
+ SCM_REPLY_PACKET ReplyPacket;
+ DWORD dwError;
- DPRINT("ScDispatcherLoop() called\n");
+ TRACE("ScDispatcherLoop() called\n");
ControlPacket = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
NULL);
if (bResult == FALSE)
{
- DPRINT1("Pipe read failed (Error: %lu)\n", GetLastError());
+ ERR("Pipe read failed (Error: %lu)\n", GetLastError());
return FALSE;
}
- /* Execute command */
- switch (ControlPacket->dwControl)
+ lpServiceName = &ControlPacket->szArguments[0];
+ TRACE("Service: %S\n", lpServiceName);
+
+ lpService = ScLookupServiceByServiceName(lpServiceName);
+ if (lpService != NULL)
+ {
+ /* Execute command */
+ switch (ControlPacket->dwControl)
+ {
+ case SERVICE_CONTROL_START:
+ TRACE("Start command - recieved 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");
+ dwError = ScControlService(lpService, ControlPacket);
+ if (dwError == ERROR_SUCCESS)
+ dwRunningServices--;
+ break;
+
+ default:
+ TRACE("Command %lu received", ControlPacket->dwControl);
+ dwError = ScControlService(lpService, ControlPacket);
+ break;
+ }
+ }
+ else
+ {
+ dwError = ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ ReplyPacket.dwError = dwError;
+
+ /* Send the reply packet */
+ bResult = WriteFile(hPipe,
+ &ReplyPacket,
+ sizeof(ReplyPacket),
+ &Count,
+ NULL);
+ if (bResult == FALSE)
{
- case SERVICE_CONTROL_START:
- DPRINT("Start command - recieved SERVICE_CONTROL_START\n");
- if (ScStartService(ControlPacket) == ERROR_SUCCESS)
- dwRunningServices++;
- break;
-
- case SERVICE_CONTROL_STOP:
- DPRINT("Stop command - recieved SERVICE_CONTROL_STOP\n");
- if (ScControlService(ControlPacket) == ERROR_SUCCESS)
- dwRunningServices--;
- break;
-
- default:
- DPRINT("Unknown command %lu", ControlPacket->dwControl);
- continue;
+ ERR("Pipe write failed (Error: %lu)\n", GetLastError());
+ return FALSE;
}
if (dwRunningServices == 0)
*
* @implemented
*/
-SERVICE_STATUS_HANDLE STDCALL
+SERVICE_STATUS_HANDLE WINAPI
RegisterServiceCtrlHandlerA(LPCSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc)
{
*
* @implemented
*/
-SERVICE_STATUS_HANDLE STDCALL
+SERVICE_STATUS_HANDLE WINAPI
RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc)
{
Service->HandlerFunction = lpHandlerProc;
Service->HandlerFunctionEx = NULL;
- DPRINT("RegisterServiceCtrlHandler returning %lu\n", Service->hService);
+ TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hServiceStatus);
- return (SERVICE_STATUS_HANDLE)Service->hService;
+ return Service->hServiceStatus;
}
*
* @implemented
*/
-SERVICE_STATUS_HANDLE STDCALL
+SERVICE_STATUS_HANDLE WINAPI
RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName,
LPHANDLER_FUNCTION_EX lpHandlerProc,
LPVOID lpContext)
*
* @implemented
*/
-SERVICE_STATUS_HANDLE STDCALL
+SERVICE_STATUS_HANDLE WINAPI
RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
LPHANDLER_FUNCTION_EX lpHandlerProc,
LPVOID lpContext)
Service->HandlerFunctionEx = lpHandlerProc;
Service->HandlerContext = lpContext;
- DPRINT("RegisterServiceCtrlHandlerEx returning %lu", Service->hService);
+ TRACE("RegisterServiceCtrlHandlerEx returning %lu\n", Service->hServiceStatus);
+
+ return Service->hServiceStatus;
+}
+
+
+/**********************************************************************
+ * I_ScSetServiceBitsA
+ *
+ * Undocumented
+ *
+ * @implemented
+ */
+BOOL WINAPI
+I_ScSetServiceBitsA(SERVICE_STATUS_HANDLE hServiceStatus,
+ DWORD dwServiceBits,
+ BOOL bSetBitsOn,
+ BOOL bUpdateImmediately,
+ LPSTR lpString)
+{
+ BOOL bResult;
+
+ RpcTryExcept
+ {
+ /* Call to services.exe using RPC */
+ bResult = RI_ScSetServiceBitsA((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
+ dwServiceBits,
+ bSetBitsOn,
+ bUpdateImmediately,
+ lpString);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ScmRpcStatusToWinError(RpcExceptionCode()));
+ bResult = FALSE;
+ }
+ RpcEndExcept;
+
+ return bResult;
+}
+
+
+/**********************************************************************
+ * I_ScSetServiceBitsW
+ *
+ * Undocumented
+ *
+ * @implemented
+ */
+BOOL WINAPI
+I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus,
+ DWORD dwServiceBits,
+ BOOL bSetBitsOn,
+ BOOL bUpdateImmediately,
+ LPWSTR lpString)
+{
+ BOOL bResult;
+
+ RpcTryExcept
+ {
+ /* Call to services.exe using RPC */
+ bResult = RI_ScSetServiceBitsW((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
+ dwServiceBits,
+ bSetBitsOn,
+ bUpdateImmediately,
+ lpString);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ScmRpcStatusToWinError(RpcExceptionCode()));
+ bResult = FALSE;
+ }
+ RpcEndExcept;
- return (SERVICE_STATUS_HANDLE)Service->hService;
+ return bResult;
}
/**********************************************************************
* SetServiceBits
*
- * @unimplemented
+ * @implemented
*/
-BOOL STDCALL
+BOOL WINAPI
SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
DWORD dwServiceBits,
BOOL bSetBitsOn,
BOOL bUpdateImmediately)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ return I_ScSetServiceBitsW(hServiceStatus,
+ dwServiceBits,
+ bSetBitsOn,
+ bUpdateImmediately,
+ NULL);
}
*
* @implemented
*/
-BOOL STDCALL
+BOOL WINAPI
SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
LPSERVICE_STATUS lpServiceStatus)
{
DWORD dwError;
- DPRINT("SetServiceStatus() called\n");
- DPRINT("hServiceStatus %lu\n", hServiceStatus);
+ TRACE("SetServiceStatus() called\n");
+ TRACE("hServiceStatus %lu\n", hServiceStatus);
- HandleBind();
+ RpcTryExcept
+ {
+ /* Call to services.exe using RPC */
+ dwError = RSetServiceStatus((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
+ lpServiceStatus);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+ }
+ RpcEndExcept;
- /* Call to services.exe using RPC */
- dwError = ScmrSetServiceStatus(BindingHandle,
- (unsigned long)hServiceStatus,
- lpServiceStatus);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmrSetServiceStatus() failed (Error %lu)\n", dwError);
+ ERR("ScmrSetServiceStatus() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
- DPRINT("SetServiceStatus() done (ret %lu)\n", dwError);
+ TRACE("SetServiceStatus() done (ret %lu)\n", dwError);
return TRUE;
}
*
* @implemented
*/
-BOOL STDCALL
-StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
+BOOL WINAPI
+StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
{
ULONG i;
HANDLE hPipe;
DWORD dwError;
PUCHAR lpMessageBuffer;
- DPRINT("StartServiceCtrlDispatcherA() called\n");
+ TRACE("StartServiceCtrlDispatcherA() called\n");
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
- lpActiveServices[i].hService = (CLIENT_HANDLE)&lpActiveServices[i];
+ lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = FALSE;
}
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;
if (lpMessageBuffer == NULL)
{
/* Free the service table */
+ for (i = 0; i < dwActiveServiceCount; i++)
+ {
+ RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+ }
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return FALSE;
}
+ ScCreateStatusBinding();
+
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
+
+ ScDestroyStatusBinding();
+
CloseHandle(hPipe);
/* Free the message buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
/* Free the service table */
+ for (i = 0; i < dwActiveServiceCount; i++)
+ {
+ RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+ }
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
*
* @implemented
*/
-BOOL STDCALL
-StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
+BOOL WINAPI
+StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
{
ULONG i;
HANDLE hPipe;
DWORD dwError;
PUCHAR lpMessageBuffer;
- DPRINT("StartServiceCtrlDispatcherW() called\n");
+ TRACE("StartServiceCtrlDispatcherW() called\n");
i = 0;
while (lpServiceStartTable[i].lpServiceProc != NULL)
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
- lpActiveServices[i].hService = (CLIENT_HANDLE)&lpActiveServices[i];
+ lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = TRUE;
}
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;
if (lpMessageBuffer == NULL)
{
/* Free the service table */
+ for (i = 0; i < dwActiveServiceCount; i++)
+ {
+ RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+ }
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;
return FALSE;
}
+ ScCreateStatusBinding();
+
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
+
+ ScDestroyStatusBinding();
+
CloseHandle(hPipe);
/* Free the message buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
/* Free the service table */
+ for (i = 0; i < dwActiveServiceCount; i++)
+ {
+ RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+ }
RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
lpActiveServices = NULL;
dwActiveServiceCount = 0;