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 * config.c
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include "services.h" #include "services.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
DWORD DWORD
ScmOpenServiceKey(LPWSTR lpServiceName, ScmOpenServiceKey(LPWSTR lpServiceName,
REGSAM samDesired, REGSAM samDesired,
PHKEY phKey) PHKEY phKey)
{ {
HKEY hServicesKey = NULL; HKEY hServicesKey = NULL;
DWORD dwError; DWORD dwError;
*phKey = NULL; *phKey = NULL;
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services", L"System\\CurrentControlSet\\Services",
0, 0,
KEY_READ, KEY_READ,
&hServicesKey); &hServicesKey);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
return dwError; return dwError;
dwError = RegOpenKeyExW(hServicesKey, dwError = RegOpenKeyExW(hServicesKey,
lpServiceName, lpServiceName,
0, 0,
samDesired, samDesired,
phKey); phKey);
RegCloseKey(hServicesKey); RegCloseKey(hServicesKey);
return dwError; return dwError;
} }
DWORD DWORD
ScmCreateServiceKey(LPWSTR lpServiceName, ScmCreateServiceKey(LPWSTR lpServiceName,
REGSAM samDesired, REGSAM samDesired,
PHKEY phKey) PHKEY phKey)
{ {
HKEY hServicesKey = NULL; HKEY hServicesKey = NULL;
DWORD dwDisposition; DWORD dwDisposition;
DWORD dwError; DWORD dwError;
*phKey = NULL; *phKey = NULL;
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services", L"System\\CurrentControlSet\\Services",
0, 0,
KEY_READ | KEY_CREATE_SUB_KEY, KEY_READ | KEY_CREATE_SUB_KEY,
&hServicesKey); &hServicesKey);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
return dwError; return dwError;
dwError = RegCreateKeyExW(hServicesKey, dwError = RegCreateKeyExW(hServicesKey,
lpServiceName, lpServiceName,
0, 0,
NULL, NULL,
REG_OPTION_NON_VOLATILE, REG_OPTION_NON_VOLATILE,
samDesired, samDesired,
NULL, NULL,
phKey, phKey,
&dwDisposition); &dwDisposition);
#if 0 #if 0
if ((dwError == ERROR_SUCCESS) && if ((dwError == ERROR_SUCCESS) &&
(dwDisposition == REG_OPENED_EXISTING_KEY)) (dwDisposition == REG_OPENED_EXISTING_KEY))
{ {
RegCloseKey(*phKey); RegCloseKey(*phKey);
*phKey = NULL; *phKey = NULL;
dwError = ERROR_SERVICE_EXISTS; dwError = ERROR_SERVICE_EXISTS;
} }
#endif #endif
RegCloseKey(hServicesKey); RegCloseKey(hServicesKey);
return dwError; return dwError;
} }
DWORD DWORD
ScmWriteDependencies(HKEY hServiceKey, ScmWriteDependencies(HKEY hServiceKey,
LPWSTR lpDependencies, LPWSTR lpDependencies,
DWORD dwDependenciesLength) DWORD dwDependenciesLength)
{ {
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
DWORD dwGroupLength = 0; DWORD dwGroupLength = 0;
DWORD dwServiceLength = 0; DWORD dwServiceLength = 0;
DWORD dwLength; DWORD dwLength;
LPWSTR lpGroupDeps; LPWSTR lpGroupDeps;
LPWSTR lpServiceDeps; LPWSTR lpServiceDeps;
LPWSTR lpSrc; LPWSTR lpSrc;
LPWSTR lpDst; LPWSTR lpDst;
if (*lpDependencies == 0) if (*lpDependencies == 0)
{ {
RegDeleteValue(hServiceKey, RegDeleteValue(hServiceKey,
L"DependOnService"); L"DependOnService");
RegDeleteValue(hServiceKey, RegDeleteValue(hServiceKey,
L"DependOnGroup"); L"DependOnGroup");
} }
else else
{ {
lpGroupDeps = HeapAlloc(GetProcessHeap(), lpGroupDeps = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
(dwDependenciesLength + 2) * sizeof(WCHAR)); (dwDependenciesLength + 2) * sizeof(WCHAR));
if (lpGroupDeps == NULL) if (lpGroupDeps == NULL)
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
lpSrc = lpDependencies; lpSrc = lpDependencies;
lpDst = lpGroupDeps; lpDst = lpGroupDeps;
while (*lpSrc != 0) while (*lpSrc != 0)
{ {
dwLength = wcslen(lpSrc); dwLength = wcslen(lpSrc);
if (*lpSrc == SC_GROUP_IDENTIFIERW) if (*lpSrc == SC_GROUP_IDENTIFIERW)
{ {
lpSrc++; lpSrc++;
dwGroupLength += dwLength; dwGroupLength += dwLength;
wcscpy(lpDst, lpSrc); wcscpy(lpDst, lpSrc);
lpDst = lpDst + dwLength; lpDst = lpDst + dwLength;
} }
lpSrc = lpSrc + dwLength; lpSrc = lpSrc + dwLength;
} }
*lpDst = 0; *lpDst = 0;
lpDst++; lpDst++;
dwGroupLength++; dwGroupLength++;
lpSrc = lpDependencies; lpSrc = lpDependencies;
lpServiceDeps = lpDst; lpServiceDeps = lpDst;
while (*lpSrc != 0) while (*lpSrc != 0)
{ {
dwLength = wcslen(lpSrc) + 1; dwLength = wcslen(lpSrc) + 1;
if (*lpSrc != SC_GROUP_IDENTIFIERW) if (*lpSrc != SC_GROUP_IDENTIFIERW)
{ {
dwServiceLength += dwLength; dwServiceLength += dwLength;
wcscpy(lpDst, lpSrc); wcscpy(lpDst, lpSrc);
lpDst = lpDst + dwLength; lpDst = lpDst + dwLength;
} }
lpSrc = lpSrc + dwLength; lpSrc = lpSrc + dwLength;
} }
*lpDst = 0; *lpDst = 0;
dwServiceLength++; dwServiceLength++;
dwError = RegSetValueExW(hServiceKey, dwError = RegSetValueExW(hServiceKey,
L"DependOnGroup", L"DependOnGroup",
0, 0,
REG_MULTI_SZ, REG_MULTI_SZ,
(LPBYTE)lpGroupDeps, (LPBYTE)lpGroupDeps,
dwGroupLength * sizeof(WCHAR)); dwGroupLength * sizeof(WCHAR));
if (dwError == ERROR_SUCCESS) if (dwError == ERROR_SUCCESS)
{ {
dwError = RegSetValueExW(hServiceKey, dwError = RegSetValueExW(hServiceKey,
L"DependOnService", L"DependOnService",
0, 0,
REG_MULTI_SZ, REG_MULTI_SZ,
(LPBYTE)lpServiceDeps, (LPBYTE)lpServiceDeps,
dwServiceLength * sizeof(WCHAR)); dwServiceLength * sizeof(WCHAR));
} }
HeapFree(GetProcessHeap(), 0, lpGroupDeps); HeapFree(GetProcessHeap(), 0, lpGroupDeps);
} }
return dwError; return dwError;
} }
DWORD DWORD
ScmMarkServiceForDelete(PSERVICE pService) ScmMarkServiceForDelete(PSERVICE pService)
{ {
HKEY hServiceKey = NULL; HKEY hServiceKey = NULL;
DWORD dwValue = 1; DWORD dwValue = 1;
DWORD dwError; DWORD dwError;
DPRINT("ScmMarkServiceForDelete() called\n"); DPRINT("ScmMarkServiceForDelete() called\n");
dwError = ScmOpenServiceKey(pService->lpServiceName, dwError = ScmOpenServiceKey(pService->lpServiceName,
KEY_WRITE, KEY_WRITE,
&hServiceKey); &hServiceKey);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
return dwError; return dwError;
dwError = RegSetValueExW(hServiceKey, dwError = RegSetValueExW(hServiceKey,
L"DeleteFlag", L"DeleteFlag",
0, 0,
REG_DWORD, REG_DWORD,
(LPBYTE)&dwValue, (LPBYTE)&dwValue,
sizeof(DWORD)); sizeof(DWORD));
RegCloseKey(hServiceKey); RegCloseKey(hServiceKey);
return dwError; return dwError;
} }
BOOL BOOL
ScmIsDeleteFlagSet(HKEY hServiceKey) ScmIsDeleteFlagSet(HKEY hServiceKey)
{ {
DWORD dwError; DWORD dwError;
DWORD dwType; DWORD dwType;
DWORD dwFlag; DWORD dwFlag;
DWORD dwSize = sizeof(DWORD); DWORD dwSize = sizeof(DWORD);
dwError = RegQueryValueExW(hServiceKey, dwError = RegQueryValueExW(hServiceKey,
L"DeleteFlag", L"DeleteFlag",
0, 0,
&dwType, &dwType,
(LPBYTE)&dwFlag, (LPBYTE)&dwFlag,
&dwSize); &dwSize);
return (dwError == ERROR_SUCCESS); return (dwError == ERROR_SUCCESS);
} }
DWORD DWORD
ScmReadString(HKEY hServiceKey, ScmReadString(HKEY hServiceKey,
LPWSTR lpValueName, LPWSTR lpValueName,
LPWSTR *lpValue) LPWSTR *lpValue)
{ {
DWORD dwError; DWORD dwError;
DWORD dwSize; DWORD dwSize;
DWORD dwType; DWORD dwType;
DWORD dwSizeNeeded; DWORD dwSizeNeeded;
LPWSTR expanded = NULL; LPWSTR expanded = NULL;
LPWSTR ptr = NULL; LPWSTR ptr = NULL;
*lpValue = NULL; *lpValue = NULL;
dwSize = 0; dwSize = 0;
dwError = RegQueryValueExW(hServiceKey, dwError = RegQueryValueExW(hServiceKey,
lpValueName, lpValueName,
0, 0,
&dwType, &dwType,
NULL, NULL,
&dwSize); &dwSize);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
return dwError; return dwError;
ptr = HeapAlloc(GetProcessHeap(), 0, dwSize); ptr = HeapAlloc(GetProcessHeap(), 0, dwSize);
if (ptr == NULL) if (ptr == NULL)
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
dwError = RegQueryValueExW(hServiceKey, dwError = RegQueryValueExW(hServiceKey,
lpValueName, lpValueName,
0, 0,
&dwType, &dwType,
(LPBYTE)ptr, (LPBYTE)ptr,
&dwSize); &dwSize);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
goto done; goto done;
if (dwType == REG_EXPAND_SZ) if (dwType == REG_EXPAND_SZ)
{ {
/* Expand the value... */ /* Expand the value... */
dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0); dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0);
if (dwSizeNeeded == 0) if (dwSizeNeeded == 0)
{ {
dwError = GetLastError(); dwError = GetLastError();
goto done; goto done;
} }
expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR)); expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR));
if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded)) if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded))
{ {
dwError = GetLastError(); dwError = GetLastError();
goto done; goto done;
} }
*lpValue = expanded; *lpValue = expanded;
HeapFree(GetProcessHeap(), 0, ptr); HeapFree(GetProcessHeap(), 0, ptr);
dwError = ERROR_SUCCESS; dwError = ERROR_SUCCESS;
} }
else else
{ {
*lpValue = ptr; *lpValue = ptr;
} }
done:; done:;
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
{ {
HeapFree(GetProcessHeap(), 0, ptr); HeapFree(GetProcessHeap(), 0, ptr);
HeapFree(GetProcessHeap(), 0, expanded); HeapFree(GetProcessHeap(), 0, expanded);
} }
return dwError; return dwError;
} }
/* EOF */ /* EOF */

View file

@ -1,253 +1,253 @@
/* /*
* driver.c * driver.c
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include "services.h" #include "services.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS NTSTATUS
ScmLoadDriver(PSERVICE lpService) ScmLoadDriver(PSERVICE lpService)
{ {
WCHAR szDriverPath[MAX_PATH]; WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath; UNICODE_STRING DriverPath;
NTSTATUS Status; NTSTATUS Status;
/* Build the driver path */ /* Build the driver path */
wcscpy(szDriverPath, wcscpy(szDriverPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
wcscat(szDriverPath, wcscat(szDriverPath,
lpService->lpServiceName); lpService->lpServiceName);
RtlInitUnicodeString(&DriverPath, RtlInitUnicodeString(&DriverPath,
szDriverPath); szDriverPath);
/* FIXME: Acquire privilege */ /* FIXME: Acquire privilege */
DPRINT(" Path: %wZ\n", &DriverPath); DPRINT(" Path: %wZ\n", &DriverPath);
Status = NtLoadDriver(&DriverPath); Status = NtLoadDriver(&DriverPath);
/* FIXME: Release privilege */ /* FIXME: Release privilege */
return Status; return Status;
} }
DWORD DWORD
ScmUnloadDriver(PSERVICE lpService) ScmUnloadDriver(PSERVICE lpService)
{ {
WCHAR szDriverPath[MAX_PATH]; WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath; UNICODE_STRING DriverPath;
NTSTATUS Status; NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */ /* Build the driver path */
wcscpy(szDriverPath, wcscpy(szDriverPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
wcscat(szDriverPath, wcscat(szDriverPath,
lpService->lpServiceName); lpService->lpServiceName);
RtlInitUnicodeString(&DriverPath, RtlInitUnicodeString(&DriverPath,
szDriverPath); szDriverPath);
/* FIXME: Acquire privilege */ /* FIXME: Acquire privilege */
Status = NtUnloadDriver(&DriverPath); Status = NtUnloadDriver(&DriverPath);
/* FIXME: Release privilege */ /* FIXME: Release privilege */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
dwError = RtlNtStatusToDosError(Status); dwError = RtlNtStatusToDosError(Status);
} }
return dwError; return dwError;
} }
DWORD DWORD
ScmGetDriverStatus(PSERVICE lpService, ScmGetDriverStatus(PSERVICE lpService,
LPSERVICE_STATUS lpServiceStatus) LPSERVICE_STATUS lpServiceStatus)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirName; UNICODE_STRING DirName;
HANDLE DirHandle; HANDLE DirHandle;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
POBJECT_DIRECTORY_INFORMATION DirInfo; POBJECT_DIRECTORY_INFORMATION DirInfo;
ULONG BufferLength; ULONG BufferLength;
ULONG DataLength; ULONG DataLength;
ULONG Index; ULONG Index;
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
BOOLEAN bFound = FALSE; BOOLEAN bFound = FALSE;
DPRINT1("ScmGetDriverStatus() called\n"); DPRINT1("ScmGetDriverStatus() called\n");
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS)); memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER) if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
{ {
RtlInitUnicodeString(&DirName, RtlInitUnicodeString(&DirName,
L"\\Driver"); L"\\Driver");
} }
else else
{ {
RtlInitUnicodeString(&DirName, RtlInitUnicodeString(&DirName,
L"\\FileSystem"); L"\\FileSystem");
} }
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&DirName, &DirName,
0, 0,
NULL, NULL,
NULL); NULL);
Status = NtOpenDirectoryObject(&DirHandle, Status = NtOpenDirectoryObject(&DirHandle,
DIRECTORY_QUERY | DIRECTORY_TRAVERSE, DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
&ObjectAttributes); &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NtOpenDirectoryObject() failed!\n"); DPRINT1("NtOpenDirectoryObject() failed!\n");
return RtlNtStatusToDosError(Status); return RtlNtStatusToDosError(Status);
} }
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) + BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
2 * MAX_PATH * sizeof(WCHAR); 2 * MAX_PATH * sizeof(WCHAR);
DirInfo = HeapAlloc(GetProcessHeap(), DirInfo = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
BufferLength); BufferLength);
Index = 0; Index = 0;
while (TRUE) while (TRUE)
{ {
Status = NtQueryDirectoryObject(DirHandle, Status = NtQueryDirectoryObject(DirHandle,
DirInfo, DirInfo,
BufferLength, BufferLength,
TRUE, TRUE,
FALSE, FALSE,
&Index, &Index,
&DataLength); &DataLength);
if (Status == STATUS_NO_MORE_ENTRIES) if (Status == STATUS_NO_MORE_ENTRIES)
{ {
DPRINT("No more services\n"); DPRINT("No more services\n");
break; break;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
break; break;
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName); DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);
if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0) if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
{ {
DPRINT1("Found: '%S' '%wZ'\n", DPRINT1("Found: '%S' '%wZ'\n",
lpService->lpServiceName, &DirInfo->ObjectName); lpService->lpServiceName, &DirInfo->ObjectName);
bFound = TRUE; bFound = TRUE;
break; break;
} }
} }
HeapFree(GetProcessHeap(), HeapFree(GetProcessHeap(),
0, 0,
DirInfo); DirInfo);
NtClose(DirHandle); NtClose(DirHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Status: %lx\n", Status); DPRINT1("Status: %lx\n", Status);
return RtlNtStatusToDosError(Status); return RtlNtStatusToDosError(Status);
} }
if ((bFound == TRUE) && if ((bFound == TRUE) &&
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING)) (lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
{ {
if (lpService->Status.dwCurrentState == SERVICE_STOPPED) if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
{ {
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS; lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS; lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
lpService->Status.dwCheckPoint = 0; lpService->Status.dwCheckPoint = 0;
lpService->Status.dwWaitHint = 0; lpService->Status.dwWaitHint = 0;
lpService->Status.dwControlsAccepted = 0; lpService->Status.dwControlsAccepted = 0;
} }
else else
{ {
lpService->Status.dwCurrentState = SERVICE_RUNNING; lpService->Status.dwCurrentState = SERVICE_RUNNING;
lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP; lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED) if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS; lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
} }
} }
else else
{ {
lpService->Status.dwCurrentState = SERVICE_STOPPED; lpService->Status.dwCurrentState = SERVICE_STOPPED;
lpService->Status.dwControlsAccepted = 0; lpService->Status.dwControlsAccepted = 0;
lpService->Status.dwCheckPoint = 0; lpService->Status.dwCheckPoint = 0;
lpService->Status.dwWaitHint = 0; lpService->Status.dwWaitHint = 0;
if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING) if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS; lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
else else
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE; lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
} }
if (lpServiceStatus != NULL) if (lpServiceStatus != NULL)
{ {
memcpy(lpServiceStatus, memcpy(lpServiceStatus,
&lpService->Status, &lpService->Status,
sizeof(SERVICE_STATUS)); sizeof(SERVICE_STATUS));
} }
DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError); DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
DWORD DWORD
ScmControlDriver(PSERVICE lpService, ScmControlDriver(PSERVICE lpService,
DWORD dwControl, DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus) LPSERVICE_STATUS lpServiceStatus)
{ {
DWORD dwError; DWORD dwError;
DPRINT("ScmControlDriver() called\n"); DPRINT("ScmControlDriver() called\n");
switch (dwControl) switch (dwControl)
{ {
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
if (lpService->Status.dwCurrentState != SERVICE_RUNNING) if (lpService->Status.dwCurrentState != SERVICE_RUNNING)
{ {
dwError = ERROR_INVALID_SERVICE_CONTROL; dwError = ERROR_INVALID_SERVICE_CONTROL;
goto done; goto done;
} }
dwError = ScmUnloadDriver(lpService); dwError = ScmUnloadDriver(lpService);
if (dwError == ERROR_SUCCESS) if (dwError == ERROR_SUCCESS)
{ {
lpService->Status.dwControlsAccepted = 0; lpService->Status.dwControlsAccepted = 0;
lpService->Status.dwCurrentState = SERVICE_STOPPED; lpService->Status.dwCurrentState = SERVICE_STOPPED;
} }
break; break;
case SERVICE_CONTROL_INTERROGATE: case SERVICE_CONTROL_INTERROGATE:
dwError = ScmGetDriverStatus(lpService, dwError = ScmGetDriverStatus(lpService,
lpServiceStatus); lpServiceStatus);
break; break;
default: default:
dwError = ERROR_INVALID_SERVICE_CONTROL; dwError = ERROR_INVALID_SERVICE_CONTROL;
} }
done:; done:;
DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError); DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
return dwError; return dwError;
} }
/* EOF */ /* EOF */

View file

@ -1,140 +1,140 @@
/* /*
* groupdb.c * groupdb.c
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include "services.h" #include "services.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
LIST_ENTRY GroupListHead; LIST_ENTRY GroupListHead;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static NTSTATUS STDCALL static NTSTATUS STDCALL
CreateGroupOrderListRoutine(PWSTR ValueName, CreateGroupOrderListRoutine(PWSTR ValueName,
ULONG ValueType, ULONG ValueType,
PVOID ValueData, PVOID ValueData,
ULONG ValueLength, ULONG ValueLength,
PVOID Context, PVOID Context,
PVOID EntryContext) PVOID EntryContext)
{ {
PSERVICE_GROUP Group; PSERVICE_GROUP Group;
DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n", DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",
ValueName, ValueType, ValueData, ValueLength, Context, EntryContext); ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
if (ValueType == REG_BINARY && if (ValueType == REG_BINARY &&
ValueData != NULL && ValueData != NULL &&
ValueLength >= sizeof(DWORD) && ValueLength >= sizeof(DWORD) &&
ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD)) ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))
{ {
Group = (PSERVICE_GROUP)Context; Group = (PSERVICE_GROUP)Context;
Group->TagCount = ((PULONG)ValueData)[0]; Group->TagCount = ((PULONG)ValueData)[0];
if (Group->TagCount > 0) if (Group->TagCount > 0)
{ {
if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD)) if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))
{ {
Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(), Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
Group->TagCount * sizeof(DWORD)); Group->TagCount * sizeof(DWORD));
if (Group->TagArray == NULL) if (Group->TagArray == NULL)
{ {
Group->TagCount = 0; Group->TagCount = 0;
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlCopyMemory(Group->TagArray, RtlCopyMemory(Group->TagArray,
(PULONG)ValueData + 1, (PULONG)ValueData + 1,
Group->TagCount * sizeof(DWORD)); Group->TagCount * sizeof(DWORD));
} }
else else
{ {
Group->TagCount = 0; Group->TagCount = 0;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
} }
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS STDCALL static NTSTATUS STDCALL
CreateGroupListRoutine(PWSTR ValueName, CreateGroupListRoutine(PWSTR ValueName,
ULONG ValueType, ULONG ValueType,
PVOID ValueData, PVOID ValueData,
ULONG ValueLength, ULONG ValueLength,
PVOID Context, PVOID Context,
PVOID EntryContext) PVOID EntryContext)
{ {
PSERVICE_GROUP Group; PSERVICE_GROUP Group;
RTL_QUERY_REGISTRY_TABLE QueryTable[2]; RTL_QUERY_REGISTRY_TABLE QueryTable[2];
NTSTATUS Status; NTSTATUS Status;
if (ValueType == REG_SZ) if (ValueType == REG_SZ)
{ {
DPRINT("Data: '%S'\n", (PWCHAR)ValueData); DPRINT("Data: '%S'\n", (PWCHAR)ValueData);
Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(), Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR))); sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));
if (Group == NULL) if (Group == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
wcscpy(Group->szGroupName, ValueData); wcscpy(Group->szGroupName, ValueData);
Group->lpGroupName = Group->szGroupName; Group->lpGroupName = Group->szGroupName;
Group->dwRefCount = (DWORD)-1; Group->dwRefCount = (DWORD)-1;
RtlZeroMemory(&QueryTable, sizeof(QueryTable)); RtlZeroMemory(&QueryTable, sizeof(QueryTable));
QueryTable[0].Name = (PWSTR)ValueData; QueryTable[0].Name = (PWSTR)ValueData;
QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine; QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
L"GroupOrderList", L"GroupOrderList",
QueryTable, QueryTable,
(PVOID)Group, (PVOID)Group,
NULL); NULL);
DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData); DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
InsertTailList(&GroupListHead, InsertTailList(&GroupListHead,
&Group->GroupListEntry); &Group->GroupListEntry);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
DWORD DWORD
ScmCreateGroupList(VOID) ScmCreateGroupList(VOID)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[2]; RTL_QUERY_REGISTRY_TABLE QueryTable[2];
NTSTATUS Status; NTSTATUS Status;
InitializeListHead(&GroupListHead); InitializeListHead(&GroupListHead);
/* Build group order list */ /* Build group order list */
RtlZeroMemory(&QueryTable, RtlZeroMemory(&QueryTable,
sizeof(QueryTable)); sizeof(QueryTable));
QueryTable[0].Name = L"List"; QueryTable[0].Name = L"List";
QueryTable[0].QueryRoutine = CreateGroupListRoutine; QueryTable[0].QueryRoutine = CreateGroupListRoutine;
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
L"ServiceGroupOrder", L"ServiceGroupOrder",
QueryTable, QueryTable,
NULL, NULL,
NULL); NULL);
return RtlNtStatusToDosError(Status); return RtlNtStatusToDosError(Status);
} }
/* EOF */ /* EOF */