-Add QueryServiceConfig2A stub.
authorEric Kohl <eric.kohl@reactos.org>
Fri, 23 Dec 2005 15:56:51 +0000 (15:56 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 23 Dec 2005 15:56:51 +0000 (15:56 +0000)
-Implement QueryServiceObjectSecurity and SetServiceObjectSecurity.

svn path=/trunk/; revision=20311

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

index 311203e..5aa5ad6 100644 (file)
@@ -10,6 +10,7 @@
 #define BOOL unsigned long\r
 #define SC_HANDLE unsigned int\r
 #define SC_LOCK unsigned int\r
+#define SERVICE_STATUS_HANDLE unsigned long\r
 #define LPSTR char*\r
 #define LPCSTR char*\r
 #define LPWSTR wchar_t*\r
@@ -57,10 +58,19 @@ cpp_quote("#endif")
                                 [out] SC_LOCK *hLock);\r
 \r
   /* Function 4 */\r
-  DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */\r
+  DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle,\r
+                                       [in] SC_HANDLE hService,\r
+                                       [in] DWORD dwSecurityInformation,\r
+                                       [out, size_is(dwSecuityDescriptorSize)] unsigned char *lpSecurityDescriptor,\r
+                                       [in] DWORD dwSecuityDescriptorSize,\r
+                                       [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 5 */\r
-  DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */\r
+  DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle,\r
+                                     [in] SC_HANDLE hService,\r
+                                     [in] DWORD dwSecurityInformation,\r
+                                     [in, size_is(dwSecuityDescriptorSize)] unsigned char *lpSecurityDescriptor,\r
+                                     [in] DWORD dwSecuityDescriptorSize);\r
 \r
   /* Function 6 */\r
   DWORD ScmrQueryServiceStatus([in] handle_t BindingHandle,\r
@@ -68,7 +78,8 @@ cpp_quote("#endif")
                                [out] LPSERVICE_STATUS lpServiceStatus);\r
 \r
   /* Function 7 */\r
-  DWORD ScmrSetServiceStatus([in] handle_t BindingHandle); /* FIXME */\r
+  DWORD ScmrSetServiceStatus([in] handle_t BindingHandle,\r
+                             [in] SERVICE_STATUS_HANDLE hServiceStatus); /* FIXME */\r
 \r
   /* Function 8 */\r
   DWORD ScmrUnlockServiceDatabase([in] handle_t BindingHandle,\r
@@ -78,6 +89,13 @@ cpp_quote("#endif")
   DWORD ScmrNotifyBootConfigStatus([in] handle_t BindingHandle,\r
                                    [in] BOOL BootAcceptable);\r
 \r
+  /* Function 10 */\r
+  DWORD ScmrI_ScSetServiceBitsW([in] handle_t BindingHandle,\r
+                                [in] SERVICE_STATUS_HANDLE hServiceStatus,\r
+                                [in] DWORD dwServiceBits,\r
+                                [in] BOOL bSetBitsOn,\r
+                                [in] BOOL bUpdateImmediately,\r
+                                [in, string, unique] LPWSTR lpString);\r
 \r
   /* Function 11 */\r
   DWORD ScmrChangeServiceConfigW([in] handle_t BindingHandle,\r
@@ -132,7 +150,7 @@ cpp_quote("#endif")
                                 [in] DWORD dwBufSize,\r
                                 [out] LPDWORD pcbBytesNeeded,\r
                                 [out] LPDWORD lpServicesReturned,\r
-                                [in, out] LPDWORD lpResumeHandle); /* FIXME: unique */\r
+                                [in, out, unique] LPDWORD lpResumeHandle);\r
 \r
   /* Function 15 */\r
   DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,\r
index fc27715..4abe55b 100644 (file)
@@ -449,7 +449,7 @@ PrivilegedServiceAuditAlarmW@20
 ;QueryAllTracesA
 ;QueryAllTracesW
 QueryRecoveryAgentsOnEncryptedFile@8
-;QueryServiceConfig2A@20
+QueryServiceConfig2A@20
 QueryServiceConfig2W@20
 QueryServiceConfigA@16
 QueryServiceConfigW@16
index 9bb5ebb..ed1bb9a 100644 (file)
@@ -1035,8 +1035,7 @@ QueryServiceConfigA(
  *
  * @implemented
  */
-BOOL
-STDCALL
+BOOL STDCALL
 QueryServiceConfigW(SC_HANDLE hService,
                     LPQUERY_SERVICE_CONFIGW lpServiceConfig,
                     DWORD cbBufSize,
@@ -1094,6 +1093,25 @@ QueryServiceConfigW(SC_HANDLE hService,
 }
 
 
+/**********************************************************************
+ *  QueryServiceConfig2A
+ *
+ * @unimplemented
+ */
+BOOL
+STDCALL
+QueryServiceConfig2A(
+    SC_HANDLE       hService,
+    DWORD           dwInfo,
+    LPBYTE          lpBuffer,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded)
+{
+    DPRINT1("QueryServiceConfig2A is unimplemented\n");
+    return FALSE;
+}
+
+
 /**********************************************************************
  *  QueryServiceConfig2W
  *
@@ -1101,15 +1119,14 @@ QueryServiceConfigW(SC_HANDLE hService,
  */
 BOOL
 STDCALL
-QueryServiceConfig2W
-(
+QueryServiceConfig2W(
     SC_HANDLE       hService,
     DWORD           dwInfo,
     LPBYTE          lpBuffer,
     DWORD           cbBufSize,
     LPDWORD         pcbBytesNeeded)
 {
-    DPRINT1("QueryServiceConfigW2 is unimplemented\n");
+    DPRINT1("QueryServiceConfig2W is unimplemented\n");
     return FALSE;
 }
 
@@ -1155,20 +1172,37 @@ QueryServiceLockStatusW(
 /**********************************************************************
  *  QueryServiceObjectSecurity
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-QueryServiceObjectSecurity(
-    SC_HANDLE       hService,
-    SECURITY_INFORMATION    dwSecurityInformation,
-    PSECURITY_DESCRIPTOR    lpSecurityDescriptor,
-    DWORD           cbBufSize,
-    LPDWORD         pcbBytesNeeded)
+BOOL STDCALL
+QueryServiceObjectSecurity(SC_HANDLE hService,
+                           SECURITY_INFORMATION dwSecurityInformation,
+                           PSECURITY_DESCRIPTOR lpSecurityDescriptor,
+                           DWORD cbBufSize,
+                           LPDWORD pcbBytesNeeded)
 {
-    DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+
+    DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
+           hService, dwSecurityInformation, lpSecurityDescriptor);
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
+                                             (unsigned int)hService,
+                                             dwSecurityInformation,
+                                             (unsigned char *)lpSecurityDescriptor,
+                                             cbBufSize,
+                                             pcbBytesNeeded);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
@@ -1225,15 +1259,64 @@ QueryServiceStatusEx(SC_HANDLE  hService,
 /**********************************************************************
  *  SetServiceObjectSecurity
  *
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
 SetServiceObjectSecurity(SC_HANDLE hService,
-                        SECURITY_INFORMATION dwSecurityInformation,
-                        PSECURITY_DESCRIPTOR lpSecurityDescriptor)
+                         SECURITY_INFORMATION dwSecurityInformation,
+                         PSECURITY_DESCRIPTOR lpSecurityDescriptor)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
+    ULONG Length;
+    NTSTATUS Status;
+    DWORD dwError;
+
+    Length = 0;
+    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+                                   SelfRelativeSD,
+                                   &Length);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
+    if (SelfRelativeSD == NULL)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+                                   SelfRelativeSD,
+                                   &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+        SetLastError(RtlNtStatusToDosError(Status));
+        return FALSE;
+    }
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrSetServiceObjectSecurity(BindingHandle,
+                                           (unsigned int)hService,
+                                           dwSecurityInformation,
+                                           (unsigned char *)SelfRelativeSD,
+                                           Length);
+
+    HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
index 4367fc7..8198709 100644 (file)
@@ -453,16 +453,91 @@ ScmrLockServiceDatabase(handle_t BindingHandle,
 
 /* Function 4 */
 unsigned long
-ScmrQueryServiceObjectSecurity(handle_t BindingHandle)
+ScmrQueryServiceObjectSecurity(handle_t BindingHandle,
+                               unsigned int hService,
+                               unsigned long dwSecurityInformation,
+                               unsigned char *lpSecurityDescriptor,
+                               unsigned long dwSecuityDescriptorSize,
+                               unsigned long *pcbBytesNeeded)
 {
-    DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    PSERVICE_HANDLE hSvc;
+    PSERVICE lpService;
+    ULONG DesiredAccess = 0;
+    NTSTATUS Status;
+    DWORD dwBytesNeeded;
+    DWORD dwError;
+
+    DPRINT("ScmrQueryServiceSecurity() called\n");
+
+    hSvc = (PSERVICE_HANDLE)hService;
+    if (hSvc->Handle.Tag != SERVICE_TAG)
+    {
+        DPRINT1("Invalid handle tag!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (dwSecurityInformation & (DACL_SECURITY_INFORMATION ||
+                                 GROUP_SECURITY_INFORMATION ||
+                                 OWNER_SECURITY_INFORMATION))
+        DesiredAccess |= READ_CONTROL;
+
+    if (dwSecurityInformation & SACL_SECURITY_INFORMATION)
+        DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+    if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+                                  DesiredAccess))
+    {
+        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;
+    }
+
+    /* FIXME: Lock the service list */
+
+    Status = RtlQuerySecurityObject(lpService->lpSecurityDescriptor,
+                                    dwSecurityInformation,
+                                    (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
+                                    dwSecuityDescriptorSize,
+                                    &dwBytesNeeded);
+
+    /* FIXME: Unlock the service list */
+
+    if (NT_SUCCESS(Status))
+    {
+        *pcbBytesNeeded = dwBytesNeeded;
+        dwError = STATUS_SUCCESS;
+    }
+    else if (Status == STATUS_BUFFER_TOO_SMALL)
+    {
+        *pcbBytesNeeded = dwBytesNeeded;
+        dwError = ERROR_INSUFFICIENT_BUFFER;
+    }
+    else if (Status == STATUS_BAD_DESCRIPTOR_FORMAT)
+    {
+        dwError = ERROR_GEN_FAILURE;
+    }
+    else
+    {
+        dwError = RtlNtStatusToDosError(Status);
+    }
+
+    return dwError;
 }
 
 
 /* Function 5 */
 unsigned long
-ScmrSetServiceObjectSecurity(handle_t BindingHandle)
+ScmrSetServiceObjectSecurity(handle_t BindingHandle,
+                             unsigned int hService,
+                             unsigned long dwSecurityInformation,
+                             unsigned char *lpSecurityDescriptor,
+                             unsigned long dwSecuityDescriptorSize)
 {
     DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -515,7 +590,8 @@ ScmrQueryServiceStatus(handle_t BindingHandle,
 
 /* Function 7 */
 unsigned long
-ScmrSetServiceStatus(handle_t BindingHandle)
+ScmrSetServiceStatus(handle_t BindingHandle,
+                     unsigned long hServiceStatus) /* FIXME */
 {
     DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
     /* FIXME */
@@ -545,6 +621,21 @@ ScmrNotifyBootConfigStatus(handle_t BindingHandle,
 }
 
 
+/* Function 10 */
+unsigned long
+ScmrI_ScSetServiceBitsW(handle_t BindingHandle,
+                        unsigned long hServiceStatus,
+                        unsigned long dwServiceBits,
+                        unsigned long bSetBitsOn,
+                        unsigned long bUpdateImmediately,
+                        wchar_t *lpString)
+{
+    DPRINT1("ScmrI_ScSetServiceBitsW() called\n");
+    /* FIXME */
+    return ERROR_SUCCESS;
+}
+
+
 /* Function 11 */
 unsigned long
 ScmrChangeServiceConfigW(handle_t BiningHandle,
index 950a84e..37d57e5 100644 (file)
@@ -25,6 +25,8 @@ typedef struct _SERVICE
 
     ULONG Flags;
 
+    PSECURITY_DESCRIPTOR lpSecurityDescriptor;
+
     BOOLEAN ServiceVisited;
 
     HANDLE ControlPipeHandle;