mirror of
https://github.com/reactos/reactos.git
synced 2024-11-02 21:09:15 +00:00
260 lines
7.5 KiB
C
260 lines
7.5 KiB
C
/*
|
|
* PROJECT: ReactOS Service Control Manager
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: base/system/services/groupdb.c
|
|
* PURPOSE: Service group control interface
|
|
* COPYRIGHT: Copyright 2005 Eric Kohl
|
|
*
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "services.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
LIST_ENTRY GroupListHead;
|
|
LIST_ENTRY UnknownGroupListHead;
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
PSERVICE_GROUP
|
|
ScmGetServiceGroupByName(
|
|
_In_ LPCWSTR lpGroupName)
|
|
{
|
|
PLIST_ENTRY GroupEntry;
|
|
PSERVICE_GROUP lpGroup;
|
|
|
|
DPRINT("ScmGetServiceGroupByName(%S)\n", lpGroupName);
|
|
|
|
GroupEntry = GroupListHead.Flink;
|
|
while (GroupEntry != &GroupListHead)
|
|
{
|
|
lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
|
|
|
if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
|
|
return lpGroup;
|
|
|
|
GroupEntry = GroupEntry->Flink;
|
|
}
|
|
|
|
GroupEntry = UnknownGroupListHead.Flink;
|
|
while (GroupEntry != &UnknownGroupListHead)
|
|
{
|
|
lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
|
|
|
if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
|
|
return lpGroup;
|
|
|
|
GroupEntry = GroupEntry->Flink;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
DWORD
|
|
ScmSetServiceGroup(PSERVICE lpService,
|
|
LPCWSTR lpGroupName)
|
|
{
|
|
PLIST_ENTRY GroupEntry;
|
|
PSERVICE_GROUP lpGroup;
|
|
|
|
DPRINT("ScmSetServiceGroup(%S)\n", lpGroupName);
|
|
|
|
if (lpService->lpGroup != NULL)
|
|
{
|
|
ASSERT(lpService->lpGroup->dwRefCount != 0);
|
|
ASSERT(lpService->lpGroup->dwRefCount == (DWORD)-1 ||
|
|
lpService->lpGroup->dwRefCount < 10000);
|
|
if (lpService->lpGroup->dwRefCount != (DWORD)-1)
|
|
{
|
|
lpService->lpGroup->dwRefCount--;
|
|
if (lpService->lpGroup->dwRefCount == 0)
|
|
{
|
|
ASSERT(lpService->lpGroup->TagCount == 0);
|
|
ASSERT(lpService->lpGroup->TagArray == NULL);
|
|
RemoveEntryList(&lpService->lpGroup->GroupListEntry);
|
|
HeapFree(GetProcessHeap(), 0, lpService->lpGroup);
|
|
lpService->lpGroup = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (lpGroupName == NULL)
|
|
return ERROR_SUCCESS;
|
|
|
|
GroupEntry = GroupListHead.Flink;
|
|
while (GroupEntry != &GroupListHead)
|
|
{
|
|
lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
|
|
|
if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
|
|
{
|
|
lpService->lpGroup = lpGroup;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
GroupEntry = GroupEntry->Flink;
|
|
}
|
|
|
|
GroupEntry = UnknownGroupListHead.Flink;
|
|
while (GroupEntry != &UnknownGroupListHead)
|
|
{
|
|
lpGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
|
|
|
|
if (!_wcsicmp(lpGroup->lpGroupName, lpGroupName))
|
|
{
|
|
lpGroup->dwRefCount++;
|
|
lpService->lpGroup = lpGroup;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
GroupEntry = GroupEntry->Flink;
|
|
}
|
|
|
|
lpGroup = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof(SERVICE_GROUP) + ((wcslen(lpGroupName) + 1)* sizeof(WCHAR)));
|
|
if (lpGroup == NULL)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
wcscpy(lpGroup->szGroupName, lpGroupName);
|
|
lpGroup->lpGroupName = lpGroup->szGroupName;
|
|
lpGroup->dwRefCount = 1;
|
|
lpService->lpGroup = lpGroup;
|
|
|
|
InsertTailList(&UnknownGroupListHead,
|
|
&lpGroup->GroupListEntry);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
static NTSTATUS WINAPI
|
|
CreateGroupOrderListRoutine(PWSTR ValueName,
|
|
ULONG ValueType,
|
|
PVOID ValueData,
|
|
ULONG ValueLength,
|
|
PVOID Context,
|
|
PVOID EntryContext)
|
|
{
|
|
PSERVICE_GROUP Group;
|
|
|
|
DPRINT("CreateGroupOrderListRoutine(%S, %x, %p, %x, %p, %p)\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 WINAPI
|
|
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)
|
|
{
|
|
DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
|
|
|
|
Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof(SERVICE_GROUP) + ((wcslen((const wchar_t*) ValueData) + 1) * sizeof(WCHAR)));
|
|
if (Group == NULL)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
wcscpy(Group->szGroupName, (const wchar_t*) ValueData);
|
|
Group->lpGroupName = Group->szGroupName;
|
|
Group->dwRefCount = (DWORD)-1;
|
|
|
|
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 %lu %S\n", Status, Group->TagCount, (PWSTR)ValueData);
|
|
|
|
InsertTailList(&GroupListHead,
|
|
&Group->GroupListEntry);
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
DWORD
|
|
ScmCreateGroupList(VOID)
|
|
{
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
NTSTATUS Status;
|
|
|
|
InitializeListHead(&GroupListHead);
|
|
InitializeListHead(&UnknownGroupListHead);
|
|
|
|
/* Build group order list */
|
|
RtlZeroMemory(&QueryTable,
|
|
sizeof(QueryTable));
|
|
|
|
QueryTable[0].Name = L"List";
|
|
QueryTable[0].QueryRoutine = CreateGroupListRoutine;
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
|
|
L"ServiceGroupOrder",
|
|
QueryTable,
|
|
NULL,
|
|
NULL);
|
|
|
|
return RtlNtStatusToDosError(Status);
|
|
}
|
|
|
|
/* EOF */
|