advapi32.dll: Implement QueryServiceStatus.
authorEric Kohl <eric.kohl@reactos.org>
Sat, 23 Apr 2005 00:01:37 +0000 (00:01 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 23 Apr 2005 00:01:37 +0000 (00:01 +0000)
services.exe: Implement OpenSCManagerA, OpenServiceA, OpenServiceW and QueryServiceStatus.

svn path=/trunk/; revision=14750

reactos/include/idl/svcctl.idl
reactos/lib/advapi32/service/scm.c
reactos/subsys/system/services/database.c
reactos/subsys/system/services/rpcserver.c
reactos/subsys/system/services/services.h

index dee3a4c..1bd65c0 100644 (file)
@@ -54,16 +54,18 @@ cpp_quote("#endif")
                                 [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
@@ -75,20 +77,23 @@ cpp_quote("#endif")
 \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
index 466046e..9d1e6ef 100644 (file)
@@ -835,17 +835,31 @@ QueryServiceObjectSecurity(
 /**********************************************************************
  *  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 @@ StartServiceA(
 }
 
 
-
-
 /**********************************************************************
  *  StartServiceW
  *
index 1835dca..7cf99e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id$
+/*
  *
  * service control manager
  * 
@@ -53,25 +53,6 @@ typedef struct _SERVICE_GROUP
 } 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 *******************************************************************/
@@ -82,6 +63,35 @@ LIST_ENTRY ServiceListHead;
 
 /* 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 @@ CreateServiceListEntry(PUNICODE_STRING ServiceName)
   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 @@ ScmCheckDriver(PSERVICE Service)
          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 @@ ScmStartService(PSERVICE Service,
        {
          Group->ServicesRunning = TRUE;
        }
-      Service->ServiceRunning = TRUE;
+      Service->CurrentState = SERVICE_RUNNING;
     }
 #if 0
   else
index 7aae006..42c172e 100644 (file)
@@ -44,7 +44,7 @@ typedef struct _SERVICE_HANDLE
   SCMGR_HANDLE Handle;\r
 \r
   DWORD DesiredAccess;\r
-  PVOID DatabaseEntry; /* FIXME */\r
+  PSERVICE ServiceEntry;\r
 \r
   /* FIXME: Insert more data here */\r
 \r
@@ -167,10 +167,10 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
 \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
@@ -181,7 +181,7 @@ ScmCreateServiceHandle(LPVOID lpDatabaseEntry,
   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
@@ -278,20 +278,41 @@ ScmrControlService(handle_t BindingHandle,
                    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
@@ -303,6 +324,7 @@ ScmrDeleteService(handle_t BindingHandle,
                   unsigned int hService)\r
 {\r
   PSERVICE_HANDLE hSvc;\r
+  PSERVICE lpService;\r
 \r
   DPRINT1("ScmrDeleteService() called\n");\r
 \r
@@ -314,7 +336,14 @@ ScmrDeleteService(handle_t BindingHandle,
                                 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
@@ -347,6 +376,78 @@ ScmrLockServiceDatabase(handle_t BindingHandle,
 }\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
@@ -354,6 +455,7 @@ ScmrUnlockServiceDatabase(handle_t BindingHandle,
                           unsigned int hLock)\r
 {\r
   DPRINT1("ScmrUnlockServiceDatabase() called\n");\r
+  /* FIXME */\r
   return ERROR_SUCCESS;\r
 }\r
 \r
@@ -364,12 +466,14 @@ ScmrNotifyBootConfigStatus(handle_t BindingHandle,
                            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
@@ -391,7 +495,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
     *lpdwTagId = 0;\r
   return ERROR_SUCCESS;\r
 }\r
-\r
+#endif\r
 \r
 \r
 /* Function 15 */\r
@@ -447,6 +551,8 @@ ScmrOpenServiceW(handle_t BindingHandle,
                  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
@@ -464,12 +570,21 @@ ScmrOpenServiceW(handle_t BindingHandle,
     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
@@ -505,8 +620,33 @@ ScmrOpenSCManagerA(handle_t BindingHandle,
                    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
@@ -518,8 +658,23 @@ ScmrOpenServiceA(handle_t BindingHandle,
                  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
index b7a6c37..05f1a94 100644 (file)
@@ -2,6 +2,31 @@
  * 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 */
@@ -15,6 +40,9 @@ NTSTATUS ScmCreateServiceDataBase(VOID);
 VOID ScmGetBootAndSystemDriverState(VOID);
 VOID ScmAutoStartServices(VOID);
 
+PSERVICE
+ScmGetServiceEntryByName(PUNICODE_STRING ServiceName);
+
 
 /* rpcserver.c */