Author: ekohl
Date: Sat Feb 27 22:47:59 2010
New Revision: 45711
URL:
http://svn.reactos.org/svn/reactos?rev=45711&view=rev
Log:
[SERVICES]
- Generate unique service status handles. Services could set the status information of
another service because the status handles were not guaranteed to be unique for all
services.
- Lock and unlock the service database when getting or setting service status
information.
Modified:
trunk/reactos/base/system/services/database.c
trunk/reactos/base/system/services/rpcserver.c
trunk/reactos/base/system/services/services.h
trunk/reactos/dll/win32/advapi32/service/sctrl.c
trunk/reactos/include/reactos/services/services.h
Modified: trunk/reactos/base/system/services/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -107,37 +107,6 @@
SERVICE,
ServiceListEntry);
if (CurrentService->dwResumeCount > dwResumeCount)
- {
- DPRINT("Found service: '%S'\n",
CurrentService->lpDisplayName);
- return CurrentService;
- }
-
- ServiceEntry = ServiceEntry->Flink;
- }
-
- DPRINT("Couldn't find a matching service\n");
-
- return NULL;
-}
-
-
-PSERVICE
-ScmGetServiceEntryByClientHandle(HANDLE Handle)
-{
- PLIST_ENTRY ServiceEntry;
- PSERVICE CurrentService;
-
- DPRINT("ScmGetServiceEntryByClientHandle() called\n");
- DPRINT("looking for %p\n", Handle);
-
- ServiceEntry = ServiceListHead.Flink;
- while (ServiceEntry != &ServiceListHead)
- {
- CurrentService = CONTAINING_RECORD(ServiceEntry,
- SERVICE,
- ServiceListEntry);
-
- if (CurrentService->hClient == Handle)
{
DPRINT("Found service: '%S'\n",
CurrentService->lpDisplayName);
return CurrentService;
@@ -728,8 +697,8 @@
return ERROR_NOT_ENOUGH_MEMORY;
ControlPacket->dwControl = dwControl;
- ControlPacket->hClient = Service->hClient;
ControlPacket->dwSize = TotalLength;
+ ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
/* Send the control packet */
@@ -793,7 +762,7 @@
return ERROR_NOT_ENOUGH_MEMORY;
ControlPacket->dwControl = SERVICE_CONTROL_START;
- ControlPacket->hClient = Service->hClient;
+ ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
ControlPacket->dwSize = TotalLength;
Ptr = &ControlPacket->szArguments[0];
wcscpy(Ptr, Service->lpServiceName);
@@ -850,6 +819,7 @@
WCHAR NtControlPipeName[MAX_PATH + 1];
HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
DWORD KeyDisposition;
+ DWORD dwProcessId;
RtlInitUnicodeString(&ImagePath, NULL);
@@ -991,7 +961,7 @@
/* Read SERVICE_STATUS_HANDLE from pipe */
if (!ReadFile(Service->ControlPipeHandle,
- (LPVOID)&Service->hClient,
+ (LPVOID)&dwProcessId,
sizeof(DWORD),
&dwRead,
NULL))
@@ -1002,7 +972,7 @@
}
else
{
- DPRINT("Received service status %lu\n", Service->hClient);
+ DPRINT("Received service process ID %lu\n", dwProcessId);
/* Send start command */
dwError = ScmSendStartCommand(Service, argc, argv);
@@ -1244,4 +1214,25 @@
DPRINT("ScmGetBootAndSystemDriverState() done\n");
}
+
+BOOL
+ScmLockDatabaseExclusive(VOID)
+{
+ return RtlAcquireResourceExclusive(&DatabaseLock, TRUE);
+}
+
+
+BOOL
+ScmLockDatabaseShared(VOID)
+{
+ return RtlAcquireResourceShared(&DatabaseLock, TRUE);
+}
+
+
+VOID
+ScmUnlockDatabase(VOID)
+{
+ RtlReleaseResource(&DatabaseLock);
+}
+
/* EOF */
Modified: trunk/reactos/base/system/services/rpcserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcse…
==============================================================================
--- trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -978,10 +978,14 @@
return ERROR_INVALID_HANDLE;
}
+ ScmLockDatabaseShared();
+
/* Return service status information */
RtlCopyMemory(lpServiceStatus,
&lpService->Status,
sizeof(SERVICE_STATUS));
+
+ ScmUnlockDatabase();
return ERROR_SUCCESS;
}
@@ -1030,7 +1034,7 @@
return ERROR_INVALID_HANDLE;
}
- lpService = ScmGetServiceEntryByClientHandle((HANDLE)hServiceStatus);
+ lpService = (PSERVICE)hServiceStatus;
if (lpService == NULL)
{
DPRINT("lpService == NULL!\n");
@@ -1059,10 +1063,13 @@
return ERROR_INVALID_DATA;
}
+ ScmLockDatabaseExclusive();
RtlCopyMemory(&lpService->Status,
lpServiceStatus,
sizeof(SERVICE_STATUS));
+
+ ScmUnlockDatabase();
DPRINT("Set %S to %lu\n", lpService->lpDisplayName,
lpService->Status.dwCurrentState);
DPRINT("RSetServiceStatus() done\n");
Modified: trunk/reactos/base/system/services/services.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servi…
==============================================================================
--- trunk/reactos/base/system/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/services.h [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -42,7 +42,6 @@
DWORD dwResumeCount;
DWORD dwRefCount;
- CLIENT_HANDLE hClient;
SERVICE_STATUS Status;
DWORD dwStartType;
DWORD dwErrorControl;
@@ -112,7 +111,6 @@
PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName);
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
-PSERVICE ScmGetServiceEntryByClientHandle(HANDLE Handle);
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
PSERVICE *lpServiceRecord);
VOID ScmDeleteServiceRecord(PSERVICE lpService);
@@ -121,6 +119,11 @@
DWORD ScmControlService(PSERVICE Service,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus);
+
+BOOL ScmLockDatabaseExclusive(VOID);
+BOOL ScmLockDatabaseShared(VOID);
+VOID ScmUnlockDatabase(VOID);
+
/* driver.c */
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 [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/service/sctrl.c [iso-8859-1] Sat Feb 27 22:47:59
2010
@@ -22,7 +22,7 @@
typedef struct _ACTIVE_SERVICE
{
- CLIENT_HANDLE hService;
+ SERVICE_STATUS_HANDLE hServiceStatus;
UNICODE_STRING ServiceName;
union
{
@@ -32,7 +32,6 @@
LPHANDLER_FUNCTION HandlerFunction;
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext;
- SERVICE_STATUS ServiceStatus;
BOOL bUnicode;
LPWSTR Arguments;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
@@ -199,6 +198,7 @@
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,
@@ -249,37 +249,34 @@
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);
- TRACE("Sent SERVICE_HANDLE %lu\n", lpActiveServices->hService);
+ TRACE("Sent Process ID %lu\n", dwProcessId);
+
return ERROR_SUCCESS;
}
static DWORD
-ScStartService(PSCM_CONTROL_PACKET ControlPacket)
-{
- PACTIVE_SERVICE lpService;
+ScStartService(PACTIVE_SERVICE lpService,
+ PSCM_CONTROL_PACKET ControlPacket)
+{
HANDLE ThreadHandle;
DWORD ThreadId;
TRACE("ScStartService() called\n");
- TRACE("client handle: %lu\n", ControlPacket->hClient);
TRACE("Size: %lu\n", ControlPacket->dwSize);
TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
- lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
- if (lpService == NULL)
- {
- TRACE("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,
@@ -309,20 +306,12 @@
static DWORD
-ScControlService(PSCM_CONTROL_PACKET ControlPacket)
-{
- PACTIVE_SERVICE lpService;
-
+ScControlService(PACTIVE_SERVICE lpService,
+ PSCM_CONTROL_PACKET ControlPacket)
+{
TRACE("ScControlService() called\n");
TRACE("Size: %lu\n", ControlPacket->dwSize);
TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
-
- lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
- if (lpService == NULL)
- {
- TRACE("Service not found\n");
- return ERROR_SERVICE_DOES_NOT_EXIST;
- }
if (lpService->HandlerFunction)
{
@@ -356,6 +345,8 @@
DWORD Count;
BOOL bResult;
DWORD dwRunningServices = 0;
+ LPWSTR lpServiceName;
+ PACTIVE_SERVICE lpService;
TRACE("ScDispatcherLoop() called\n");
@@ -379,25 +370,32 @@
return FALSE;
}
- /* Execute command */
- switch (ControlPacket->dwControl)
- {
- case SERVICE_CONTROL_START:
- TRACE("Start command - recieved SERVICE_CONTROL_START\n");
- if (ScStartService(ControlPacket) == ERROR_SUCCESS)
- dwRunningServices++;
- break;
-
- case SERVICE_CONTROL_STOP:
- TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
- if (ScControlService(ControlPacket) == ERROR_SUCCESS)
- dwRunningServices--;
- break;
-
- default:
- TRACE("Command %lu received", ControlPacket->dwControl);
- ScControlService(ControlPacket);
- continue;
+ 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");
+ if (ScStartService(lpService, ControlPacket) == ERROR_SUCCESS)
+ dwRunningServices++;
+ break;
+
+ case SERVICE_CONTROL_STOP:
+ TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
+ if (ScControlService(lpService, ControlPacket) == ERROR_SUCCESS)
+ dwRunningServices--;
+ break;
+
+ default:
+ TRACE("Command %lu received",
ControlPacket->dwControl);
+ ScControlService(lpService, ControlPacket);
+ continue;
+ }
}
if (dwRunningServices == 0)
@@ -461,9 +459,9 @@
Service->HandlerFunction = lpHandlerProc;
Service->HandlerFunctionEx = NULL;
- TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hService);
-
- return (SERVICE_STATUS_HANDLE)Service->hService;
+ TRACE("RegisterServiceCtrlHandler returning %lu\n",
Service->hServiceStatus);
+
+ return Service->hServiceStatus;
}
@@ -520,9 +518,9 @@
Service->HandlerFunctionEx = lpHandlerProc;
Service->HandlerContext = lpContext;
- TRACE("RegisterServiceCtrlHandlerEx returning %lu\n",
Service->hService);
-
- return (SERVICE_STATUS_HANDLE)Service->hService;
+ TRACE("RegisterServiceCtrlHandlerEx returning %lu\n",
Service->hServiceStatus);
+
+ return Service->hServiceStatus;
}
@@ -683,7 +681,7 @@
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;
}
@@ -773,7 +771,7 @@
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;
}
Modified: trunk/reactos/include/reactos/services/services.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/services/s…
==============================================================================
--- trunk/reactos/include/reactos/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/services/services.h [iso-8859-1] Sat Feb 27 22:47:59
2010
@@ -11,12 +11,10 @@
#define SERVICE_CONTROL_START 0
-DECLARE_HANDLE(CLIENT_HANDLE);
-
typedef struct _SCM_CONTROL_PACKET
{
DWORD dwControl;
- CLIENT_HANDLE hClient;
+ SERVICE_STATUS_HANDLE hServiceStatus;
DWORD dwSize;
WCHAR szArguments[1];
} SCM_CONTROL_PACKET, *PSCM_CONTROL_PACKET;