mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- Prepare to delete marked services upon startup.
- ControlService: Implement unloading of drivers. svn path=/trunk/; revision=19385
This commit is contained in:
parent
5488776a17
commit
840ca0f27e
5 changed files with 174 additions and 20 deletions
|
@ -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
|
||||
{
|
||||
|
|
113
reactos/subsys/system/services/driver.c
Normal file
113
reactos/subsys/system/services/driver.c
Normal 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 */
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue