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);