Updated:
I have been trying now for some time to find a way to list the owner, groups, and DACl of a system service.
The built in SC.exe utility will return the DACL but not the Owner or groups.
After digging thru the Object browser for some time it appears that there is no straight forward way as in folder,file,and registry permissions to get the information thru .Net.
There is a System.ServiceProcess.ServiceControllerPermissionEntryCollection but it does not appear to do what I am looking for.
I have converted the C# version of the Pinvoke code at
http://www.pinvoke.net/print.aspx/advapi32.QueryServiceObjectSecurity
I found a better Import for the DLL Siginture in a download at VBWin7TriggerStartService Located Here
http://support.microsoft.com/kb/975425[
^]
But this does not have the "QueryServiceObjectSecurity" listed.
I still cannot get it to work and I am messing up the code even worse trying all sorts of changes.
One of the main problems is an Access denied error problem for connecting to the service.
I cannot figure out how to connect to the service to get the handle.
Here is what I have now.
Updated: Repalced the Original code listed with What I have Now.
Moved the API calls to a Class.
I can now return the Handles to the Service Controler and the Service.
Now the problem is getting the DACL out. Appears to be a Memory Mgmt. problem.
I have searched the internet for months trying to find code samples that uses this function.
The only Place that I can find that Shows using it is a C++ Example located here
http://msdn.microsoft.com/en-us/library/ms684215(v=vs.85).aspx[
^]
Any help is appreciated.
Private Sub btnGetInfo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetInfo.Click
Try
Dim SvcName As String
If cbServices.SelectedItem = Nothing Then
MsgBox("No Service Was Selected")
Exit Sub
Else
SvcName = cbServices.SelectedItem.ToString
End If
svcCtlrHandle = ServiceAPI.OpenSCManager(Nothing, Nothing, ServiceControlAccessRights.SC_MANAGER_CONNECT)
'#define ACTRL_READ_CONTROL 0x10000000
'#define SDDL_READ_CONTROL TEXT("RC")
'#define READ_CONTROL (0x00020000L) From Winnt.h
If svcCtlrHandle = Nothing Then
MsgBox("Open Service Controler Failed")
Exit Sub
End If
serviceHandle = ServiceAPI.OpenService(svcCtlrHandle, SvcName, &H20000) 'Read_Control
If serviceHandle = Nothing Then
ServiceAPI.CloseServiceHandle(svcCtlrHandle)
MsgBox("Open Service Failed" & vbNewLine & "Service Controler handle will be released")
Exit Sub
End If
'Dim psd As Byte() = New Byte(-1) {}
If Not ServiceAPI.QueryServiceObjectSecurity(serviceHandle, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, psd, 0, bufSizeNeeded) Then
'Dim err As Integer = Marshal.GetLastWin32Error()
Merr = Err.LastDllError
If Merr = 122 Then
' ERROR_INSUFFICIENT_BUFFER
' expected; now we know bufsize
buffSize = bufSizeNeeded
'psd = CType(HeapAlloc(GetProcessHeap(), ServiceAPI.HeapAllocFlags.HEAP_ZERO_MEMORY, buffSize), SECURITY_DESCRIPTOR)
If Not ServiceAPI.QueryServiceObjectSecurity(serviceHandle, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, psd, buffSize, bufSizeNeeded) Then
MsgBox("Query Service Objet Security Failed ", MsgBoxStyle.Information, "Bummer")
'CleanupPointers()
'Exit Sub
End If
ElseIf Merr <> 122 Or Merr <> 0 Then
MsgBox("Error Number " & Merr.ToString)
CleanupPointers()
Exit Sub
End If
opdacl = GetSecurityDescriptorDacl(psd, Nothing, Nothing, Nothing)
Dim op As String
op = psd.ToString & vbNewLine & opdacl
ElseIf Merr = 6 Then
MsgBox(Merr.ToString)
CleanupPointers()
Exit Sub
Else
CleanupPointers()
Throw New ApplicationException("error calling QueryServiceObjectSecurity() to get DACL for SeaweedService: error code=" + Merr)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub CleanupPointers()
ServiceAPI.CloseServiceHandle(svcCtlrHandle)
ServiceAPI.CloseServiceHandle(serviceHandle)
End Sub