reactos/ntoskrnl/io
diff -u -r1.51 -r1.52
--- driver.c 7 Sep 2004 11:48:16 -0000 1.51
+++ driver.c 20 Sep 2004 19:47:25 -0000 1.52
@@ -1,4 +1,4 @@
-/* $Id: driver.c,v 1.51 2004/09/07 11:48:16 ekohl Exp $
+/* $Id: driver.c,v 1.52 2004/09/20 19:47:25 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -29,6 +29,8 @@
LIST_ENTRY GroupListEntry;
UNICODE_STRING GroupName;
BOOLEAN ServicesRunning;
+ ULONG TagCount;
+ PULONG TagArray;
} SERVICE_GROUP, *PSERVICE_GROUP;
typedef struct _SERVICE
@@ -705,6 +707,48 @@
return STATUS_SUCCESS;
}
+static NTSTATUS STDCALL
+IopGetGroupOrderList(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PSERVICE_GROUP Group;
+
+ DPRINT("IopGetGroupOrderList(%S, %x, %x, %x, %x, %x)\n",
+ ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
+
+ if (ValueType == REG_BINARY &&
+ ValueData != NULL &&
+ ValueLength >= sizeof(DWORD) &&
+ ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
+ {
+ Group = (PSERVICE_GROUP)Context;
+ Group->TagCount = ((PULONG)ValueData)[0];
+ if (Group->TagCount > 0)
+ {
+ if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
+ {
+ Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(DWORD));
+ if (Group->TagArray == NULL)
+ {
+ Group->TagCount = 0;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(DWORD));
+ }
+ else
+ {
+ Group->TagCount = 0;
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+ }
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS STDCALL
IopCreateGroupListEntry(PWSTR ValueName,
ULONG ValueType,
@@ -714,6 +758,9 @@
PVOID EntryContext)
{
PSERVICE_GROUP Group;
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
if (ValueType == REG_SZ)
{
@@ -735,6 +782,16 @@
return(STATUS_INSUFFICIENT_RESOURCES);
}
+ RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+ QueryTable[0].Name = (PWSTR)ValueData;
+ QueryTable[0].QueryRoutine = IopGetGroupOrderList;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"GroupOrderList",
+ QueryTable,
+ (PVOID)Group,
+ NULL);
+ DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
InsertTailList(&GroupListHead,
&Group->GroupListEntry);
@@ -747,7 +804,7 @@
static NTSTATUS STDCALL
IopCreateServiceListEntry(PUNICODE_STRING ServiceName)
{
- RTL_QUERY_REGISTRY_TABLE QueryTable[6];
+ RTL_QUERY_REGISTRY_TABLE QueryTable[7];
PSERVICE Service;
NTSTATUS Status;
@@ -786,6 +843,10 @@
QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[4].EntryContext = &Service->ImagePath;
+ QueryTable[5].Name = L"Tag";
+ QueryTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[5].EntryContext = &Service->Tag;
+
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
ServiceName->Buffer,
QueryTable,
@@ -823,8 +884,8 @@
DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);
- DPRINT("Start %lx Type %lx ErrorControl %lx\n",
- Service->Start, Service->Type, Service->ErrorControl);
+ DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n",
+ Service->Start, Service->Type, Service->Tag, Service->ErrorControl);
/* Append service entry */
InsertTailList(&ServiceListHead,
@@ -952,6 +1013,10 @@
RtlFreeUnicodeString(&CurrentGroup->GroupName);
RemoveEntryList(GroupEntry);
+ if (CurrentGroup->TagArray)
+ {
+ ExFreePool(CurrentGroup->TagArray);
+ }
ExFreePool(CurrentGroup);
GroupEntry = GroupListHead.Flink;
@@ -978,7 +1043,7 @@
return(STATUS_SUCCESS);
}
-VOID STATIC
+VOID STATIC INIT_FUNCTION
MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
{
ULONG i;
@@ -995,7 +1060,7 @@
* Initialize a driver that is already loaded in memory.
*/
-NTSTATUS FASTCALL
+NTSTATUS FASTCALL INIT_FUNCTION
IopInitializeBuiltinDriver(
PDEVICE_NODE ModuleDeviceNode,
PVOID ModuleLoadBase,
@@ -1179,6 +1244,45 @@
}
}
+static INIT_FUNCTION NTSTATUS
+IopLoadDriver(PSERVICE Service)
+{
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ IopDisplayLoadingMessage(Service->ServiceName.Buffer);
+ Status = NtLoadDriver(&Service->RegistryPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtLoadDriver() failed (Status %lx)\n", Status);
+#if 0
+ if (Service->ErrorControl == 1)
+ {
+ /* Log error */
+ }
+ else if (Service->ErrorControl == 2)
+ {
+ if (IsLastKnownGood == FALSE)
+ {
+ /* Boot last known good configuration */
+ }
+ }
+ else if (Service->ErrorControl == 3)
+ {
+ if (IsLastKnownGood == FALSE)
+ {
+ /* Boot last known good configuration */
+ }
+ else
+ {
+ /* BSOD! */
+ }
+ }
+#endif
+ }
+ return Status;
+}
+
+
/*
* IopInitializeSystemDrivers
*
@@ -1199,6 +1303,7 @@
PSERVICE_GROUP CurrentGroup;
PSERVICE CurrentService;
NTSTATUS Status;
+ ULONG i;
DPRINT("IopInitializeSystemDrivers()\n");
@@ -1209,45 +1314,47 @@
DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
+ /* Load all drivers with a valid tag */
+ for (i = 0; i < CurrentGroup->TagCount; i++)
+ {
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
+
+ if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
+ &CurrentService->ServiceGroup, TRUE) == 0) &&
+ (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/) &&
+ (CurrentService->Tag == CurrentGroup->TagArray[i]))
+ {
+ DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);
+ Status = IopLoadDriver(CurrentService);
+ }
+ ServiceEntry = ServiceEntry->Flink;
+ }
+ }
+
+ /* Load all drivers without a tag or with an invalid tag */
ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead)
{
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
-
if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
- &CurrentService->ServiceGroup, TRUE) == 0) &&
+ &CurrentService->ServiceGroup, TRUE) == 0) &&
(CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))
{
- DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);
- IopDisplayLoadingMessage(CurrentService->ServiceName.Buffer);
- Status = NtLoadDriver(&CurrentService->RegistryPath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtLoadDriver() failed (Status %lx)\n", Status);
-#if 0
- if (CurrentService->ErrorControl == 1)
- {
- /* Log error */
- } else
- if (CurrentService->ErrorControl == 2)
- {
- if (IsLastKnownGood == FALSE)
- {
- /* Boot last known good configuration */
- }
- } else
- if (CurrentService->ErrorControl == 3)
- {
- if (IsLastKnownGood == FALSE)
- {
- /* Boot last known good configuration */
- } else
- {
- /* BSOD! */
- }
- }
-#endif
- }
+ for (i = 0; i < CurrentGroup->TagCount; i++)
+ {
+ if (CurrentGroup->TagArray[i] == CurrentService->Tag)
+ {
+ break;
+ }
+ }
+ if (i >= CurrentGroup->TagCount)
+ {
+ DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);
+ Status = IopLoadDriver(CurrentService);
+ }
}
ServiceEntry = ServiceEntry->Flink;
}
reactos/subsys/system/services
diff -u -r1.17 -r1.18
--- database.c 3 Jul 2004 17:40:24 -0000 1.17
+++ database.c 20 Sep 2004 19:47:25 -0000 1.18
@@ -1,4 +1,4 @@
-/* $Id: database.c,v 1.17 2004/07/03 17:40:24 navaraf Exp $
+/* $Id: database.c,v 1.18 2004/09/20 19:47:25 hbirr Exp $
*
* service control manager
*
@@ -46,6 +46,8 @@
UNICODE_STRING GroupName;
BOOLEAN ServicesRunning;
+ ULONG TagCount;
+ PULONG TagArray;
} SERVICE_GROUP, *PSERVICE_GROUP;
@@ -79,6 +81,52 @@
/* FUNCTIONS *****************************************************************/
+static NTSTATUS STDCALL
+CreateGroupOrderListRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PSERVICE_GROUP Group;
+
+ DPRINT("IopGetGroupOrderList(%S, %x, %x, %x, %x, %x)\n",
+ ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
+
+ if (ValueType == REG_BINARY &&
+ ValueData != NULL &&
+ ValueLength >= sizeof(DWORD) &&
+ ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
+ {
+ Group = (PSERVICE_GROUP)Context;
+ Group->TagCount = ((PULONG)ValueData)[0];
+ if (Group->TagCount > 0)
+ {
+ if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
+ {
+ Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ Group->TagCount * sizeof(DWORD));
+ if (Group->TagArray == NULL)
+ {
+ Group->TagCount = 0;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlCopyMemory(Group->TagArray,
+ (PULONG)ValueData + 1,
+ Group->TagCount * sizeof(DWORD));
+ }
+ else
+ {
+ Group->TagCount = 0;
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+ }
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS STDCALL
CreateGroupListRoutine(PWSTR ValueName,
ULONG ValueType,
@@ -88,6 +136,8 @@
PVOID EntryContext)
{
PSERVICE_GROUP Group;
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
if (ValueType == REG_SZ)
{
@@ -106,6 +156,17 @@
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
+
+ RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+ QueryTable[0].Name = (PWSTR)ValueData;
+ QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"GroupOrderList",
+ QueryTable,
+ (PVOID)Group,
+ NULL);
+ DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
InsertTailList(&GroupListHead,
@@ -184,6 +245,10 @@
QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[3].EntryContext = &Service->ServiceGroup;
+ QueryTable[4].Name = L"Tag";
+ QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[4].EntryContext = &Service->Tag;
+
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
ServiceName->Buffer,
QueryTable,
@@ -201,8 +266,8 @@
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
- DPRINT("Start %lx Type %lx ErrorControl %lx\n",
- Service->Start, Service->Type, Service->ErrorControl);
+ DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n",
+ Service->Start, Service->Type, Service->Tag, Service->ErrorControl);
/* Append service entry */
InsertTailList(&ServiceListHead,
@@ -636,6 +701,7 @@
PLIST_ENTRY ServiceEntry;
PSERVICE_GROUP CurrentGroup;
PSERVICE CurrentService;
+ ULONG i;
/* Clear 'ServiceVisited' flag */
ServiceEntry = ServiceListHead.Flink;
@@ -654,6 +720,29 @@
DPRINT("Group '%wZ'\n", &CurrentGroup->GroupName);
+ /* Start all services witch have a valid tag */
+ for (i = 0; i < CurrentGroup->TagCount; i++)
+ {
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
+
+ if ((RtlEqualUnicodeString(&CurrentGroup->GroupName, &CurrentService->ServiceGroup, TRUE)) &&
+ (CurrentService->Start == SERVICE_AUTO_START) &&
+ (CurrentService->ServiceVisited == FALSE) &&
+ (CurrentService->Tag == CurrentGroup->TagArray[i]))
+ {
+ CurrentService->ServiceVisited = TRUE;
+ ScmStartService(CurrentService,
+ CurrentGroup);
+ }
+
+ ServiceEntry = ServiceEntry->Flink;
+ }
+ }
+
+ /* Start all services which have an invalid tag or which do not have a tag */
ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead)
{
@@ -680,7 +769,7 @@
{
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
- if ((CurrentService->ServiceGroup.Length == 0) &&
+ if ((CurrentService->ServiceGroup.Length != 0) &&
(CurrentService->Start == SERVICE_AUTO_START) &&
(CurrentService->ServiceVisited == FALSE))
{