mirror of
https://github.com/reactos/reactos.git
synced 2024-07-04 19:54:58 +00:00
SVN maintenance
svn path=/trunk/; revision=20492
This commit is contained in:
parent
d244063997
commit
840e249e37
|
@ -1,298 +1,298 @@
|
|||
/*
|
||||
* config.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
DWORD
|
||||
ScmOpenServiceKey(LPWSTR lpServiceName,
|
||||
REGSAM samDesired,
|
||||
PHKEY phKey)
|
||||
{
|
||||
HKEY hServicesKey = NULL;
|
||||
DWORD dwError;
|
||||
|
||||
*phKey = NULL;
|
||||
|
||||
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Services",
|
||||
0,
|
||||
KEY_READ,
|
||||
&hServicesKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegOpenKeyExW(hServicesKey,
|
||||
lpServiceName,
|
||||
0,
|
||||
samDesired,
|
||||
phKey);
|
||||
|
||||
RegCloseKey(hServicesKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmCreateServiceKey(LPWSTR lpServiceName,
|
||||
REGSAM samDesired,
|
||||
PHKEY phKey)
|
||||
{
|
||||
HKEY hServicesKey = NULL;
|
||||
DWORD dwDisposition;
|
||||
DWORD dwError;
|
||||
|
||||
*phKey = NULL;
|
||||
|
||||
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Services",
|
||||
0,
|
||||
KEY_READ | KEY_CREATE_SUB_KEY,
|
||||
&hServicesKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegCreateKeyExW(hServicesKey,
|
||||
lpServiceName,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
samDesired,
|
||||
NULL,
|
||||
phKey,
|
||||
&dwDisposition);
|
||||
#if 0
|
||||
if ((dwError == ERROR_SUCCESS) &&
|
||||
(dwDisposition == REG_OPENED_EXISTING_KEY))
|
||||
{
|
||||
RegCloseKey(*phKey);
|
||||
*phKey = NULL;
|
||||
dwError = ERROR_SERVICE_EXISTS;
|
||||
}
|
||||
#endif
|
||||
|
||||
RegCloseKey(hServicesKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DWORD
|
||||
ScmWriteDependencies(HKEY hServiceKey,
|
||||
LPWSTR lpDependencies,
|
||||
DWORD dwDependenciesLength)
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
DWORD dwGroupLength = 0;
|
||||
DWORD dwServiceLength = 0;
|
||||
DWORD dwLength;
|
||||
LPWSTR lpGroupDeps;
|
||||
LPWSTR lpServiceDeps;
|
||||
LPWSTR lpSrc;
|
||||
LPWSTR lpDst;
|
||||
|
||||
if (*lpDependencies == 0)
|
||||
{
|
||||
RegDeleteValue(hServiceKey,
|
||||
L"DependOnService");
|
||||
RegDeleteValue(hServiceKey,
|
||||
L"DependOnGroup");
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGroupDeps = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(dwDependenciesLength + 2) * sizeof(WCHAR));
|
||||
if (lpGroupDeps == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
lpSrc = lpDependencies;
|
||||
lpDst = lpGroupDeps;
|
||||
while (*lpSrc != 0)
|
||||
{
|
||||
dwLength = wcslen(lpSrc);
|
||||
if (*lpSrc == SC_GROUP_IDENTIFIERW)
|
||||
{
|
||||
lpSrc++;
|
||||
dwGroupLength += dwLength;
|
||||
wcscpy(lpDst, lpSrc);
|
||||
lpDst = lpDst + dwLength;
|
||||
}
|
||||
|
||||
lpSrc = lpSrc + dwLength;
|
||||
}
|
||||
*lpDst = 0;
|
||||
lpDst++;
|
||||
dwGroupLength++;
|
||||
|
||||
lpSrc = lpDependencies;
|
||||
lpServiceDeps = lpDst;
|
||||
while (*lpSrc != 0)
|
||||
{
|
||||
dwLength = wcslen(lpSrc) + 1;
|
||||
if (*lpSrc != SC_GROUP_IDENTIFIERW)
|
||||
{
|
||||
dwServiceLength += dwLength;
|
||||
wcscpy(lpDst, lpSrc);
|
||||
lpDst = lpDst + dwLength;
|
||||
}
|
||||
|
||||
lpSrc = lpSrc + dwLength;
|
||||
}
|
||||
*lpDst = 0;
|
||||
dwServiceLength++;
|
||||
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DependOnGroup",
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(LPBYTE)lpGroupDeps,
|
||||
dwGroupLength * sizeof(WCHAR));
|
||||
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DependOnService",
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(LPBYTE)lpServiceDeps,
|
||||
dwServiceLength * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, lpGroupDeps);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmMarkServiceForDelete(PSERVICE pService)
|
||||
{
|
||||
HKEY hServiceKey = NULL;
|
||||
DWORD dwValue = 1;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("ScmMarkServiceForDelete() called\n");
|
||||
|
||||
dwError = ScmOpenServiceKey(pService->lpServiceName,
|
||||
KEY_WRITE,
|
||||
&hServiceKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DeleteFlag",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&dwValue,
|
||||
sizeof(DWORD));
|
||||
|
||||
RegCloseKey(hServiceKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ScmIsDeleteFlagSet(HKEY hServiceKey)
|
||||
{
|
||||
DWORD dwError;
|
||||
DWORD dwType;
|
||||
DWORD dwFlag;
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
L"DeleteFlag",
|
||||
0,
|
||||
&dwType,
|
||||
(LPBYTE)&dwFlag,
|
||||
&dwSize);
|
||||
|
||||
return (dwError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmReadString(HKEY hServiceKey,
|
||||
LPWSTR lpValueName,
|
||||
LPWSTR *lpValue)
|
||||
{
|
||||
DWORD dwError;
|
||||
DWORD dwSize;
|
||||
DWORD dwType;
|
||||
DWORD dwSizeNeeded;
|
||||
LPWSTR expanded = NULL;
|
||||
LPWSTR ptr = NULL;
|
||||
|
||||
*lpValue = NULL;
|
||||
|
||||
dwSize = 0;
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
lpValueName,
|
||||
0,
|
||||
&dwType,
|
||||
NULL,
|
||||
&dwSize);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
ptr = HeapAlloc(GetProcessHeap(), 0, dwSize);
|
||||
if (ptr == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
lpValueName,
|
||||
0,
|
||||
&dwType,
|
||||
(LPBYTE)ptr,
|
||||
&dwSize);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (dwType == REG_EXPAND_SZ)
|
||||
{
|
||||
/* Expand the value... */
|
||||
dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0);
|
||||
if (dwSizeNeeded == 0)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR));
|
||||
if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded))
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
*lpValue = expanded;
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lpValue = ptr;
|
||||
}
|
||||
|
||||
done:;
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
HeapFree(GetProcessHeap(), 0, expanded);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
/*
|
||||
* config.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
DWORD
|
||||
ScmOpenServiceKey(LPWSTR lpServiceName,
|
||||
REGSAM samDesired,
|
||||
PHKEY phKey)
|
||||
{
|
||||
HKEY hServicesKey = NULL;
|
||||
DWORD dwError;
|
||||
|
||||
*phKey = NULL;
|
||||
|
||||
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Services",
|
||||
0,
|
||||
KEY_READ,
|
||||
&hServicesKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegOpenKeyExW(hServicesKey,
|
||||
lpServiceName,
|
||||
0,
|
||||
samDesired,
|
||||
phKey);
|
||||
|
||||
RegCloseKey(hServicesKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmCreateServiceKey(LPWSTR lpServiceName,
|
||||
REGSAM samDesired,
|
||||
PHKEY phKey)
|
||||
{
|
||||
HKEY hServicesKey = NULL;
|
||||
DWORD dwDisposition;
|
||||
DWORD dwError;
|
||||
|
||||
*phKey = NULL;
|
||||
|
||||
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Services",
|
||||
0,
|
||||
KEY_READ | KEY_CREATE_SUB_KEY,
|
||||
&hServicesKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegCreateKeyExW(hServicesKey,
|
||||
lpServiceName,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
samDesired,
|
||||
NULL,
|
||||
phKey,
|
||||
&dwDisposition);
|
||||
#if 0
|
||||
if ((dwError == ERROR_SUCCESS) &&
|
||||
(dwDisposition == REG_OPENED_EXISTING_KEY))
|
||||
{
|
||||
RegCloseKey(*phKey);
|
||||
*phKey = NULL;
|
||||
dwError = ERROR_SERVICE_EXISTS;
|
||||
}
|
||||
#endif
|
||||
|
||||
RegCloseKey(hServicesKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DWORD
|
||||
ScmWriteDependencies(HKEY hServiceKey,
|
||||
LPWSTR lpDependencies,
|
||||
DWORD dwDependenciesLength)
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
DWORD dwGroupLength = 0;
|
||||
DWORD dwServiceLength = 0;
|
||||
DWORD dwLength;
|
||||
LPWSTR lpGroupDeps;
|
||||
LPWSTR lpServiceDeps;
|
||||
LPWSTR lpSrc;
|
||||
LPWSTR lpDst;
|
||||
|
||||
if (*lpDependencies == 0)
|
||||
{
|
||||
RegDeleteValue(hServiceKey,
|
||||
L"DependOnService");
|
||||
RegDeleteValue(hServiceKey,
|
||||
L"DependOnGroup");
|
||||
}
|
||||
else
|
||||
{
|
||||
lpGroupDeps = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(dwDependenciesLength + 2) * sizeof(WCHAR));
|
||||
if (lpGroupDeps == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
lpSrc = lpDependencies;
|
||||
lpDst = lpGroupDeps;
|
||||
while (*lpSrc != 0)
|
||||
{
|
||||
dwLength = wcslen(lpSrc);
|
||||
if (*lpSrc == SC_GROUP_IDENTIFIERW)
|
||||
{
|
||||
lpSrc++;
|
||||
dwGroupLength += dwLength;
|
||||
wcscpy(lpDst, lpSrc);
|
||||
lpDst = lpDst + dwLength;
|
||||
}
|
||||
|
||||
lpSrc = lpSrc + dwLength;
|
||||
}
|
||||
*lpDst = 0;
|
||||
lpDst++;
|
||||
dwGroupLength++;
|
||||
|
||||
lpSrc = lpDependencies;
|
||||
lpServiceDeps = lpDst;
|
||||
while (*lpSrc != 0)
|
||||
{
|
||||
dwLength = wcslen(lpSrc) + 1;
|
||||
if (*lpSrc != SC_GROUP_IDENTIFIERW)
|
||||
{
|
||||
dwServiceLength += dwLength;
|
||||
wcscpy(lpDst, lpSrc);
|
||||
lpDst = lpDst + dwLength;
|
||||
}
|
||||
|
||||
lpSrc = lpSrc + dwLength;
|
||||
}
|
||||
*lpDst = 0;
|
||||
dwServiceLength++;
|
||||
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DependOnGroup",
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(LPBYTE)lpGroupDeps,
|
||||
dwGroupLength * sizeof(WCHAR));
|
||||
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DependOnService",
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(LPBYTE)lpServiceDeps,
|
||||
dwServiceLength * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, lpGroupDeps);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmMarkServiceForDelete(PSERVICE pService)
|
||||
{
|
||||
HKEY hServiceKey = NULL;
|
||||
DWORD dwValue = 1;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("ScmMarkServiceForDelete() called\n");
|
||||
|
||||
dwError = ScmOpenServiceKey(pService->lpServiceName,
|
||||
KEY_WRITE,
|
||||
&hServiceKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"DeleteFlag",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&dwValue,
|
||||
sizeof(DWORD));
|
||||
|
||||
RegCloseKey(hServiceKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ScmIsDeleteFlagSet(HKEY hServiceKey)
|
||||
{
|
||||
DWORD dwError;
|
||||
DWORD dwType;
|
||||
DWORD dwFlag;
|
||||
DWORD dwSize = sizeof(DWORD);
|
||||
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
L"DeleteFlag",
|
||||
0,
|
||||
&dwType,
|
||||
(LPBYTE)&dwFlag,
|
||||
&dwSize);
|
||||
|
||||
return (dwError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmReadString(HKEY hServiceKey,
|
||||
LPWSTR lpValueName,
|
||||
LPWSTR *lpValue)
|
||||
{
|
||||
DWORD dwError;
|
||||
DWORD dwSize;
|
||||
DWORD dwType;
|
||||
DWORD dwSizeNeeded;
|
||||
LPWSTR expanded = NULL;
|
||||
LPWSTR ptr = NULL;
|
||||
|
||||
*lpValue = NULL;
|
||||
|
||||
dwSize = 0;
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
lpValueName,
|
||||
0,
|
||||
&dwType,
|
||||
NULL,
|
||||
&dwSize);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
ptr = HeapAlloc(GetProcessHeap(), 0, dwSize);
|
||||
if (ptr == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
dwError = RegQueryValueExW(hServiceKey,
|
||||
lpValueName,
|
||||
0,
|
||||
&dwType,
|
||||
(LPBYTE)ptr,
|
||||
&dwSize);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (dwType == REG_EXPAND_SZ)
|
||||
{
|
||||
/* Expand the value... */
|
||||
dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0);
|
||||
if (dwSizeNeeded == 0)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR));
|
||||
if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded))
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
*lpValue = expanded;
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lpValue = ptr;
|
||||
}
|
||||
|
||||
done:;
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
HeapFree(GetProcessHeap(), 0, expanded);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
|
|
@ -1,253 +1,253 @@
|
|||
/*
|
||||
* driver.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
ScmLoadDriver(PSERVICE lpService)
|
||||
{
|
||||
WCHAR szDriverPath[MAX_PATH];
|
||||
UNICODE_STRING DriverPath;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Build the driver path */
|
||||
wcscpy(szDriverPath,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
wcscat(szDriverPath,
|
||||
lpService->lpServiceName);
|
||||
|
||||
RtlInitUnicodeString(&DriverPath,
|
||||
szDriverPath);
|
||||
|
||||
/* FIXME: Acquire privilege */
|
||||
|
||||
DPRINT(" Path: %wZ\n", &DriverPath);
|
||||
Status = NtLoadDriver(&DriverPath);
|
||||
|
||||
/* FIXME: Release privilege */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmUnloadDriver(PSERVICE lpService)
|
||||
{
|
||||
WCHAR szDriverPath[MAX_PATH];
|
||||
UNICODE_STRING DriverPath;
|
||||
NTSTATUS Status;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
/* Build the driver path */
|
||||
wcscpy(szDriverPath,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
wcscat(szDriverPath,
|
||||
lpService->lpServiceName);
|
||||
|
||||
RtlInitUnicodeString(&DriverPath,
|
||||
szDriverPath);
|
||||
|
||||
/* FIXME: Acquire privilege */
|
||||
|
||||
Status = NtUnloadDriver(&DriverPath);
|
||||
|
||||
/* FIXME: Release privilege */
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
dwError = RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmGetDriverStatus(PSERVICE lpService,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirName;
|
||||
HANDLE DirHandle;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
POBJECT_DIRECTORY_INFORMATION DirInfo;
|
||||
ULONG BufferLength;
|
||||
ULONG DataLength;
|
||||
ULONG Index;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
BOOLEAN bFound = FALSE;
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() called\n");
|
||||
|
||||
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
|
||||
|
||||
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\Driver");
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\FileSystem");
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenDirectoryObject(&DirHandle,
|
||||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenDirectoryObject() failed!\n");
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||
2 * MAX_PATH * sizeof(WCHAR);
|
||||
DirInfo = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferLength);
|
||||
|
||||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
Status = NtQueryDirectoryObject(DirHandle,
|
||||
DirInfo,
|
||||
BufferLength,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&Index,
|
||||
&DataLength);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
DPRINT("No more services\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
|
||||
if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
|
||||
{
|
||||
DPRINT1("Found: '%S' '%wZ'\n",
|
||||
lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
bFound = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
DirInfo);
|
||||
NtClose(DirHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Status: %lx\n", Status);
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
if ((bFound == TRUE) &&
|
||||
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
|
||||
{
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
|
||||
{
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||
|
||||
if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
else
|
||||
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
if (lpServiceStatus != NULL)
|
||||
{
|
||||
memcpy(lpServiceStatus,
|
||||
&lpService->Status,
|
||||
sizeof(SERVICE_STATUS));
|
||||
}
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmControlDriver(PSERVICE lpService,
|
||||
DWORD dwControl,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("ScmControlDriver() called\n");
|
||||
|
||||
switch (dwControl)
|
||||
{
|
||||
case SERVICE_CONTROL_STOP:
|
||||
if (lpService->Status.dwCurrentState != SERVICE_RUNNING)
|
||||
{
|
||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dwError = ScmUnloadDriver(lpService);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||
}
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
dwError = ScmGetDriverStatus(lpService,
|
||||
lpServiceStatus);
|
||||
break;
|
||||
|
||||
default:
|
||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
||||
}
|
||||
|
||||
done:;
|
||||
DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
/*
|
||||
* driver.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
ScmLoadDriver(PSERVICE lpService)
|
||||
{
|
||||
WCHAR szDriverPath[MAX_PATH];
|
||||
UNICODE_STRING DriverPath;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Build the driver path */
|
||||
wcscpy(szDriverPath,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
wcscat(szDriverPath,
|
||||
lpService->lpServiceName);
|
||||
|
||||
RtlInitUnicodeString(&DriverPath,
|
||||
szDriverPath);
|
||||
|
||||
/* FIXME: Acquire privilege */
|
||||
|
||||
DPRINT(" Path: %wZ\n", &DriverPath);
|
||||
Status = NtLoadDriver(&DriverPath);
|
||||
|
||||
/* FIXME: Release privilege */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmUnloadDriver(PSERVICE lpService)
|
||||
{
|
||||
WCHAR szDriverPath[MAX_PATH];
|
||||
UNICODE_STRING DriverPath;
|
||||
NTSTATUS Status;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
/* Build the driver path */
|
||||
wcscpy(szDriverPath,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
wcscat(szDriverPath,
|
||||
lpService->lpServiceName);
|
||||
|
||||
RtlInitUnicodeString(&DriverPath,
|
||||
szDriverPath);
|
||||
|
||||
/* FIXME: Acquire privilege */
|
||||
|
||||
Status = NtUnloadDriver(&DriverPath);
|
||||
|
||||
/* FIXME: Release privilege */
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
dwError = RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmGetDriverStatus(PSERVICE lpService,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirName;
|
||||
HANDLE DirHandle;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
POBJECT_DIRECTORY_INFORMATION DirInfo;
|
||||
ULONG BufferLength;
|
||||
ULONG DataLength;
|
||||
ULONG Index;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
BOOLEAN bFound = FALSE;
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() called\n");
|
||||
|
||||
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
|
||||
|
||||
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\Driver");
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\FileSystem");
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenDirectoryObject(&DirHandle,
|
||||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenDirectoryObject() failed!\n");
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||
2 * MAX_PATH * sizeof(WCHAR);
|
||||
DirInfo = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferLength);
|
||||
|
||||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
Status = NtQueryDirectoryObject(DirHandle,
|
||||
DirInfo,
|
||||
BufferLength,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&Index,
|
||||
&DataLength);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
DPRINT("No more services\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
|
||||
if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
|
||||
{
|
||||
DPRINT1("Found: '%S' '%wZ'\n",
|
||||
lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
bFound = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
DirInfo);
|
||||
NtClose(DirHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Status: %lx\n", Status);
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
if ((bFound == TRUE) &&
|
||||
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
|
||||
{
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
|
||||
{
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||
|
||||
if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
else
|
||||
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
if (lpServiceStatus != NULL)
|
||||
{
|
||||
memcpy(lpServiceStatus,
|
||||
&lpService->Status,
|
||||
sizeof(SERVICE_STATUS));
|
||||
}
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmControlDriver(PSERVICE lpService,
|
||||
DWORD dwControl,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("ScmControlDriver() called\n");
|
||||
|
||||
switch (dwControl)
|
||||
{
|
||||
case SERVICE_CONTROL_STOP:
|
||||
if (lpService->Status.dwCurrentState != SERVICE_RUNNING)
|
||||
{
|
||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dwError = ScmUnloadDriver(lpService);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||
}
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
dwError = ScmGetDriverStatus(lpService,
|
||||
lpServiceStatus);
|
||||
break;
|
||||
|
||||
default:
|
||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
||||
}
|
||||
|
||||
done:;
|
||||
DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,140 +1,140 @@
|
|||
/*
|
||||
* groupdb.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LIST_ENTRY GroupListHead;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
CreateGroupOrderListRoutine(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
|
||||
|
||||
Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));
|
||||
if (Group == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
wcscpy(Group->szGroupName, 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 %d %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);
|
||||
|
||||
/* 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 */
|
||||
/*
|
||||
* groupdb.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LIST_ENTRY GroupListHead;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
CreateGroupOrderListRoutine(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
|
||||
|
||||
Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));
|
||||
if (Group == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
wcscpy(Group->szGroupName, 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 %d %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);
|
||||
|
||||
/* 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 */
|
||||
|
|
Loading…
Reference in a new issue