Author: gedmurphy
Date: Tue Sep 11 16:59:38 2007
New Revision: 29005
URL:
http://svn.reactos.org/svn/reactos?rev=29005&view=rev
Log:
- Send the SERVICE_STATUS_HANDLE to the SCM so SetServiceStatus has something to work
with
- Add control code to stop, pause and resume services and forward it onto the service
control handler
Modified:
trunk/reactos/dll/win32/advapi32/service/scm.c
trunk/reactos/dll/win32/advapi32/service/sctrl.c
Modified: trunk/reactos/dll/win32/advapi32/service/scm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/scm.c (original)
+++ trunk/reactos/dll/win32/advapi32/service/scm.c Tue Sep 11 16:59:38 2007
@@ -21,7 +21,7 @@
handle_t BindingHandle = NULL;
-static VOID
+VOID
HandleBind(VOID)
{
LPWSTR pszStringBinding;
@@ -1987,38 +1987,6 @@
return TRUE;
}
-/**********************************************************************
- * SetServiceStatus
- *
- * @implemented
- */
-BOOL STDCALL
-SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
- LPSERVICE_STATUS lpServiceStatus)
-{
- DWORD dwError;
-
- DPRINT("SetServiceStatus() called\n");
- DPRINT("ThreadId %lu, data addr %p called\n", hServiceStatus,
lpServiceStatus);
-
- HandleBind();
-
- /* Call to services.exe using RPC */
- dwError = ScmrSetServiceStatus(BindingHandle,
- (unsigned long)hServiceStatus,
- lpServiceStatus);
- if (dwError != ERROR_SUCCESS)
- {
- DPRINT1("ScmrSetServiceStatus() failed (Error %lu)\n", dwError);
- SetLastError(dwError);
- return FALSE;
- }
-
- DPRINT("SetServiceStatus() done (ret %lu\n", dwError);
-
- return TRUE;
-}
-
/**********************************************************************
* StartServiceA
Modified: trunk/reactos/dll/win32/advapi32/service/sctrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/sctrl.c (original)
+++ trunk/reactos/dll/win32/advapi32/service/sctrl.c Tue Sep 11 16:59:38 2007
@@ -20,9 +20,11 @@
/* TYPES *********************************************************************/
+VOID HandleBind(VOID);
+
typedef struct _ACTIVE_SERVICE
{
- DWORD ThreadId;
+ SERVICE_STATUS_HANDLE hServiceStatus;
UNICODE_STRING ServiceName;
union
{
@@ -40,6 +42,7 @@
/* GLOBALS *******************************************************************/
+extern handle_t BindingHandle;
static DWORD dwActiveServiceCount = 0;
static PACTIVE_SERVICE lpActiveServices = NULL;
@@ -64,25 +67,6 @@
return NULL;
}
-/*
-static PACTIVE_SERVICE
-ScLookupServiceByThreadId(DWORD ThreadId)
-{
- DWORD i;
-
- for (i = 0; i < dwActiveServiceCount; i++)
- {
- if (lpActiveServices[i].ThreadId == ThreadId)
- {
- return &lpActiveServices[i];
- }
- }
-
- SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
-
- return NULL;
-}
-*/
static DWORD WINAPI
ScServiceMainStub(LPVOID Context)
@@ -213,7 +197,6 @@
ScConnectControlPipe(HANDLE *hPipe)
{
DWORD dwBytesWritten;
- DWORD dwProcessId;
DWORD dwState;
if (!WaitNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe", 15000))
@@ -243,14 +226,14 @@
return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
}
- dwProcessId = GetCurrentProcessId();
+ /* HACK: send the SERVICE_STATUS_HANDLE handle */
WriteFile(*hPipe,
- &dwProcessId,
- sizeof(DWORD),
+ (DWORD *)&lpActiveServices->hServiceStatus,
+ sizeof(SERVICE_STATUS_HANDLE),
&dwBytesWritten,
NULL);
- DPRINT("Sent process id %lu\n", dwProcessId);
+ DPRINT("Sent SERVICE_STATUS_HANDLE handle %lu\n",
lpActiveServices->hServiceStatus);
return ERROR_SUCCESS;
}
@@ -262,6 +245,7 @@
{
PACTIVE_SERVICE lpService;
HANDLE ThreadHandle;
+ DWORD ThreadId;
DPRINT("ScStartService() called\n");
DPRINT("Size: %lu\n", ControlPacket->dwSize);
@@ -281,17 +265,56 @@
ControlPacket->szArguments,
ControlPacket->dwSize * sizeof(WCHAR));
+ /* invoke the services entry point and implement the command loop */
ThreadHandle = CreateThread(NULL,
0,
ScServiceMainStub,
lpService,
CREATE_SUSPENDED,
- &lpService->ThreadId);
+ &ThreadId);
if (ThreadHandle == NULL)
return ERROR_SERVICE_NO_THREAD;
ResumeThread(ThreadHandle);
CloseHandle(ThreadHandle);
+
+ return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScControlService(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 = ScLookupServiceByServiceName(&ControlPacket->szArguments[0]);
+ if (lpService == NULL)
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+
+ if (lpService->HandlerFunction)
+ {
+ DPRINT("Calling HandlerFunction with %lu\n",
ControlPacket->dwControl);
+ (lpService->HandlerFunction)(ControlPacket->dwControl);
+ }
+ else if (lpService->HandlerFunctionEx)
+ {
+ DPRINT("Calling HandlerFunctionEx with %lu\n",
ControlPacket->dwControl);
+ /* FIXME: send correct params */
+ (lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL);
+ }
+
+ if (ControlPacket->dwControl == SERVICE_CONTROL_STOP)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpService->Arguments);
+ }
+
+ DPRINT("ScControlService() done\n");
return ERROR_SUCCESS;
}
@@ -333,19 +356,20 @@
switch (ControlPacket->dwControl)
{
case SERVICE_CONTROL_START:
- DPRINT("Start command\n");
+ DPRINT("Start command - recieved SERVICE_CONTROL_START\n");
if (ScStartService(ControlPacket) == ERROR_SUCCESS)
dwRunningServices++;
break;
case SERVICE_CONTROL_STOP:
- DPRINT("Stop command\n");
- dwRunningServices--;
+ DPRINT("Stop command - recieved SERVICE_CONTROL_STOP\n");
+ if (ScControlService(ControlPacket) == ERROR_SUCCESS)
+ dwRunningServices--;
break;
default:
- DPRINT1("Unknown command %lu", ControlPacket->dwControl);
- break;
+ DPRINT("Unknown command %lu", ControlPacket->dwControl);
+ continue;
}
if (dwRunningServices == 0)
@@ -409,7 +433,9 @@
Service->HandlerFunction = lpHandlerProc;
Service->HandlerFunctionEx = NULL;
- return (SERVICE_STATUS_HANDLE)Service->ThreadId;
+ DPRINT("RegisterServiceCtrlHandler returning %lu\n",
Service->hServiceStatus);
+
+ return Service->hServiceStatus;
}
@@ -456,6 +482,7 @@
{
PACTIVE_SERVICE Service;
+ /* FIXME: WinXP can start services with incorrect names */
Service = ScLookupServiceByServiceName(lpServiceName);
if (Service == NULL)
{
@@ -466,7 +493,9 @@
Service->HandlerFunctionEx = lpHandlerProc;
Service->HandlerContext = lpContext;
- return (SERVICE_STATUS_HANDLE)Service->ThreadId;
+ DPRINT("RegisterServiceCtrlHandlerEx returning %lu",
Service->hServiceStatus);
+
+ return Service->hServiceStatus;
}
@@ -487,6 +516,39 @@
/**********************************************************************
+ * SetServiceStatus
+ *
+ * @implemented
+ */
+BOOL STDCALL
+SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
+ LPSERVICE_STATUS lpServiceStatus)
+{
+ DWORD dwError;
+
+ DPRINT("SetServiceStatus() called\n");
+ DPRINT("hServiceStatus %lu\n", hServiceStatus);
+
+ HandleBind();
+
+ /* Call to services.exe using RPC */
+ dwError = ScmrSetServiceStatus(BindingHandle,
+ (unsigned long)hServiceStatus,
+ lpServiceStatus);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("ScmrSetServiceStatus() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ DPRINT("SetServiceStatus() done (ret %lu)\n", dwError);
+
+ return TRUE;
+}
+
+
+/**********************************************************************
* StartServiceCtrlDispatcherA
*
* @unimplemented
@@ -522,6 +584,7 @@
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
+ lpActiveServices[i].hServiceStatus =
(SERVICE_STATUS_HANDLE)&lpActiveServices[i];
lpActiveServices[i].bUnicode = FALSE;
}
@@ -599,6 +662,7 @@
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
+ lpActiveServices[i].hServiceStatus =
(SERVICE_STATUS_HANDLE)&lpActiveServices[i];
lpActiveServices[i].bUnicode = TRUE;
}