advapi32.dll: Implement QueryServiceStatus. services.exe: Implement OpenSCManagerA, OpenServiceA, OpenServiceW and QueryServiceStatus. Modified: trunk/reactos/include/idl/svcctl.idl Modified: trunk/reactos/lib/advapi32/service/scm.c Modified: trunk/reactos/subsys/system/services/database.c Modified: trunk/reactos/subsys/system/services/rpcserver.c Modified: trunk/reactos/subsys/system/services/services.h _____
Modified: trunk/reactos/include/idl/svcctl.idl --- trunk/reactos/include/idl/svcctl.idl 2005-04-22 19:57:03 UTC (rev 14749) +++ trunk/reactos/include/idl/svcctl.idl 2005-04-23 00:01:37 UTC (rev 14750) @@ -54,16 +54,18 @@
[out] SC_LOCK *hLock);
/* Function 4 */ -// DWORD ScmrQueryServiceObjectSecurity(); + DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
/* Function 5 */ -// DWORD ScmrSetServiceObjectSecurity(); + DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
/* Function 6 */ -// DWORD ScmrQueryServiceStatus(); + DWORD ScmrQueryServiceStatus([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [out] LPSERVICE_STATUS lpServiceStatus);
/* Function 7 */ -// DWORD ScmrSetServiceStatus(); + DWORD ScmrSetServiceStatus([in] handle_t BindingHandle); /* FIXME */
/* Function 8 */ DWORD ScmrUnlockServiceDatabase([in] handle_t BindingHandle, @@ -75,20 +77,23 @@
/* Function 12 */ - DWORD ScmrCreateServiceW([in] handle_t BindingHandle, - [in] SC_HANDLE hSCManager, - [in, string, ref] LPCWSTR lpServiceName, - [in, string, ref] LPCWSTR lpDisplayName, - [in] DWORD dwDesiredAccess, - [in] DWORD dwServiceType, - [in] DWORD dwStartType, - [in] DWORD dwErrorControl, - [in, string, ref] LPCWSTR lpBinaryPathName, - [in, string, unique] LPCWSTR lpLoadOrderGroup, - [out] LPDWORD lpdwTagId, - [in, string, unique] LPCWSTR lpDependencies, - [in, string, unique] LPCWSTR lpServiceStartName, - [in, string, unique] LPCWSTR lpPassword); +// DWORD ScmrCreateServiceW([in] handle_t BindingHandle, +// [in] SC_HANDLE hSCManager, +// [in, string, ref] LPCWSTR lpServiceName, +// [in, string, ref] LPCWSTR lpDisplayName, +// [in] DWORD dwDesiredAccess, +// [in] DWORD dwServiceType, +// [in] DWORD dwStartType, +// [in] DWORD dwErrorControl, +// [in, string, ref] LPCWSTR lpBinaryPathName, +// [in, string, unique] LPCWSTR lpLoadOrderGroup, +// [out] LPDWORD lpdwTagId, +// [in, size_is(dwDepwndenciesLength), unique] LPCWSTR lpDependencies, +// [in] DWORD dwDependenciesLength, +// [in, string, unique] LPCWSTR lpServiceStartName, +// [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword, +// [in] DWORD dwPasswordLength, +// [out] SC_HANDLE *hService);
/* Function 15 */ _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- trunk/reactos/lib/advapi32/service/scm.c 2005-04-22 19:57:03 UTC (rev 14749) +++ trunk/reactos/lib/advapi32/service/scm.c 2005-04-23 00:01:37 UTC (rev 14750) @@ -835,17 +835,31 @@
/********************************************************************** * QueryServiceStatus * - * @unimplemented + * @implemented */ -BOOL -STDCALL -QueryServiceStatus( - SC_HANDLE hService, - LPSERVICE_STATUS lpServiceStatus) +BOOL STDCALL +QueryServiceStatus(SC_HANDLE hService, + LPSERVICE_STATUS lpServiceStatus) { - DPRINT1("QueryServiceStatus is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + DWORD dwError; + + DPRINT("QueryServiceStatus(%p, %p)\n", + hService, lpServiceStatus); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrQueryServiceStatus(BindingHandle, + (unsigned int)hService, + lpServiceStatus); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError); + SetLastError(dwError); return FALSE; + } + + return TRUE; }
@@ -886,8 +900,6 @@ }
- - /********************************************************************** * StartServiceW * _____
Modified: trunk/reactos/subsys/system/services/database.c --- trunk/reactos/subsys/system/services/database.c 2005-04-22 19:57:03 UTC (rev 14749) +++ trunk/reactos/subsys/system/services/database.c 2005-04-23 00:01:37 UTC (rev 14750) @@ -1,4 +1,4 @@
-/* $Id$ +/* * * service control manager * @@ -53,27 +53,8 @@ } 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 *******************************************************************/
LIST_ENTRY GroupListHead; @@ -82,6 +63,35 @@
/* 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, @@ -277,6 +287,13 @@ 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; }
@@ -461,7 +478,7 @@ 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) @@ -767,7 +784,7 @@ { Group->ServicesRunning = TRUE; } - Service->ServiceRunning = TRUE; + Service->CurrentState = SERVICE_RUNNING; } #if 0 else _____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-04-22 19:57:03 UTC (rev 14749) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-04-23 00:01:37 UTC (rev 14750) @@ -44,7 +44,7 @@
SCMGR_HANDLE Handle;
DWORD DesiredAccess; - PVOID DatabaseEntry; /* FIXME */ + PSERVICE ServiceEntry;
/* FIXME: Insert more data here */
@@ -167,10 +167,10 @@
static DWORD -ScmCreateServiceHandle(LPVOID lpDatabaseEntry, +ScmCreateServiceHandle(PSERVICE lpServiceEntry, SC_HANDLE *Handle) { - PMANAGER_HANDLE Ptr; + PSERVICE_HANDLE Ptr;
Ptr = GlobalAlloc(GPTR, sizeof(SERVICE_HANDLE)); @@ -181,7 +181,7 @@ Ptr->Handle.RefCount = 1;
/* FIXME: initialize more data here */ - // Ptr->DatabaseEntry = lpDatabaseEntry; + Ptr->ServiceEntry = lpServiceEntry;
*Handle = (SC_HANDLE)Ptr;
@@ -278,21 +278,42 @@ unsigned long dwControl, LPSERVICE_STATUS lpServiceStatus) { + PSERVICE_HANDLE hSvc; + PSERVICE lpService; + DPRINT1("ScmrControlService() called\n");
- /* FIXME: return proper service information */ + hSvc = (PSERVICE_HANDLE)hService; + if (hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + }
- /* test data */ -// #if 0 - lpServiceStatus->dwServiceType = 0x12345678; - lpServiceStatus->dwCurrentState = 0x98765432; - lpServiceStatus->dwControlsAccepted = 0xdeadbabe; - lpServiceStatus->dwWin32ExitCode = 0xbaadf00d; - lpServiceStatus->dwServiceSpecificExitCode = 0xdeadf00d; - lpServiceStatus->dwCheckPoint = 0xbaadbabe; - lpServiceStatus->dwWaitHint = 0x2468ACE1; -// #endif
+ /* FIXME: Check access rights */ + + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + + /* FIXME: Send control code to the service */ + + + /* Return service status information */ + lpServiceStatus->dwServiceType = lpService->Type; + lpServiceStatus->dwCurrentState = lpService->CurrentState; + lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted; + lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode; + lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode; + lpServiceStatus->dwCheckPoint = lpService->CheckPoint; + lpServiceStatus->dwWaitHint = lpService->WaitHint; + return ERROR_SUCCESS; }
@@ -303,6 +324,7 @@ unsigned int hService) { PSERVICE_HANDLE hSvc; + PSERVICE lpService;
DPRINT1("ScmrDeleteService() called\n");
@@ -314,8 +336,15 @@ STANDARD_RIGHTS_REQUIRED)) return ERROR_ACCESS_DENIED;
- /* FIXME: Delete the service */ + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + }
+ /* FIXME: Mark service for delete */ + return ERROR_SUCCESS; }
@@ -347,13 +376,86 @@ }
+/* Function 4 */ +unsigned long +ScmrQueryServiceObjectSecurity(handle_t BindingHandle) +{ + DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +}
+ +/* Function 5 */ +unsigned long +ScmrSetServiceObjectSecurity(handle_t BindingHandle) +{ + DPRINT1("ScmrSetServiceSecurity() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + + +/* Function 6 */ +unsigned long +ScmrQueryServiceStatus(handle_t BindingHandle, + unsigned int hService, + LPSERVICE_STATUS lpServiceStatus) +{ + PSERVICE_HANDLE hSvc; + PSERVICE lpService; + + DPRINT("ScmrQueryServiceStatus() called\n"); + + hSvc = (PSERVICE_HANDLE)hService; + if (hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + SERVICE_QUERY_STATUS)) + { + DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + /* Return service status information */ + lpServiceStatus->dwServiceType = lpService->Type; + lpServiceStatus->dwCurrentState = lpService->CurrentState; + lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted; + lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode; + lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode; + lpServiceStatus->dwCheckPoint = lpService->CheckPoint; + lpServiceStatus->dwWaitHint = lpService->WaitHint; + + return ERROR_SUCCESS; +} + + +/* Function 7 */ +unsigned long +ScmrSetServiceStatus(handle_t BindingHandle) +{ + DPRINT1("ScmrSetServiceStatus() is unimplemented\n"); + /* FIXME */ + return ERROR_CALL_NOT_IMPLEMENTED; +} + + /* Function 8 */ unsigned long ScmrUnlockServiceDatabase(handle_t BindingHandle, unsigned int hLock) { DPRINT1("ScmrUnlockServiceDatabase() called\n"); + /* FIXME */ return ERROR_SUCCESS; }
@@ -364,12 +466,14 @@ unsigned long BootAcceptable) { DPRINT1("ScmrNotifyBootConfigStatus() called\n"); + /* FIXME */ return ERROR_SUCCESS; }
/* Function 12 */ +#if 0 unsigned long ScmrCreateServiceW(handle_t BindingHandle, unsigned int hSCManager, @@ -391,9 +495,9 @@ *lpdwTagId = 0; return ERROR_SUCCESS; } +#endif
- /* Function 15 */ unsigned long ScmrOpenSCManagerW(handle_t BindingHandle, @@ -447,6 +551,8 @@ unsigned long dwDesiredAccess, unsigned int *hService) { + UNICODE_STRING ServiceName; + PSERVICE lpService; PMANAGER_HANDLE hManager; SC_HANDLE hHandle; DWORD dwError; @@ -464,12 +570,21 @@ return ERROR_INVALID_HANDLE; }
- /* FIXME: Check desired access */ + /* FIXME: Lock the service list */
- /* FIXME: Get service database entry */ + /* Get service database entry */ + RtlInitUnicodeString(&ServiceName, + lpServiceName);
+ lpService = ScmGetServiceEntryByName(&ServiceName); + if (lpService == NULL) + { + DPRINT1("Could not find a service!\n"); + return ERROR_SERVICE_DOES_NOT_EXIST; + } + /* Create a service handle */ - dwError = ScmCreateServiceHandle(NULL, + dwError = ScmCreateServiceHandle(lpService, &hHandle); if (dwError != ERROR_SUCCESS) { @@ -505,8 +620,33 @@ unsigned long dwDesiredAccess, unsigned int *hScm) { + UNICODE_STRING MachineName; + UNICODE_STRING DatabaseName; + DWORD dwError; + DPRINT("ScmrOpenSCManagerA() called\n"); - return ERROR_SUCCESS; + + if (lpMachineName) + RtlCreateUnicodeStringFromAsciiz(&MachineName, + lpMachineName); + + if (lpDatabaseName) + RtlCreateUnicodeStringFromAsciiz(&DatabaseName, + lpDatabaseName); + + dwError = ScmrOpenSCManagerW(BindingHandle, + lpMachineName ? MachineName.Buffer : NULL, + lpDatabaseName ? DatabaseName.Buffer : NULL, + dwDesiredAccess, + hScm); + + if (lpMachineName) + RtlFreeUnicodeString(&MachineName); + + if (lpDatabaseName) + RtlFreeUnicodeString(&DatabaseName); + + return dwError; }
@@ -518,8 +658,23 @@ unsigned long dwDesiredAccess, unsigned int *hService) { + UNICODE_STRING ServiceName; + DWORD dwError; + DPRINT("ScmrOpenServiceA() called\n"); - return 0; + + RtlCreateUnicodeStringFromAsciiz(&ServiceName, + lpServiceName); + + dwError = ScmrOpenServiceW(BindingHandle, + hSCManager, + ServiceName.Buffer, + dwDesiredAccess, + hService); + + RtlFreeUnicodeString(&ServiceName); + + return dwError; }
_____
Modified: trunk/reactos/subsys/system/services/services.h --- trunk/reactos/subsys/system/services/services.h 2005-04-22 19:57:03 UTC (rev 14749) +++ trunk/reactos/subsys/system/services/services.h 2005-04-23 00:01:37 UTC (rev 14750) @@ -2,8 +2,33 @@
* services.h */
+typedef struct _SERVICE +{ + LIST_ENTRY ServiceListEntry; + UNICODE_STRING ServiceName; + UNICODE_STRING RegistryPath; + UNICODE_STRING ServiceGroup;
+ ULONG Start; + ULONG Type; + ULONG ErrorControl; + ULONG Tag;
+ ULONG CurrentState; + ULONG ControlsAccepted; + ULONG Win32ExitCode; + ULONG ServiceSpecificExitCode; + ULONG CheckPoint; + ULONG WaitHint; + + BOOLEAN ServiceVisited; + + HANDLE ControlPipeHandle; + ULONG ProcessId; + ULONG ThreadId; +} SERVICE, *PSERVICE; + + /* services.c */
VOID PrintString(LPCSTR fmt, ...); @@ -15,7 +40,10 @@ VOID ScmGetBootAndSystemDriverState(VOID); VOID ScmAutoStartServices(VOID);
+PSERVICE +ScmGetServiceEntryByName(PUNICODE_STRING ServiceName);
+ /* rpcserver.c */
VOID ScmStartRpcServer(VOID);