Using QueryServiceConfig with VB.NET

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am attempting to get information from the Win32 API QueryServiceConfig. I
keep getting a 1421 error. I need to know what I am doing wrong. Here is
the code:

<DllImport("advapi32.dll", CharSet:=CharSet.Auto,
entrypoint:="QueryServiceConfigA")> _
Public Shared Function QueryServiceConfig(ByVal hService As Integer, _
ByRef lpServiceConfig As IntPtr, _
ByVal cbBufSize As Long, ByRef pcbBytesNeeded As Long) As Boolean
End Function

<StructLayout(LayoutKind.Sequential)> _
Public Structure QUERY_SERVICE_CONFIG
Public dwServiceType As Integer
Public dwStartType As Integer
Public dwErrorControl As Integer
<MarshalAs(UnmanagedType.LPTStr)> Public lpBinaryPathName As String
<MarshalAs(UnmanagedType.LPTStr)> Public lpLoadOrderGroup As String
Public dwTagId As Integer
<MarshalAs(UnmanagedType.LPTStr)> Public lpDependencies As String
<MarshalAs(UnmanagedType.LPTStr)> Public lpServiceStartName As String
<MarshalAs(UnmanagedType.LPTStr)> Public lpDisplayName As String
End Structure

Public Function RetrieveUserName(ByVal sServiceName As String) As String
Dim iSCManagerHandle As Integer
Dim iSCManagerLockHandle As Integer
Dim iServiceHandle As Integer

Dim bCloseService As Boolean
Dim bUnlockSCManager As Boolean
Dim bCloseSCManager As Boolean


Dim iScActionsPointer As New IntPtr


Try

iSCManagerHandle = OpenSCManager(vbNullString, vbNullString, _
ServiceControlManagerType.SC_MANAGER_ALL_ACCESS)


If iSCManagerHandle < 1 Then
Throw New Exception("Unable to open the Services Manager.")
End If


iSCManagerLockHandle = LockServiceDatabase(iSCManagerHandle)


If iSCManagerLockHandle < 1 Then
Throw New Exception("Unable to lock the Services Manager.")
End If


iServiceHandle = OpenService(iSCManagerHandle, sServiceName, _
ACCESS_TYPE.SERVICE_QUERY_CONFIG)

If iServiceHandle < 1 Then
Throw New Exception("Unable to open the Service for
modification.")
End If

'Allocate memory for struct.
Dim oQSC As New QUERY_SERVICE_CONFIG

Dim bQuery As Boolean
Dim lBytesNeeded As Long

bQuery = QueryServiceConfig(iServiceHandle, oQSC, 0, lBytesNeeded)

MsgBox(Marshal.GetLastWin32Error())
If Not bQuery Then
Throw New Exception("Unable to query the Service settings.")
End If

Catch ex As Exception
Throw ex
Finally
'Once you are done you should close/release the handles to the
service()
'and the Service Control Manager, as well as free the memory
that(held)
'the array of SC_ACTION structures.


Marshal.FreeHGlobal(iScActionsPointer)
If iServiceHandle > 0 Then
bCloseService = CloseServiceHandle(iServiceHandle)
End If


bUnlockSCManager = UnlockServiceDatabase(iSCManagerLockHandle)


If iSCManagerHandle > 0 Then
bCloseSCManager = CloseServiceHandle(iSCManagerHandle)
End If
End Try
End Function


Note: I get a valid handle from the OpenService call.
 
Hi

You may try to pass the QUERY_SERVICE_CONFIG's structure on an unmanaged
heap with the managed intptr pointed to it.
Here is the sample which works on my side.

Imports System.Runtime.InteropServices
Module Module3
Private Const SC_MANAGER_CONNECT = 1
Private Const SERVICE_QUERY_CONFIG = 1
Private Const SERVICE_CHANGE_CONFIG = 2
Private Const SERVICE_INTERACTIVE_PROCESS = &H100
Private Const ERROR_INSUFFICIENT_BUFFER = 122
Private Const SERVICE_NO_CHANGE = &HFFFFFFFF

<StructLayout(LayoutKind.Sequential)> _
Private Structure QUERY_SERVICE_CONFIG
Public dwServiceType As Integer
Public dwStartType As Integer
Public dwErrorControl As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public pBinaryPathName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pLoadOrderGroup As String
Public dwTagId As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public pDependencies As String
<MarshalAs(UnmanagedType.LPWStr)> Public pServiceStartName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDisplayName As String
End Structure

<DllImport("advapi32.dll", EntryPoint:="OpenSCManagerW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
OpenSCManager(ByVal sMachineName As String, _
ByVal sDatabaseName As String, _
ByVal dwDesiredAction As Integer) As IntPtr
End Function

<DllImport("advapi32.dll", EntryPoint:="OpenServiceW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
OpenService(ByVal hSCM As IntPtr, _
ByVal sServiceName As String, _
ByVal dwDesiredAction As Integer) As IntPtr
End Function

<DllImport("advapi32.dll", EntryPoint:="CloseServiceHandle",
SetLastError:=True, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Function _
CloseServiceHandle(ByVal hSCHandle As IntPtr) As Boolean
End Function

<DllImport("advapi32.dll", EntryPoint:="QueryServiceConfigW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
QueryServiceConfig(ByVal hService As IntPtr, _
ByVal pBuffer As IntPtr, _
ByVal cbBufSize As Integer, _
ByRef pcbBytesNeeded As Integer) As Boolean
End Function

<DllImport("advapi32.dll", EntryPoint:="ChangeServiceConfigW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
ChangeServiceConfig(ByVal hService As IntPtr, _
ByVal dwServiceType As Integer, _
ByVal dwStartType As Integer, _
ByVal dwErrorControl As Integer, _
ByVal pBinaryPathName As IntPtr, _
ByVal pLoadOrderGroup As IntPtr, _
ByVal pdwTagId As IntPtr, _
ByVal pDependencies As IntPtr, _
ByVal pServiceStartName As IntPtr, _
ByVal pPassword As IntPtr, _
ByVal pDisplayName As IntPtr) As Boolean
End Function
Public Sub main()
MakeServiceInteractive("Themes")
End Sub
Private Function MakeServiceInteractive(ByVal sServiceName As String)
As Boolean

Dim pBuffer As IntPtr
Dim ServiceConfig As QUERY_SERVICE_CONFIG
Dim cbServiceConfig As Integer

Dim hSCM As IntPtr
Dim hService As IntPtr
Dim dwTagId As Integer
Dim fResult As Boolean

MakeServiceInteractive = False

Try

dwTagId = 0

hSCM = OpenSCManager(Nothing, Nothing, SC_MANAGER_CONNECT)
If hSCM.Equals(0) Then
MsgBox("OpenSCManager() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

hService = OpenService(hSCM, sServiceName, _
SERVICE_QUERY_CONFIG Or SERVICE_CHANGE_CONFIG)
If hService.Equals(0) Then
MsgBox("OpenService() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

fResult = QueryServiceConfig(hService, pBuffer, _
cbServiceConfig, cbServiceConfig)
If Not fResult Then
If Marshal.GetLastWin32Error <> ERROR_INSUFFICIENT_BUFFER
Then
MsgBox("QueryServiceConfig() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If
End If

pBuffer = Marshal.AllocHGlobal(cbServiceConfig)

fResult = QueryServiceConfig(hService, pBuffer, _
cbServiceConfig, cbServiceConfig)
If Not fResult Then
MsgBox("QueryServiceConfig() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

ServiceConfig = Marshal.PtrToStructure(pBuffer,
GetType(QUERY_SERVICE_CONFIG))
Console.WriteLine(ServiceConfig.pBinaryPathName)
Finally

CloseServiceHandle(hSCM)
CloseServiceHandle(hService)

If Not pBuffer.Equals(0) Then
Marshal.FreeHGlobal(pBuffer)
End If

End Try

End Function

End Module




Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
That is exactly what I needed. Thank you.

"Peter Huang" said:
Hi

You may try to pass the QUERY_SERVICE_CONFIG's structure on an unmanaged
heap with the managed intptr pointed to it.
Here is the sample which works on my side.

Imports System.Runtime.InteropServices
Module Module3
Private Const SC_MANAGER_CONNECT = 1
Private Const SERVICE_QUERY_CONFIG = 1
Private Const SERVICE_CHANGE_CONFIG = 2
Private Const SERVICE_INTERACTIVE_PROCESS = &H100
Private Const ERROR_INSUFFICIENT_BUFFER = 122
Private Const SERVICE_NO_CHANGE = &HFFFFFFFF

<StructLayout(LayoutKind.Sequential)> _
Private Structure QUERY_SERVICE_CONFIG
Public dwServiceType As Integer
Public dwStartType As Integer
Public dwErrorControl As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public pBinaryPathName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pLoadOrderGroup As String
Public dwTagId As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public pDependencies As String
<MarshalAs(UnmanagedType.LPWStr)> Public pServiceStartName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDisplayName As String
End Structure

<DllImport("advapi32.dll", EntryPoint:="OpenSCManagerW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
OpenSCManager(ByVal sMachineName As String, _
ByVal sDatabaseName As String, _
ByVal dwDesiredAction As Integer) As IntPtr
End Function

<DllImport("advapi32.dll", EntryPoint:="OpenServiceW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
OpenService(ByVal hSCM As IntPtr, _
ByVal sServiceName As String, _
ByVal dwDesiredAction As Integer) As IntPtr
End Function

<DllImport("advapi32.dll", EntryPoint:="CloseServiceHandle",
SetLastError:=True, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Function _
CloseServiceHandle(ByVal hSCHandle As IntPtr) As Boolean
End Function

<DllImport("advapi32.dll", EntryPoint:="QueryServiceConfigW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
QueryServiceConfig(ByVal hService As IntPtr, _
ByVal pBuffer As IntPtr, _
ByVal cbBufSize As Integer, _
ByRef pcbBytesNeeded As Integer) As Boolean
End Function

<DllImport("advapi32.dll", EntryPoint:="ChangeServiceConfigW",
SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Function _
ChangeServiceConfig(ByVal hService As IntPtr, _
ByVal dwServiceType As Integer, _
ByVal dwStartType As Integer, _
ByVal dwErrorControl As Integer, _
ByVal pBinaryPathName As IntPtr, _
ByVal pLoadOrderGroup As IntPtr, _
ByVal pdwTagId As IntPtr, _
ByVal pDependencies As IntPtr, _
ByVal pServiceStartName As IntPtr, _
ByVal pPassword As IntPtr, _
ByVal pDisplayName As IntPtr) As Boolean
End Function
Public Sub main()
MakeServiceInteractive("Themes")
End Sub
Private Function MakeServiceInteractive(ByVal sServiceName As String)
As Boolean

Dim pBuffer As IntPtr
Dim ServiceConfig As QUERY_SERVICE_CONFIG
Dim cbServiceConfig As Integer

Dim hSCM As IntPtr
Dim hService As IntPtr
Dim dwTagId As Integer
Dim fResult As Boolean

MakeServiceInteractive = False

Try

dwTagId = 0

hSCM = OpenSCManager(Nothing, Nothing, SC_MANAGER_CONNECT)
If hSCM.Equals(0) Then
MsgBox("OpenSCManager() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

hService = OpenService(hSCM, sServiceName, _
SERVICE_QUERY_CONFIG Or SERVICE_CHANGE_CONFIG)
If hService.Equals(0) Then
MsgBox("OpenService() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

fResult = QueryServiceConfig(hService, pBuffer, _
cbServiceConfig, cbServiceConfig)
If Not fResult Then
If Marshal.GetLastWin32Error <> ERROR_INSUFFICIENT_BUFFER
Then
MsgBox("QueryServiceConfig() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If
End If

pBuffer = Marshal.AllocHGlobal(cbServiceConfig)

fResult = QueryServiceConfig(hService, pBuffer, _
cbServiceConfig, cbServiceConfig)
If Not fResult Then
MsgBox("QueryServiceConfig() failed with error " &
Marshal.GetLastWin32Error(), _
MsgBoxStyle.Exclamation, "Error")
Exit Try
End If

ServiceConfig = Marshal.PtrToStructure(pBuffer,
GetType(QUERY_SERVICE_CONFIG))
Console.WriteLine(ServiceConfig.pBinaryPathName)
Finally

CloseServiceHandle(hSCM)
CloseServiceHandle(hService)

If Not pBuffer.Equals(0) Then
Marshal.FreeHGlobal(pBuffer)
End If

End Try

End Function

End Module




Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi

I am glad that works for you.
If you still have any other question, please feel free to post in the
newsgroup.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top