[out] SC_LOCK *hLock);\r
\r
/* Function 4 */\r
-// DWORD ScmrQueryServiceObjectSecurity();\r
+ DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */\r
\r
/* Function 5 */\r
-// DWORD ScmrSetServiceObjectSecurity();\r
+ DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */\r
\r
/* Function 6 */\r
-// DWORD ScmrQueryServiceStatus();\r
+ DWORD ScmrQueryServiceStatus([in] handle_t BindingHandle,\r
+ [in] SC_HANDLE hSCManager,\r
+ [out] LPSERVICE_STATUS lpServiceStatus);\r
\r
/* Function 7 */\r
-// DWORD ScmrSetServiceStatus();\r
+ DWORD ScmrSetServiceStatus([in] handle_t BindingHandle); /* FIXME */\r
\r
/* Function 8 */\r
DWORD ScmrUnlockServiceDatabase([in] handle_t BindingHandle,\r
\r
\r
/* Function 12 */\r
- DWORD ScmrCreateServiceW([in] handle_t BindingHandle,\r
- [in] SC_HANDLE hSCManager,\r
- [in, string, ref] LPCWSTR lpServiceName,\r
- [in, string, ref] LPCWSTR lpDisplayName,\r
- [in] DWORD dwDesiredAccess,\r
- [in] DWORD dwServiceType,\r
- [in] DWORD dwStartType,\r
- [in] DWORD dwErrorControl,\r
- [in, string, ref] LPCWSTR lpBinaryPathName,\r
- [in, string, unique] LPCWSTR lpLoadOrderGroup,\r
- [out] LPDWORD lpdwTagId,\r
- [in, string, unique] LPCWSTR lpDependencies,\r
- [in, string, unique] LPCWSTR lpServiceStartName,\r
- [in, string, unique] LPCWSTR lpPassword);\r
+// DWORD ScmrCreateServiceW([in] handle_t BindingHandle,\r
+// [in] SC_HANDLE hSCManager,\r
+// [in, string, ref] LPCWSTR lpServiceName,\r
+// [in, string, ref] LPCWSTR lpDisplayName,\r
+// [in] DWORD dwDesiredAccess,\r
+// [in] DWORD dwServiceType,\r
+// [in] DWORD dwStartType,\r
+// [in] DWORD dwErrorControl,\r
+// [in, string, ref] LPCWSTR lpBinaryPathName,\r
+// [in, string, unique] LPCWSTR lpLoadOrderGroup,\r
+// [out] LPDWORD lpdwTagId,\r
+// [in, size_is(dwDepwndenciesLength), unique] LPCWSTR lpDependencies,\r
+// [in] DWORD dwDependenciesLength,\r
+// [in, string, unique] LPCWSTR lpServiceStartName,\r
+// [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword,\r
+// [in] DWORD dwPasswordLength,\r
+// [out] SC_HANDLE *hService);\r
\r
\r
/* Function 15 */\r
-/* $Id$
+/*
*
* service control manager
*
} SERVICE_GROUP, *PSERVICE_GROUP;
-typedef struct _SERVICE
-{
- LIST_ENTRY ServiceListEntry;
- UNICODE_STRING ServiceName;
- UNICODE_STRING RegistryPath;
- UNICODE_STRING ServiceGroup;
-
- ULONG Start;
- ULONG Type;
- ULONG ErrorControl;
- ULONG Tag;
-
- BOOLEAN ServiceRunning;
- BOOLEAN ServiceVisited;
-
- HANDLE ControlPipeHandle;
- ULONG ProcessId;
- ULONG ThreadId;
-} SERVICE, *PSERVICE;
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
+PSERVICE
+ScmGetServiceEntryByName(PUNICODE_STRING ServiceName)
+{
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
+
+ DPRINT("ScmGetServiceEntryByName() called\n");
+
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+ if (RtlEqualUnicodeString(&CurrentService->ServiceName, ServiceName, TRUE))
+ {
+ DPRINT("Found service: '%wZ'\n", &CurrentService->ServiceName);
+ return CurrentService;
+ }
+
+ ServiceEntry = ServiceEntry->Flink;
+ }
+
+ DPRINT("Couldn't find a matching service\n");
+
+ return NULL;
+}
+
+
static NTSTATUS STDCALL
CreateGroupOrderListRoutine(PWSTR ValueName,
ULONG ValueType,
InsertTailList(&ServiceListHead,
&Service->ServiceListEntry);
+ Service->CurrentState = SERVICE_STOPPED;
+ Service->ControlsAccepted = 0;
+ Service->Win32ExitCode = 0;
+ Service->ServiceSpecificExitCode = 0;
+ Service->CheckPoint = 0;
+ Service->WaitHint = 2000; /* 2 seconds */
+
return STATUS_SUCCESS;
}
DPRINT("Found: '%wZ' '%wZ'\n", &Service->ServiceName, &DirInfo->ObjectName);
/* Mark service as 'running' */
- Service->ServiceRunning = TRUE;
+ Service->CurrentState = SERVICE_RUNNING;
/* Find the driver's group and mark it as 'running' */
if (Service->ServiceGroup.Buffer != NULL)
{
Group->ServicesRunning = TRUE;
}
- Service->ServiceRunning = TRUE;
+ Service->CurrentState = SERVICE_RUNNING;
}
#if 0
else
SCMGR_HANDLE Handle;\r
\r
DWORD DesiredAccess;\r
- PVOID DatabaseEntry; /* FIXME */\r
+ PSERVICE ServiceEntry;\r
\r
/* FIXME: Insert more data here */\r
\r
\r
\r
static DWORD\r
-ScmCreateServiceHandle(LPVOID lpDatabaseEntry,\r
+ScmCreateServiceHandle(PSERVICE lpServiceEntry,\r
SC_HANDLE *Handle)\r
{\r
- PMANAGER_HANDLE Ptr;\r
+ PSERVICE_HANDLE Ptr;\r
\r
Ptr = GlobalAlloc(GPTR,\r
sizeof(SERVICE_HANDLE));\r
Ptr->Handle.RefCount = 1;\r
\r
/* FIXME: initialize more data here */\r
- // Ptr->DatabaseEntry = lpDatabaseEntry;\r
+ Ptr->ServiceEntry = lpServiceEntry;\r
\r
*Handle = (SC_HANDLE)Ptr;\r
\r
unsigned long dwControl,\r
LPSERVICE_STATUS lpServiceStatus)\r
{\r
+ PSERVICE_HANDLE hSvc;\r
+ PSERVICE lpService;\r
+\r
DPRINT1("ScmrControlService() called\n");\r
\r
- /* FIXME: return proper service information */\r
+ hSvc = (PSERVICE_HANDLE)hService;\r
+ if (hSvc->Handle.Tag != SERVICE_TAG)\r
+ {\r
+ DPRINT1("Invalid handle tag!\n");\r
+ return ERROR_INVALID_HANDLE;\r
+ }\r
+\r
+\r
+ /* FIXME: Check access rights */\r
\r
- /* test data */\r
-// #if 0\r
- lpServiceStatus->dwServiceType = 0x12345678;\r
- lpServiceStatus->dwCurrentState = 0x98765432;\r
- lpServiceStatus->dwControlsAccepted = 0xdeadbabe;\r
- lpServiceStatus->dwWin32ExitCode = 0xbaadf00d;\r
- lpServiceStatus->dwServiceSpecificExitCode = 0xdeadf00d;\r
- lpServiceStatus->dwCheckPoint = 0xbaadbabe;\r
- lpServiceStatus->dwWaitHint = 0x2468ACE1;\r
-// #endif\r
+\r
+ lpService = hSvc->ServiceEntry;\r
+ if (lpService == NULL)\r
+ {\r
+ DPRINT1("lpService == NULL!\n");\r
+ return ERROR_INVALID_HANDLE;\r
+ }\r
+\r
+\r
+ /* FIXME: Send control code to the service */\r
+\r
+\r
+ /* Return service status information */\r
+ lpServiceStatus->dwServiceType = lpService->Type;\r
+ lpServiceStatus->dwCurrentState = lpService->CurrentState;\r
+ lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted;\r
+ lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode;\r
+ lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode;\r
+ lpServiceStatus->dwCheckPoint = lpService->CheckPoint;\r
+ lpServiceStatus->dwWaitHint = lpService->WaitHint;\r
\r
return ERROR_SUCCESS;\r
}\r
unsigned int hService)\r
{\r
PSERVICE_HANDLE hSvc;\r
+ PSERVICE lpService;\r
\r
DPRINT1("ScmrDeleteService() called\n");\r
\r
STANDARD_RIGHTS_REQUIRED))\r
return ERROR_ACCESS_DENIED;\r
\r
- /* FIXME: Delete the service */\r
+ lpService = hSvc->ServiceEntry;\r
+ if (lpService == NULL)\r
+ {\r
+ DPRINT1("lpService == NULL!\n");\r
+ return ERROR_INVALID_HANDLE;\r
+ }\r
+\r
+ /* FIXME: Mark service for delete */\r
\r
return ERROR_SUCCESS;\r
}\r
}\r
\r
\r
+/* Function 4 */\r
+unsigned long\r
+ScmrQueryServiceObjectSecurity(handle_t BindingHandle)\r
+{\r
+ DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");\r
+ return ERROR_CALL_NOT_IMPLEMENTED;\r
+}\r
+\r
+\r
+/* Function 5 */\r
+unsigned long\r
+ScmrSetServiceObjectSecurity(handle_t BindingHandle)\r
+{\r
+ DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");\r
+ return ERROR_CALL_NOT_IMPLEMENTED;\r
+}\r
+\r
+\r
+/* Function 6 */\r
+unsigned long\r
+ScmrQueryServiceStatus(handle_t BindingHandle,\r
+ unsigned int hService,\r
+ LPSERVICE_STATUS lpServiceStatus)\r
+{\r
+ PSERVICE_HANDLE hSvc;\r
+ PSERVICE lpService;\r
+\r
+ DPRINT("ScmrQueryServiceStatus() called\n");\r
+\r
+ hSvc = (PSERVICE_HANDLE)hService;\r
+ if (hSvc->Handle.Tag != SERVICE_TAG)\r
+ {\r
+ DPRINT1("Invalid handle tag!\n");\r
+ return ERROR_INVALID_HANDLE;\r
+ }\r
+\r
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,\r
+ SERVICE_QUERY_STATUS))\r
+ {\r
+ DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);\r
+ return ERROR_ACCESS_DENIED;\r
+ }\r
+\r
+ lpService = hSvc->ServiceEntry;\r
+ if (lpService == NULL)\r
+ {\r
+ DPRINT1("lpService == NULL!\n");\r
+ return ERROR_INVALID_HANDLE;\r
+ }\r
+\r
+ /* Return service status information */\r
+ lpServiceStatus->dwServiceType = lpService->Type;\r
+ lpServiceStatus->dwCurrentState = lpService->CurrentState;\r
+ lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted;\r
+ lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode;\r
+ lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode;\r
+ lpServiceStatus->dwCheckPoint = lpService->CheckPoint;\r
+ lpServiceStatus->dwWaitHint = lpService->WaitHint;\r
+\r
+ return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+/* Function 7 */\r
+unsigned long\r
+ScmrSetServiceStatus(handle_t BindingHandle)\r
+{\r
+ DPRINT1("ScmrSetServiceStatus() is unimplemented\n");\r
+ /* FIXME */\r
+ return ERROR_CALL_NOT_IMPLEMENTED;\r
+}\r
+\r
\r
/* Function 8 */\r
unsigned long\r
unsigned int hLock)\r
{\r
DPRINT1("ScmrUnlockServiceDatabase() called\n");\r
+ /* FIXME */\r
return ERROR_SUCCESS;\r
}\r
\r
unsigned long BootAcceptable)\r
{\r
DPRINT1("ScmrNotifyBootConfigStatus() called\n");\r
+ /* FIXME */\r
return ERROR_SUCCESS;\r
}\r
\r
\r
\r
/* Function 12 */\r
+#if 0\r
unsigned long\r
ScmrCreateServiceW(handle_t BindingHandle,\r
unsigned int hSCManager,\r
*lpdwTagId = 0;\r
return ERROR_SUCCESS;\r
}\r
-\r
+#endif\r
\r
\r
/* Function 15 */\r
unsigned long dwDesiredAccess,\r
unsigned int *hService)\r
{\r
+ UNICODE_STRING ServiceName;\r
+ PSERVICE lpService;\r
PMANAGER_HANDLE hManager;\r
SC_HANDLE hHandle;\r
DWORD dwError;\r
return ERROR_INVALID_HANDLE;\r
}\r
\r
- /* FIXME: Check desired access */\r
+ /* FIXME: Lock the service list */\r
+\r
+ /* Get service database entry */\r
+ RtlInitUnicodeString(&ServiceName,\r
+ lpServiceName);\r
\r
- /* FIXME: Get service database entry */\r
+ lpService = ScmGetServiceEntryByName(&ServiceName);\r
+ if (lpService == NULL)\r
+ {\r
+ DPRINT1("Could not find a service!\n");\r
+ return ERROR_SERVICE_DOES_NOT_EXIST;\r
+ }\r
\r
/* Create a service handle */\r
- dwError = ScmCreateServiceHandle(NULL,\r
+ dwError = ScmCreateServiceHandle(lpService,\r
&hHandle);\r
if (dwError != ERROR_SUCCESS)\r
{\r
unsigned long dwDesiredAccess,\r
unsigned int *hScm)\r
{\r
+ UNICODE_STRING MachineName;\r
+ UNICODE_STRING DatabaseName;\r
+ DWORD dwError;\r
+\r
DPRINT("ScmrOpenSCManagerA() called\n");\r
- return ERROR_SUCCESS;\r
+\r
+ if (lpMachineName)\r
+ RtlCreateUnicodeStringFromAsciiz(&MachineName,\r
+ lpMachineName);\r
+\r
+ if (lpDatabaseName)\r
+ RtlCreateUnicodeStringFromAsciiz(&DatabaseName,\r
+ lpDatabaseName);\r
+\r
+ dwError = ScmrOpenSCManagerW(BindingHandle,\r
+ lpMachineName ? MachineName.Buffer : NULL,\r
+ lpDatabaseName ? DatabaseName.Buffer : NULL,\r
+ dwDesiredAccess,\r
+ hScm);\r
+\r
+ if (lpMachineName)\r
+ RtlFreeUnicodeString(&MachineName);\r
+\r
+ if (lpDatabaseName)\r
+ RtlFreeUnicodeString(&DatabaseName);\r
+\r
+ return dwError;\r
}\r
\r
\r
unsigned long dwDesiredAccess,\r
unsigned int *hService)\r
{\r
+ UNICODE_STRING ServiceName;\r
+ DWORD dwError;\r
+\r
DPRINT("ScmrOpenServiceA() called\n");\r
- return 0;\r
+\r
+ RtlCreateUnicodeStringFromAsciiz(&ServiceName,\r
+ lpServiceName);\r
+\r
+ dwError = ScmrOpenServiceW(BindingHandle,\r
+ hSCManager,\r
+ ServiceName.Buffer,\r
+ dwDesiredAccess,\r
+ hService);\r
+\r
+ RtlFreeUnicodeString(&ServiceName);\r
+\r
+ return dwError;\r
}\r
\r
\r