-Add QueryServiceConfig2A stub.
-Implement QueryServiceObjectSecurity and SetServiceObjectSecurity.
Modified: trunk/reactos/include/idl/svcctl.idl
Modified: trunk/reactos/lib/advapi32/advapi32.def
Modified: trunk/reactos/lib/advapi32/service/scm.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-12-23 15:46:03 UTC (rev 20310)
+++ trunk/reactos/include/idl/svcctl.idl	2005-12-23 15:56:51 UTC (rev 20311)
@@ -10,6 +10,7 @@
 #define BOOL unsigned long
 #define SC_HANDLE unsigned int
 #define SC_LOCK unsigned int
+#define SERVICE_STATUS_HANDLE unsigned long
 #define LPSTR char*
 #define LPCSTR char*
 #define LPWSTR wchar_t*
@@ -57,10 +58,19 @@
                                 [out] SC_LOCK *hLock);
 
   /* Function 4 */
-  DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
+  DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle,
+                                       [in] SC_HANDLE hService,
+                                       [in] DWORD dwSecurityInformation,
+                                       [out, size_is(dwSecuityDescriptorSize)] unsigned char *lpSecurityDescriptor,
+                                       [in] DWORD dwSecuityDescriptorSize,
+                                       [out] LPDWORD pcbBytesNeeded);
 
   /* Function 5 */
-  DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
+  DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle,
+                                     [in] SC_HANDLE hService,
+                                     [in] DWORD dwSecurityInformation,
+                                     [in, size_is(dwSecuityDescriptorSize)] unsigned char *lpSecurityDescriptor,
+                                     [in] DWORD dwSecuityDescriptorSize);
 
   /* Function 6 */
   DWORD ScmrQueryServiceStatus([in] handle_t BindingHandle,
@@ -68,7 +78,8 @@
                                [out] LPSERVICE_STATUS lpServiceStatus);
 
   /* Function 7 */
-  DWORD ScmrSetServiceStatus([in] handle_t BindingHandle); /* FIXME */
+  DWORD ScmrSetServiceStatus([in] handle_t BindingHandle,
+                             [in] SERVICE_STATUS_HANDLE hServiceStatus); /* FIXME */
 
   /* Function 8 */
   DWORD ScmrUnlockServiceDatabase([in] handle_t BindingHandle,
@@ -78,6 +89,13 @@
   DWORD ScmrNotifyBootConfigStatus([in] handle_t BindingHandle,
                                    [in] BOOL BootAcceptable);
 
+  /* Function 10 */
+  DWORD ScmrI_ScSetServiceBitsW([in] handle_t BindingHandle,
+                                [in] SERVICE_STATUS_HANDLE hServiceStatus,
+                                [in] DWORD dwServiceBits,
+                                [in] BOOL bSetBitsOn,
+                                [in] BOOL bUpdateImmediately,
+                                [in, string, unique] LPWSTR lpString);
 
   /* Function 11 */
   DWORD ScmrChangeServiceConfigW([in] handle_t BindingHandle,
@@ -132,7 +150,7 @@
                                 [in] DWORD dwBufSize,
                                 [out] LPDWORD pcbBytesNeeded,
                                 [out] LPDWORD lpServicesReturned,
-                                [in, out] LPDWORD lpResumeHandle); /* FIXME: unique */
+                                [in, out, unique] LPDWORD lpResumeHandle);
 
   /* Function 15 */
   DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,

Modified: trunk/reactos/lib/advapi32/advapi32.def
--- trunk/reactos/lib/advapi32/advapi32.def	2005-12-23 15:46:03 UTC (rev 20310)
+++ trunk/reactos/lib/advapi32/advapi32.def	2005-12-23 15:56:51 UTC (rev 20311)
@@ -449,7 +449,7 @@
 ;QueryAllTracesA
 ;QueryAllTracesW
 QueryRecoveryAgentsOnEncryptedFile@8
-;QueryServiceConfig2A@20
+QueryServiceConfig2A@20
 QueryServiceConfig2W@20
 QueryServiceConfigA@16
 QueryServiceConfigW@16

Modified: trunk/reactos/lib/advapi32/service/scm.c
--- trunk/reactos/lib/advapi32/service/scm.c	2005-12-23 15:46:03 UTC (rev 20310)
+++ trunk/reactos/lib/advapi32/service/scm.c	2005-12-23 15:56:51 UTC (rev 20311)
@@ -1035,8 +1035,7 @@
  *
  * @implemented
  */
-BOOL
-STDCALL
+BOOL STDCALL
 QueryServiceConfigW(SC_HANDLE hService,
                     LPQUERY_SERVICE_CONFIGW lpServiceConfig,
                     DWORD cbBufSize,
@@ -1095,21 +1094,39 @@
 
 
 /**********************************************************************
+ *  QueryServiceConfig2A
+ *
+ * @unimplemented
+ */
+BOOL
+STDCALL
+QueryServiceConfig2A(
+    SC_HANDLE       hService,
+    DWORD           dwInfo,
+    LPBYTE          lpBuffer,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded)
+{
+    DPRINT1("QueryServiceConfig2A is unimplemented\n");
+    return FALSE;
+}
+
+
+/**********************************************************************
  *  QueryServiceConfig2W
  *
  * @unimplemented
  */
 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 @@
 /**********************************************************************
  *  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 @@
 /**********************************************************************
  *  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;
 }
 
 

Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- trunk/reactos/subsys/system/services/rpcserver.c	2005-12-23 15:46:03 UTC (rev 20310)
+++ trunk/reactos/subsys/system/services/rpcserver.c	2005-12-23 15:56:51 UTC (rev 20311)
@@ -453,16 +453,91 @@
 
 /* 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 @@
 
 /* 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 @@
 }
 
 
+/* 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,

Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/subsys/system/services/services.h	2005-12-23 15:46:03 UTC (rev 20310)
+++ trunk/reactos/subsys/system/services/services.h	2005-12-23 15:56:51 UTC (rev 20311)
@@ -25,6 +25,8 @@
 
     ULONG Flags;
 
+    PSECURITY_DESCRIPTOR lpSecurityDescriptor;
+
     BOOLEAN ServiceVisited;
 
     HANDLE ControlPipeHandle;