- Prepare to delete marked services upon startup.

- ControlService: Implement unloading of drivers.

svn path=/trunk/; revision=19385
This commit is contained in:
Eric Kohl 2005-11-20 20:18:00 +00:00
parent 5488776a17
commit 840ca0f27e
5 changed files with 174 additions and 20 deletions

View file

@ -404,6 +404,32 @@ ScmReadGroupList(VOID)
}
VOID
ScmDeleteMarkedServices(VOID)
{
PLIST_ENTRY ServiceEntry;
PSERVICE CurrentService;
ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead)
{
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
ServiceEntry = ServiceEntry->Flink;
if (CurrentService->bDeleted == TRUE)
{
DPRINT1("Delete service: %S\n", CurrentService->lpServiceName);
/* FIXME: Delete the registry keys */
/* FIXME: Delete the service record from the list */
}
}
}
DWORD
ScmCreateServiceDatabase(VOID)
{
@ -474,7 +500,8 @@ ScmCreateServiceDatabase(VOID)
RegCloseKey(hServicesKey);
/* FIXME: Delete services that are marked for delete */
/* Delete services that are marked for delete */
ScmDeleteMarkedServices();
DPRINT("ScmCreateServiceDatabase() done\n");
@ -836,8 +863,6 @@ static NTSTATUS
ScmStartService(PSERVICE Service,
PSERVICE_GROUP Group)
{
WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath;
NTSTATUS Status;
DPRINT("ScmStartService() called\n");
@ -845,21 +870,12 @@ ScmStartService(PSERVICE Service,
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER ||
Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER ||
Service->Status.dwServiceType == SERVICE_RECOGNIZER_DRIVER)
if (Service->Status.dwServiceType & SERVICE_DRIVER)
{
/* Load driver */
wcscpy(szDriverPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
wcscat(szDriverPath,
Service->lpServiceName);
RtlInitUnicodeString(&DriverPath,
szDriverPath);
DPRINT(" Path: %wZ\n", &DriverPath);
Status = NtLoadDriver(&DriverPath);
Status = ScmLoadDriver(Service);
if (Status == STATUS_SUCCESS)
Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
}
else
{

View file

@ -0,0 +1,113 @@
/*
* driver.c
*/
/* INCLUDES *****************************************************************/
#include "services.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
NTSTATUS
ScmLoadDriver(PSERVICE lpService)
{
WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath;
NTSTATUS Status;
/* Build the driver path */
wcscpy(szDriverPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
wcscat(szDriverPath,
lpService->lpServiceName);
RtlInitUnicodeString(&DriverPath,
szDriverPath);
/* FIXME: Acquire privilege */
DPRINT(" Path: %wZ\n", &DriverPath);
Status = NtLoadDriver(&DriverPath);
/* FIXME: Release privilege */
return Status;
}
DWORD
ScmUnloadDriver(PSERVICE lpService)
{
WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */
wcscpy(szDriverPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
wcscat(szDriverPath,
lpService->lpServiceName);
RtlInitUnicodeString(&DriverPath,
szDriverPath);
/* FIXME: Acquire privilege */
Status = NtUnloadDriver(&DriverPath);
/* FIXME: Release privilege */
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
}
return dwError;
}
DWORD
ScmControlDriver(PSERVICE lpService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus)
{
DWORD dwError;
DPRINT("ScmControlDriver() called\n");
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
if (lpService->Status.dwCurrentState != SERVICE_RUNNING)
{
dwError = ERROR_INVALID_SERVICE_CONTROL;
goto done;
}
dwError = ScmUnloadDriver(lpService);
if (dwError == ERROR_SUCCESS)
{
lpService->Status.dwControlsAccepted = 0;
lpService->Status.dwCurrentState = SERVICE_STOPPED;
}
break;
case SERVICE_CONTROL_INTERROGATE:
dwError = ERROR_INVALID_SERVICE_CONTROL;
break;
default:
dwError = ERROR_INVALID_SERVICE_CONTROL;
}
done:;
DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
return dwError;
}
/* EOF */

View file

@ -281,6 +281,7 @@ ScmrControlService(handle_t BindingHandle,
PSERVICE_HANDLE hSvc;
PSERVICE lpService;
ACCESS_MASK DesiredAccess;
DWORD dwError = ERROR_SUCCESS;
DPRINT("ScmrControlService() called\n");
@ -335,16 +336,30 @@ ScmrControlService(handle_t BindingHandle,
return ERROR_INVALID_HANDLE;
}
/* FIXME: Send control code to the service */
if (lpService->Status.dwServiceType & SERVICE_DRIVER)
{
/* Send control code to the driver */
dwError = ScmControlDriver(lpService,
dwControl,
lpServiceStatus);
}
else
{
/* FIXME: Send control code to the service */
#if 0
dwError = ScmControlService(lpService,
dwControl,
lpServiceStatus);
#endif
dwError = ERROR_INVALID_SERVICE_CONTROL;
}
/* Return service status information */
RtlCopyMemory(lpServiceStatus,
&lpService->Status,
sizeof(SERVICE_STATUS));
return ERROR_SUCCESS;
return dwError;
}

View file

@ -76,6 +76,15 @@ DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
DWORD ScmMarkServiceForDelete(PSERVICE pService);
/* driver.c */
NTSTATUS ScmLoadDriver(PSERVICE lpService);
DWORD ScmUnloadDriver(PSERVICE lpService);
DWORD ScmControlDriver(PSERVICE lpService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus);
/* rpcserver.c */
VOID ScmStartRpcServer(VOID);

View file

@ -12,6 +12,7 @@
<library>rpcrt4</library>
<file>config.c</file>
<file>database.c</file>
<file>driver.c</file>
<file>rpcserver.c</file>
<file>services.c</file>
<file>services.rc</file>