#include <debug.h>
-/* TYPES *********************************************************************/
-
-typedef struct _SERVICE_GROUP
-{
- LIST_ENTRY GroupListEntry;
- UNICODE_STRING GroupName;
-
- BOOLEAN ServicesRunning;
- ULONG TagCount;
- PULONG TagArray;
-
-} SERVICE_GROUP, *PSERVICE_GROUP;
-
-
/* GLOBALS *******************************************************************/
-LIST_ENTRY GroupListHead;
LIST_ENTRY ServiceListHead;
static RTL_RESOURCE DatabaseLock;
+static DWORD dwResumeCount = 1;
/* FUNCTIONS *****************************************************************/
}
-static NTSTATUS STDCALL
-CreateGroupOrderListRoutine(PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
+PSERVICE
+ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
{
- PSERVICE_GROUP Group;
-
- DPRINT("CreateGroupOrderListRoutine(%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;
-}
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
+ DPRINT("ScmGetServiceEntryByResumeCount() called\n");
-static NTSTATUS STDCALL
-CreateGroupListRoutine(PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PSERVICE_GROUP Group;
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
-
- if (ValueType == REG_SZ)
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
{
- DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
-
- Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(SERVICE_GROUP));
- if (Group == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if (!RtlCreateUnicodeString(&Group->GroupName,
- (PWSTR)ValueData))
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+ if (CurrentService->dwResumeCount > dwResumeCount)
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
+ return CurrentService;
}
- 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,
- &Group->GroupListEntry);
+ ServiceEntry = ServiceEntry->Flink;
}
- return STATUS_SUCCESS;
+ DPRINT("Couldn't find a matching service\n");
+
+ return NULL;
}
lpService->lpServiceName = lpService->szServiceName;
lpService->lpDisplayName = lpService->lpServiceName;
+ /* Set the resume count */
+ lpService->dwResumeCount = dwResumeCount++;
+
/* Append service entry */
InsertTailList(&ServiceListHead,
&lpService->ServiceListEntry);
}
-DWORD
-ScmReadGroupList(VOID)
+VOID
+ScmDeleteMarkedServices(VOID)
{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
- InitializeListHead(&GroupListHead);
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
- /* Build group order list */
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
+ ServiceEntry = ServiceEntry->Flink;
- QueryTable[0].Name = L"List";
- QueryTable[0].QueryRoutine = CreateGroupListRoutine;
+ if (CurrentService->bDeleted == TRUE)
+ {
+ DPRINT1("Delete service: %S\n", CurrentService->lpServiceName);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
- L"ServiceGroupOrder",
- QueryTable,
- NULL,
- NULL);
+ /* FIXME: Delete the registry keys */
+
+ /* FIXME: Delete the service record from the list */
- return RtlNtStatusToDosError(Status);
+ }
+ }
}
DPRINT("ScmCreateServiceDatabase() called\n");
- dwError = ScmReadGroupList();
+ dwError = ScmCreateGroupList();
if (dwError != ERROR_SUCCESS)
return dwError;
RegCloseKey(hServicesKey);
- /* FIXME: Delete services that are marked for delete */
+ /* Delete services that are marked for delete */
+ ScmDeleteMarkedServices();
DPRINT("ScmCreateServiceDatabase() done\n");
{
CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
- DPRINT("Checking group '%wZ'\n", &CurrentGroup->GroupName);
+ DPRINT("Checking group '%S'\n", &CurrentGroup->lpGroupName);
if (Service->lpServiceGroup != NULL &&
- _wcsicmp(Service->lpServiceGroup, CurrentGroup->GroupName.Buffer) == 0)
+ _wcsicmp(Service->lpServiceGroup, CurrentGroup->lpGroupName) == 0)
{
CurrentGroup->ServicesRunning = TRUE;
}
ScmStartService(PSERVICE Service,
PSERVICE_GROUP Group)
{
- WCHAR szDriverPath[MAX_PATH];
- UNICODE_STRING DriverPath;
NTSTATUS Status;
DPRINT("ScmStartService() called\n");
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
{
{
CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
- DPRINT("Group '%wZ'\n", &CurrentGroup->GroupName);
+ DPRINT("Group '%S'\n", CurrentGroup->lpGroupName);
/* Start all services witch have a valid tag */
for (i = 0; i < CurrentGroup->TagCount; i++)
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
if ((CurrentService->lpServiceGroup != NULL) &&
- (_wcsicmp(CurrentGroup->GroupName.Buffer, CurrentService->lpServiceGroup) == 0) &&
+ (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
(CurrentService->dwStartType == SERVICE_AUTO_START) &&
(CurrentService->ServiceVisited == FALSE) &&
(CurrentService->dwTag == CurrentGroup->TagArray[i]))
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
if ((CurrentService->lpServiceGroup != NULL) &&
- (_wcsicmp(CurrentGroup->GroupName.Buffer, CurrentService->lpServiceGroup) == 0) &&
+ (_wcsicmp(CurrentGroup->lpGroupName, CurrentService->lpServiceGroup) == 0) &&
(CurrentService->dwStartType == SERVICE_AUTO_START) &&
(CurrentService->ServiceVisited == FALSE))
{