SVN maintenance

svn path=/trunk/; revision=20492
This commit is contained in:
Eric Kohl 2005-12-31 19:02:48 +00:00
parent d244063997
commit 840e249e37
3 changed files with 691 additions and 691 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */