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:
Eric Kohl 2002-07-20 13:34:10 +00:00
parent ed77972722
commit 86dc3a88d2

View file

@ -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)