-/*\r
- * config.c\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include "services.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-\r
-DWORD\r
-ScmOpenServiceKey(LPWSTR lpServiceName,\r
- REGSAM samDesired,\r
- PHKEY phKey)\r
-{\r
- HKEY hServicesKey = NULL;\r
- DWORD dwError;\r
-\r
- *phKey = NULL;\r
-\r
- dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,\r
- L"System\\CurrentControlSet\\Services",\r
- 0,\r
- KEY_READ,\r
- &hServicesKey);\r
- if (dwError != ERROR_SUCCESS)\r
- return dwError;\r
-\r
- dwError = RegOpenKeyExW(hServicesKey,\r
- lpServiceName,\r
- 0,\r
- samDesired,\r
- phKey);\r
-\r
- RegCloseKey(hServicesKey);\r
-\r
- return dwError;\r
-}\r
-\r
-\r
-DWORD\r
-ScmCreateServiceKey(LPWSTR lpServiceName,\r
- REGSAM samDesired,\r
- PHKEY phKey)\r
-{\r
- HKEY hServicesKey = NULL;\r
- DWORD dwDisposition;\r
- DWORD dwError;\r
-\r
- *phKey = NULL;\r
-\r
- dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,\r
- L"System\\CurrentControlSet\\Services",\r
- 0,\r
- KEY_READ | KEY_CREATE_SUB_KEY,\r
- &hServicesKey);\r
- if (dwError != ERROR_SUCCESS)\r
- return dwError;\r
-\r
- dwError = RegCreateKeyExW(hServicesKey,\r
- lpServiceName,\r
- 0,\r
- NULL,\r
- REG_OPTION_NON_VOLATILE,\r
- samDesired,\r
- NULL,\r
- phKey,\r
- &dwDisposition);\r
-#if 0\r
- if ((dwError == ERROR_SUCCESS) &&\r
- (dwDisposition == REG_OPENED_EXISTING_KEY))\r
- {\r
- RegCloseKey(*phKey);\r
- *phKey = NULL;\r
- dwError = ERROR_SERVICE_EXISTS;\r
- }\r
-#endif\r
-\r
- RegCloseKey(hServicesKey);\r
-\r
- return dwError;\r
-}\r
-\r
-\r
-\r
-DWORD\r
-ScmWriteDependencies(HKEY hServiceKey,\r
- LPWSTR lpDependencies,\r
- DWORD dwDependenciesLength)\r
-{\r
- DWORD dwError = ERROR_SUCCESS;\r
- DWORD dwGroupLength = 0;\r
- DWORD dwServiceLength = 0;\r
- DWORD dwLength;\r
- LPWSTR lpGroupDeps;\r
- LPWSTR lpServiceDeps;\r
- LPWSTR lpSrc;\r
- LPWSTR lpDst;\r
-\r
- if (*lpDependencies == 0)\r
- {\r
- RegDeleteValue(hServiceKey,\r
- L"DependOnService");\r
- RegDeleteValue(hServiceKey,\r
- L"DependOnGroup");\r
- }\r
- else\r
- {\r
- lpGroupDeps = HeapAlloc(GetProcessHeap(),\r
- HEAP_ZERO_MEMORY,\r
- (dwDependenciesLength + 2) * sizeof(WCHAR));\r
- if (lpGroupDeps == NULL)\r
- return ERROR_NOT_ENOUGH_MEMORY;\r
-\r
- lpSrc = lpDependencies;\r
- lpDst = lpGroupDeps;\r
- while (*lpSrc != 0)\r
- {\r
- dwLength = wcslen(lpSrc);\r
- if (*lpSrc == SC_GROUP_IDENTIFIERW)\r
- {\r
- lpSrc++;\r
- dwGroupLength += dwLength;\r
- wcscpy(lpDst, lpSrc);\r
- lpDst = lpDst + dwLength;\r
- }\r
-\r
- lpSrc = lpSrc + dwLength;\r
- }\r
- *lpDst = 0;\r
- lpDst++;\r
- dwGroupLength++;\r
-\r
- lpSrc = lpDependencies;\r
- lpServiceDeps = lpDst;\r
- while (*lpSrc != 0)\r
- {\r
- dwLength = wcslen(lpSrc) + 1;\r
- if (*lpSrc != SC_GROUP_IDENTIFIERW)\r
- {\r
- dwServiceLength += dwLength;\r
- wcscpy(lpDst, lpSrc);\r
- lpDst = lpDst + dwLength;\r
- }\r
-\r
- lpSrc = lpSrc + dwLength;\r
- }\r
- *lpDst = 0;\r
- dwServiceLength++;\r
-\r
- dwError = RegSetValueExW(hServiceKey,\r
- L"DependOnGroup",\r
- 0,\r
- REG_MULTI_SZ,\r
- (LPBYTE)lpGroupDeps,\r
- dwGroupLength * sizeof(WCHAR));\r
-\r
- if (dwError == ERROR_SUCCESS)\r
- {\r
- dwError = RegSetValueExW(hServiceKey,\r
- L"DependOnService",\r
- 0,\r
- REG_MULTI_SZ,\r
- (LPBYTE)lpServiceDeps,\r
- dwServiceLength * sizeof(WCHAR));\r
- }\r
-\r
- HeapFree(GetProcessHeap(), 0, lpGroupDeps);\r
- }\r
-\r
- return dwError;\r
-}\r
-\r
-\r
-DWORD\r
-ScmMarkServiceForDelete(PSERVICE pService)\r
-{\r
- HKEY hServiceKey = NULL;\r
- DWORD dwValue = 1;\r
- DWORD dwError;\r
-\r
- DPRINT("ScmMarkServiceForDelete() called\n");\r
-\r
- dwError = ScmOpenServiceKey(pService->lpServiceName,\r
- KEY_WRITE,\r
- &hServiceKey);\r
- if (dwError != ERROR_SUCCESS)\r
- return dwError;\r
-\r
- dwError = RegSetValueExW(hServiceKey,\r
- L"DeleteFlag",\r
- 0,\r
- REG_DWORD,\r
- (LPBYTE)&dwValue,\r
- sizeof(DWORD));\r
-\r
- RegCloseKey(hServiceKey);\r
-\r
- return dwError;\r
-}\r
-\r
-\r
-BOOL\r
-ScmIsDeleteFlagSet(HKEY hServiceKey)\r
-{\r
- DWORD dwError;\r
- DWORD dwType;\r
- DWORD dwFlag;\r
- DWORD dwSize = sizeof(DWORD);\r
-\r
- dwError = RegQueryValueExW(hServiceKey,\r
- L"DeleteFlag",\r
- 0,\r
- &dwType,\r
- (LPBYTE)&dwFlag,\r
- &dwSize);\r
-\r
- return (dwError == ERROR_SUCCESS);\r
-}\r
-\r
-\r
-DWORD\r
-ScmReadString(HKEY hServiceKey,\r
- LPWSTR lpValueName,\r
- LPWSTR *lpValue)\r
-{\r
- DWORD dwError;\r
- DWORD dwSize;\r
- DWORD dwType;\r
- DWORD dwSizeNeeded;\r
- LPWSTR expanded = NULL;\r
- LPWSTR ptr = NULL;\r
-\r
- *lpValue = NULL;\r
-\r
- dwSize = 0;\r
- dwError = RegQueryValueExW(hServiceKey,\r
- lpValueName,\r
- 0,\r
- &dwType,\r
- NULL,\r
- &dwSize);\r
- if (dwError != ERROR_SUCCESS)\r
- return dwError;\r
-\r
- ptr = HeapAlloc(GetProcessHeap(), 0, dwSize);\r
- if (ptr == NULL)\r
- return ERROR_NOT_ENOUGH_MEMORY;\r
-\r
- dwError = RegQueryValueExW(hServiceKey,\r
- lpValueName,\r
- 0,\r
- &dwType,\r
- (LPBYTE)ptr,\r
- &dwSize);\r
- if (dwError != ERROR_SUCCESS)\r
- goto done;\r
-\r
- if (dwType == REG_EXPAND_SZ)\r
- {\r
- /* Expand the value... */\r
- dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0);\r
- if (dwSizeNeeded == 0)\r
- {\r
- dwError = GetLastError();\r
- goto done;\r
- }\r
- expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR));\r
- if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded))\r
- {\r
- dwError = GetLastError();\r
- goto done;\r
- }\r
- *lpValue = expanded;\r
- HeapFree(GetProcessHeap(), 0, ptr);\r
- dwError = ERROR_SUCCESS;\r
- }\r
- else\r
- {\r
- *lpValue = ptr;\r
- }\r
-\r
-done:;\r
- if (dwError != ERROR_SUCCESS)\r
- {\r
- HeapFree(GetProcessHeap(), 0, ptr);\r
- HeapFree(GetProcessHeap(), 0, expanded);\r
- }\r
-\r
- return dwError;\r
-}\r
-\r
-/* EOF */\r
-\r
+/*
+ * 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 */
+
-/*\r
- * driver.c\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include "services.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-NTSTATUS\r
-ScmLoadDriver(PSERVICE lpService)\r
-{\r
- WCHAR szDriverPath[MAX_PATH];\r
- UNICODE_STRING DriverPath;\r
- NTSTATUS Status;\r
-\r
- /* Build the driver path */\r
- wcscpy(szDriverPath,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
- wcscat(szDriverPath,\r
- lpService->lpServiceName);\r
-\r
- RtlInitUnicodeString(&DriverPath,\r
- szDriverPath);\r
-\r
- /* FIXME: Acquire privilege */\r
-\r
- DPRINT(" Path: %wZ\n", &DriverPath);\r
- Status = NtLoadDriver(&DriverPath);\r
-\r
- /* FIXME: Release privilege */\r
-\r
- return Status;\r
-}\r
-\r
-\r
-DWORD\r
-ScmUnloadDriver(PSERVICE lpService)\r
-{\r
- WCHAR szDriverPath[MAX_PATH];\r
- UNICODE_STRING DriverPath;\r
- NTSTATUS Status;\r
- DWORD dwError = ERROR_SUCCESS;\r
-\r
- /* Build the driver path */\r
- wcscpy(szDriverPath,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
- wcscat(szDriverPath,\r
- lpService->lpServiceName);\r
-\r
- RtlInitUnicodeString(&DriverPath,\r
- szDriverPath);\r
-\r
- /* FIXME: Acquire privilege */\r
-\r
- Status = NtUnloadDriver(&DriverPath);\r
-\r
- /* FIXME: Release privilege */\r
-\r
- if (!NT_SUCCESS(Status))\r
- {\r
- dwError = RtlNtStatusToDosError(Status);\r
- }\r
-\r
- return dwError;\r
-}\r
-\r
-\r
-DWORD\r
-ScmGetDriverStatus(PSERVICE lpService,\r
- LPSERVICE_STATUS lpServiceStatus)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING DirName;\r
- HANDLE DirHandle;\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- POBJECT_DIRECTORY_INFORMATION DirInfo;\r
- ULONG BufferLength;\r
- ULONG DataLength;\r
- ULONG Index;\r
- DWORD dwError = ERROR_SUCCESS;\r
- BOOLEAN bFound = FALSE;\r
-\r
- DPRINT1("ScmGetDriverStatus() called\n");\r
-\r
- memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));\r
-\r
- if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)\r
- {\r
- RtlInitUnicodeString(&DirName,\r
- L"\\Driver");\r
- }\r
- else\r
- {\r
- RtlInitUnicodeString(&DirName,\r
- L"\\FileSystem");\r
- }\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &DirName,\r
- 0,\r
- NULL,\r
- NULL);\r
-\r
- Status = NtOpenDirectoryObject(&DirHandle,\r
- DIRECTORY_QUERY | DIRECTORY_TRAVERSE,\r
- &ObjectAttributes);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("NtOpenDirectoryObject() failed!\n");\r
- return RtlNtStatusToDosError(Status);\r
- }\r
-\r
- BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +\r
- 2 * MAX_PATH * sizeof(WCHAR);\r
- DirInfo = HeapAlloc(GetProcessHeap(),\r
- HEAP_ZERO_MEMORY,\r
- BufferLength);\r
-\r
- Index = 0;\r
- while (TRUE)\r
- {\r
- Status = NtQueryDirectoryObject(DirHandle,\r
- DirInfo,\r
- BufferLength,\r
- TRUE,\r
- FALSE,\r
- &Index,\r
- &DataLength);\r
- if (Status == STATUS_NO_MORE_ENTRIES)\r
- {\r
- DPRINT("No more services\n");\r
- break;\r
- }\r
-\r
- if (!NT_SUCCESS(Status))\r
- break;\r
-\r
- DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);\r
-\r
- if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)\r
- {\r
- DPRINT1("Found: '%S' '%wZ'\n",\r
- lpService->lpServiceName, &DirInfo->ObjectName);\r
- bFound = TRUE;\r
-\r
- break;\r
- }\r
- }\r
-\r
- HeapFree(GetProcessHeap(),\r
- 0,\r
- DirInfo);\r
- NtClose(DirHandle);\r
-\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("Status: %lx\n", Status);\r
- return RtlNtStatusToDosError(Status);\r
- }\r
-\r
- if ((bFound == TRUE) &&\r
- (lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))\r
- {\r
- if (lpService->Status.dwCurrentState == SERVICE_STOPPED)\r
- {\r
- lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
- lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;\r
- lpService->Status.dwCheckPoint = 0;\r
- lpService->Status.dwWaitHint = 0;\r
- lpService->Status.dwControlsAccepted = 0;\r
- }\r
- else\r
- {\r
- lpService->Status.dwCurrentState = SERVICE_RUNNING;\r
- lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
-\r
- if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)\r
- lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
- }\r
- }\r
- else\r
- {\r
- lpService->Status.dwCurrentState = SERVICE_STOPPED;\r
- lpService->Status.dwControlsAccepted = 0;\r
- lpService->Status.dwCheckPoint = 0;\r
- lpService->Status.dwWaitHint = 0;\r
-\r
- if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)\r
- lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
- else\r
- lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;\r
- }\r
-\r
- if (lpServiceStatus != NULL)\r
- {\r
- memcpy(lpServiceStatus,\r
- &lpService->Status,\r
- sizeof(SERVICE_STATUS));\r
- }\r
-\r
- DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);\r
-\r
- return ERROR_SUCCESS;\r
-}\r
-\r
-\r
-DWORD\r
-ScmControlDriver(PSERVICE lpService,\r
- DWORD dwControl,\r
- LPSERVICE_STATUS lpServiceStatus)\r
-{\r
- DWORD dwError;\r
-\r
- DPRINT("ScmControlDriver() called\n");\r
-\r
- switch (dwControl)\r
- {\r
- case SERVICE_CONTROL_STOP:\r
- if (lpService->Status.dwCurrentState != SERVICE_RUNNING)\r
- {\r
- dwError = ERROR_INVALID_SERVICE_CONTROL;\r
- goto done;\r
- }\r
-\r
- dwError = ScmUnloadDriver(lpService);\r
- if (dwError == ERROR_SUCCESS)\r
- {\r
- lpService->Status.dwControlsAccepted = 0;\r
- lpService->Status.dwCurrentState = SERVICE_STOPPED;\r
- }\r
- break;\r
-\r
- case SERVICE_CONTROL_INTERROGATE:\r
- dwError = ScmGetDriverStatus(lpService,\r
- lpServiceStatus);\r
- break;\r
-\r
- default:\r
- dwError = ERROR_INVALID_SERVICE_CONTROL;\r
- }\r
-\r
-done:;\r
- DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);\r
-\r
- return dwError;\r
-}\r
-\r
-/* EOF */\r
+/*
+ * 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 */
-/*\r
- * groupdb.c\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include "services.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-\r
-/* GLOBALS *******************************************************************/\r
-\r
-LIST_ENTRY GroupListHead;\r
-\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-static NTSTATUS STDCALL\r
-CreateGroupOrderListRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- PSERVICE_GROUP Group;\r
-\r
- DPRINT("CreateGroupOrderListRoutine(%S, %x, %x, %x, %x, %x)\n",\r
- ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);\r
-\r
- if (ValueType == REG_BINARY &&\r
- ValueData != NULL &&\r
- ValueLength >= sizeof(DWORD) &&\r
- ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD))\r
- {\r
- Group = (PSERVICE_GROUP)Context;\r
- Group->TagCount = ((PULONG)ValueData)[0];\r
- if (Group->TagCount > 0)\r
- {\r
- if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD))\r
- {\r
- Group->TagArray = (PULONG)HeapAlloc(GetProcessHeap(),\r
- HEAP_ZERO_MEMORY,\r
- Group->TagCount * sizeof(DWORD));\r
- if (Group->TagArray == NULL)\r
- {\r
- Group->TagCount = 0;\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- }\r
-\r
- RtlCopyMemory(Group->TagArray,\r
- (PULONG)ValueData + 1,\r
- Group->TagCount * sizeof(DWORD));\r
- }\r
- else\r
- {\r
- Group->TagCount = 0;\r
- return STATUS_UNSUCCESSFUL;\r
- }\r
- }\r
- }\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static NTSTATUS STDCALL\r
-CreateGroupListRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- PSERVICE_GROUP Group;\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- if (ValueType == REG_SZ)\r
- {\r
- DPRINT("Data: '%S'\n", (PWCHAR)ValueData);\r
-\r
- Group = (PSERVICE_GROUP)HeapAlloc(GetProcessHeap(),\r
- HEAP_ZERO_MEMORY,\r
- sizeof(SERVICE_GROUP) + (wcslen(ValueData) * sizeof(WCHAR)));\r
- if (Group == NULL)\r
- {\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- }\r
-\r
- wcscpy(Group->szGroupName, ValueData);\r
- Group->lpGroupName = Group->szGroupName;\r
- Group->dwRefCount = (DWORD)-1;\r
-\r
- RtlZeroMemory(&QueryTable, sizeof(QueryTable));\r
- QueryTable[0].Name = (PWSTR)ValueData;\r
- QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"GroupOrderList",\r
- QueryTable,\r
- (PVOID)Group,\r
- NULL);\r
- DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);\r
-\r
- InsertTailList(&GroupListHead,\r
- &Group->GroupListEntry);\r
- }\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-DWORD\r
-ScmCreateGroupList(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- InitializeListHead(&GroupListHead);\r
-\r
- /* Build group order list */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"List";\r
- QueryTable[0].QueryRoutine = CreateGroupListRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"ServiceGroupOrder",\r
- QueryTable,\r
- NULL,\r
- NULL);\r
-\r
- return RtlNtStatusToDosError(Status);\r
-}\r
-\r
-/* EOF */\r
+/*
+ * 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 */