mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Added check for loaded system start drivers.
Create control pipe before a service is started. svn path=/trunk/; revision=3271
This commit is contained in:
parent
ed77972722
commit
86dc3a88d2
1 changed files with 123 additions and 47 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: database.c,v 1.3 2002/06/17 15:47:32 ekohl Exp $
|
/* $Id: database.c,v 1.4 2002/07/20 13:34:10 ekohl Exp $
|
||||||
*
|
*
|
||||||
* service control manager
|
* service control manager
|
||||||
*
|
*
|
||||||
|
@ -64,13 +64,16 @@ typedef struct _SERVICE
|
||||||
BOOLEAN ServiceRunning;
|
BOOLEAN ServiceRunning;
|
||||||
BOOLEAN ServiceVisited;
|
BOOLEAN ServiceVisited;
|
||||||
|
|
||||||
|
HANDLE ControlPipeHandle;
|
||||||
|
ULONG ProcessId;
|
||||||
|
ULONG ThreadId;
|
||||||
} SERVICE, *PSERVICE;
|
} SERVICE, *PSERVICE;
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
LIST_ENTRY GroupListHead = {NULL, NULL};
|
LIST_ENTRY GroupListHead;
|
||||||
LIST_ENTRY ServiceListHead = {NULL, NULL};
|
LIST_ENTRY ServiceListHead;
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -309,15 +312,20 @@ ScmCreateServiceDataBase(VOID)
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ScmCheckDriver(PSERVICE_GROUP Group,
|
ScmCheckDriver(PSERVICE Service)
|
||||||
PSERVICE Service)
|
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING DirName;
|
UNICODE_STRING DirName;
|
||||||
HANDLE DirHandle;
|
HANDLE DirHandle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
POBJDIR_INFORMATION DirInfo;
|
||||||
|
ULONG BufferLength;
|
||||||
|
ULONG DataLength;
|
||||||
|
ULONG Index;
|
||||||
|
PLIST_ENTRY GroupEntry;
|
||||||
|
PSERVICE_GROUP CurrentGroup;
|
||||||
|
|
||||||
DPRINT("ScmCheckDriver() called\n");
|
DPRINT("ScmCheckDriver(%wZ) called\n", &Service->ServiceName);
|
||||||
|
|
||||||
if (Service->Type == SERVICE_KERNEL_DRIVER)
|
if (Service->Type == SERVICE_KERNEL_DRIVER)
|
||||||
{
|
{
|
||||||
|
@ -344,37 +352,65 @@ ScmCheckDriver(PSERVICE_GROUP Group,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
BufferLength = sizeof(OBJDIR_INFORMATION) +
|
||||||
|
2 * MAX_PATH * sizeof(WCHAR);
|
||||||
|
DirInfo = HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
BufferLength);
|
||||||
|
|
||||||
Index = 0;
|
Index = 0;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
Status = NtQueryDirectoryObject(DirHandle,
|
Status = NtQueryDirectoryObject(DirHandle,
|
||||||
&DirInfo,
|
DirInfo,
|
||||||
BufferLength,
|
BufferLength,
|
||||||
TRUE,
|
TRUE,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Index,
|
&Index,
|
||||||
&DataLength);
|
&DataLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
{
|
{
|
||||||
NtClose(DirHandle);
|
/* FIXME: Add current service to 'failed service' list */
|
||||||
return(Status);
|
DPRINT("Service '%wZ' failed\n", &Service->ServiceName);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
if (!NT_SUCCESS(Status))
|
||||||
if (NT_SUCCESS(Status))
|
break;
|
||||||
|
|
||||||
|
DPRINT("Comparing: '%wZ' '%wZ'\n", &Service->ServiceName, &DirInfo->ObjectName);
|
||||||
|
|
||||||
|
if (RtlEqualUnicodeString(&Service->ServiceName, &DirInfo->ObjectName, TRUE))
|
||||||
|
{
|
||||||
|
DPRINT("Found: '%wZ' '%wZ'\n", &Service->ServiceName, &DirInfo->ObjectName);
|
||||||
|
|
||||||
|
/* Mark service as 'running' */
|
||||||
|
Service->ServiceRunning = TRUE;
|
||||||
|
|
||||||
|
/* Find the driver's group and mark it as 'running' */
|
||||||
|
if (Service->ServiceGroup.Buffer != NULL)
|
||||||
|
{
|
||||||
|
GroupEntry = GroupListHead.Flink;
|
||||||
|
while (GroupEntry != &GroupListHead)
|
||||||
{
|
{
|
||||||
CurrentGroup->ServicesRunning = TRUE;
|
CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
||||||
CurrentService->ServiceRunning = TRUE;
|
|
||||||
|
DPRINT("Checking group '%wZ'\n", &CurrentGroup->GroupName);
|
||||||
|
if (RtlEqualUnicodeString(&Service->ServiceGroup, &CurrentGroup->GroupName, TRUE))
|
||||||
|
{
|
||||||
|
CurrentGroup->ServicesRunning = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupEntry = GroupEntry->Flink;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
DirInfo);
|
||||||
NtClose(DirHandle);
|
NtClose(DirHandle);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -384,38 +420,26 @@ ScmCheckDriver(PSERVICE_GROUP Group,
|
||||||
VOID
|
VOID
|
||||||
ScmGetBootAndSystemDriverState(VOID)
|
ScmGetBootAndSystemDriverState(VOID)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY GroupEntry;
|
|
||||||
PLIST_ENTRY ServiceEntry;
|
PLIST_ENTRY ServiceEntry;
|
||||||
PSERVICE_GROUP CurrentGroup;
|
|
||||||
PSERVICE CurrentService;
|
PSERVICE CurrentService;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("ScmGetBootAndSystemDriverState() called\n");
|
DPRINT("ScmGetBootAndSystemDriverState() called\n");
|
||||||
|
|
||||||
GroupEntry = GroupListHead.Flink;
|
ServiceEntry = ServiceListHead.Flink;
|
||||||
while (GroupEntry != &GroupListHead)
|
while (ServiceEntry != &ServiceListHead)
|
||||||
{
|
{
|
||||||
CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
|
||||||
|
|
||||||
DPRINT("Checking group '%wZ'\n", &CurrentGroup->GroupName);
|
if (CurrentService->Start == SERVICE_BOOT_START ||
|
||||||
|
CurrentService->Start == SERVICE_SYSTEM_START)
|
||||||
ServiceEntry = ServiceListHead.Flink;
|
|
||||||
while (ServiceEntry != &ServiceListHead)
|
|
||||||
{
|
{
|
||||||
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
|
/* Check driver */
|
||||||
|
DPRINT(" Checking service: %wZ\n", &CurrentService->ServiceName);
|
||||||
|
|
||||||
if (CurrentService->Start == SERVICE_BOOT_START ||
|
ScmCheckDriver(CurrentService);
|
||||||
CurrentService->Start == SERVICE_SYSTEM_START)
|
|
||||||
{
|
|
||||||
/* Check driver */
|
|
||||||
DPRINT(" Checking service: %wZ\n", &CurrentService->ServiceName);
|
|
||||||
|
|
||||||
ScmCheckDriver(CurrentGroup,
|
|
||||||
CurrentService);
|
|
||||||
}
|
|
||||||
ServiceEntry = ServiceEntry->Flink;
|
|
||||||
}
|
}
|
||||||
GroupEntry = GroupEntry->Flink;
|
ServiceEntry = ServiceEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("ScmGetBootAndSystemDriverState() done\n");
|
DPRINT("ScmGetBootAndSystemDriverState() done\n");
|
||||||
|
@ -436,6 +460,8 @@ ScmStartService(PSERVICE Service,
|
||||||
|
|
||||||
DPRINT("ScmStartService() called\n");
|
DPRINT("ScmStartService() called\n");
|
||||||
|
|
||||||
|
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
if (Service->Type == SERVICE_KERNEL_DRIVER ||
|
if (Service->Type == SERVICE_KERNEL_DRIVER ||
|
||||||
Service->Type == SERVICE_FILE_SYSTEM_DRIVER ||
|
Service->Type == SERVICE_FILE_SYSTEM_DRIVER ||
|
||||||
Service->Type == SERVICE_RECOGNIZER_DRIVER)
|
Service->Type == SERVICE_RECOGNIZER_DRIVER)
|
||||||
|
@ -471,6 +497,21 @@ ScmStartService(PSERVICE Service,
|
||||||
DPRINT("Type: %lx\n", Type);
|
DPRINT("Type: %lx\n", Type);
|
||||||
|
|
||||||
/* FIXME: create '\\.\pipe\net\NtControlPipe' instance */
|
/* FIXME: create '\\.\pipe\net\NtControlPipe' instance */
|
||||||
|
Service->ControlPipeHandle = CreateNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe",
|
||||||
|
PIPE_ACCESS_DUPLEX,
|
||||||
|
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||||
|
100,
|
||||||
|
8000,
|
||||||
|
4,
|
||||||
|
30000,
|
||||||
|
NULL);
|
||||||
|
DPRINT1("CreateNamedPipeW() done\n");
|
||||||
|
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create control pipe!\n");
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
StartupInfo.cb = sizeof(StartupInfo);
|
StartupInfo.cb = sizeof(StartupInfo);
|
||||||
StartupInfo.lpReserved = NULL;
|
StartupInfo.lpReserved = NULL;
|
||||||
|
@ -485,29 +526,64 @@ ScmStartService(PSERVICE Service,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
DETACHED_PROCESS,
|
DETACHED_PROCESS | CREATE_SUSPENDED,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&StartupInfo,
|
&StartupInfo,
|
||||||
&ProcessInformation);
|
&ProcessInformation);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&ImagePath);
|
RtlFreeUnicodeString(&ImagePath);
|
||||||
|
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
/* FIXME: close control pipe */
|
/* Close control pipe */
|
||||||
|
CloseHandle(Service->ControlPipeHandle);
|
||||||
|
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
DPRINT("Failed to start '%S'\n", Service->ServiceName.Buffer);
|
DPRINT("Starting '%S' failed!\n", Service->ServiceName.Buffer);
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: connect control pipe */
|
DPRINT1("Process Id: %lu Handle %lx\n",
|
||||||
|
ProcessInformation.dwProcessId,
|
||||||
|
ProcessInformation.hProcess);
|
||||||
|
DPRINT1("Tread Id: %lu Handle %lx\n",
|
||||||
|
ProcessInformation.dwThreadId,
|
||||||
|
ProcessInformation.hThread);
|
||||||
|
|
||||||
|
/* Get process and thread ids */
|
||||||
|
Service->ProcessId = ProcessInformation.dwProcessId;
|
||||||
|
Service->ThreadId = ProcessInformation.dwThreadId;
|
||||||
|
|
||||||
|
/* Resume Thread */
|
||||||
|
ResumeThread(ProcessInformation.hThread);
|
||||||
|
|
||||||
|
/* FIXME: connect control pipe */
|
||||||
|
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Control pipe connected!\n");
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Connecting control pipe failed!\n");
|
||||||
|
|
||||||
|
/* Close control pipe */
|
||||||
|
CloseHandle(Service->ControlPipeHandle);
|
||||||
|
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||||
|
Service->ProcessId = 0;
|
||||||
|
Service->ThreadId = 0;
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close process and thread handle */
|
||||||
|
CloseHandle(ProcessInformation.hThread);
|
||||||
|
CloseHandle(ProcessInformation.hProcess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (Group != NULL)
|
if (Group != NULL)
|
||||||
|
|
Loading…
Reference in a new issue