Results 1 to 19 of 19

Thread: [RESOLVED] WMI Win32_Service Create Fails when No User Logged On

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Resolved [RESOLVED] WMI Win32_Service Create Fails when No User Logged On

    Hello,

    For some reason the following code works perfectly fine if a user is logged into a machine but if no one is logged in, I receive the error message "Call was canceled by the message filter. (Exception from HRESULT: 0x80010002 (RPC_E_CALL_CANCELED))"

    I know it is possible somehow to create the service on the remote machine even if a user is not logged in but what must I change in my code??

    Code:
    	Private Function CreateRemoteService(ByVal HostName As String, ByVal Name As String, ByVal DisplayName As String, ByVal Process As String) As Boolean
    		Try
    			Dim wmiOptions As New ConnectionOptions
    
    			wmiOptions.Impersonation = ImpersonationLevel.Impersonate
    			wmiOptions.Authentication = AuthenticationLevel.PacketPrivacy
    
    			Dim wmiPath As New ManagementPath("\\" & HostName & "\root\cimv2:Win32_Service")
    			Dim wmiScope As New ManagementScope(wmiPath, wmiOptions)
    
    			wmiScope.Connect()
    
    			Dim wmiGetOptions As New ObjectGetOptions
    
    			Dim wmi_Win32_Process_Class As New ManagementClass(wmiScope, wmiPath, wmiGetOptions)
    			Dim wmi_inParams As ManagementBaseObject = wmi_Win32_Process_Class.GetMethodParameters("Create")
    
    			wmi_inParams("Name") = Name
    			wmi_inParams("DisplayName") = DisplayName
    			wmi_inParams("PathName") = Process
    			wmi_inParams("StartMode") = "Manual"
    			wmi_inParams("DesktopInteract") = True
    
    			Dim wmi_outParams As ManagementBaseObject = wmi_Win32_Process_Class.InvokeMethod("Create", wmi_inParams, Nothing)
    
    			CreateRemoteService = True
    		Catch ex As Exception
    			MsgBox(ex.Message)
    			CreateRemoteService = False
    		End Try
    	End Function

  2. #2
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    I know this is not directly a solution to your problem but you could try using SC.exe instead of WMI (I hate WMI precisely because of random problems like this). SC.exe is part of every version of Windows since XP (or maybe even 2000) so you can just call it straight from Process.Start.
    If you open Command Prompt on your computer and just type sc /? then you will see the arguments it accepts and how to use it. You can also type a specific argument followed by /? to see more info on it, so for example the Create argument is the one you would be interested in so: sc create /?

    Oh and yes you can use SC against a remote computer
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Is there no way to call sc from a library or something instead of running another process? There has got to be some other way to do this. I didn't spend months working on re-creating PSEXEC to end up having to use a third-party executable to get the work done. LoL. If this is my only option then I guess that I will have to use SC but there must be some way!


    Just F.Y.I. though Chris, I have suceeded in re-producing most of the functions that PSEXEC does in an interactive state, unfortunately, I've not been allowed to post the final code due to the copywrite issues caused by creating this application on a corporate pc. I will however, explain what I have done in as much detail as possible, and it might help others with trying to obtain the same results. I am still getting around to re-directing standard input, output, and error for processes that will be ran on the machine non-interactively. If you have a link to any examples of real time re-directing the standard input/output/error, it would be much appreciated. I have tried this before but for some reason I didn't obtain the results until after the process ended.

  4. #4
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    Quote Originally Posted by taigon View Post
    Is there no way to call sc from a library or something instead of running another process? There has got to be some other way to do this. I didn't spend months working on re-creating PSEXEC to end up having to use a third-party executable to get the work done. LoL. If this is my only option then I guess that I will have to use SC but there must be some way!
    lol fair enough - I dont think you can call SC directly from a library but I'm sure there will be a Windows API you can call. If not then its not actually much work to create a service yourself, its just a few registry entries, though there may be more stuff that should be done in the background that will get done when you use the API or SC.exe (I'm sure I've manually created them via registry entries in the past successfully though)

    If you have a link to any examples of real time re-directing the standard input/output/error, it would be much appreciated. I have tried this before but for some reason I didn't obtain the results until after the process ended.
    Some of the posts from cicatrix in this thread might be of use: http://www.vbforums.com/showthread.php?t=616099
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  5. #5
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    Here you go, CreateService API looks like it will do what you want http://msdn.microsoft.com/en-us/libr...50(VS.85).aspx
    Combine it with OpenSCManager (http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx) and you should be able to get it to work remotely. I'm sure that will be what SC.exe uses internally anyway.

    Personally I would much rather use those APIs than WMI. I'm probably going to add a simple .NET wrapper for those two APIs to my API Pack (http://www.vbforums.com/showthread.php?t=616861) so that it is easy for people to create services from .NET code, so if you do decide to go down the API route and get it working before me I wouldn't mind seeing some of the code
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Thanks a lot for the links! That is my next project, to figure out the CreateService API, I only have 1 hour left at work so I may not have that done tonight, but certainly by tomorrow. I will let you know how it turns out. And that is definately a good idea, creating .NET wrappers for the API. One of these days, I will probably take all of my code and do the same.

    Talk to you later.

  7. #7
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    Cool let me know if you do get it working and good luck Not sure if I want to try get CreateService working first or try and put my theory of using NtQueryProcessInformation into use as mentioned in this thread http://www.vbforums.com/showthread.php?t=617477 ... decisions decisions.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    I wonder if that would work for the applet I created to list the running processes on the remote machine and then continuously calculate the CPU usage using WMI...

  9. #9
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    I'm not sure I follow you - I assume you are referring to the NtQueryInformationProcess API I mentioned but I dont think it gives you any kind of performance data - be better off using the PerformanceCounter class for that.
    By the way I decided to start trying to get this NtQueryInformationProcess working before starting on CreateService but god its a pain to work with... everything in all of the structures that I have to use with it has to be declared as IntPtr and then I have to manually get the data at that address from the pointer for the values Im interested in (if that makes sense). Its probably because its an internal API and isnt really meant to be called by normal applications, just the OS itself, but there is no other API that I can find to get simple information about a process such as its parent ID or command line arguments
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  10. #10
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    Re: WMI Win32_Service Create Fails when No User Logged On

    Btw the problem you have was sometimes reported to be due to firewall blocking reasons.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    I'm not so sure about it being a firewall dropping the connection because as soon as someone is logged into the machine, the WMI code works fine. I'm going to start working on the CreateService API.

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Well,

    Here is the class to create the remote service and it seems to work.

    Code:
    Imports System.Runtime.InteropServices
    
    Public Class WindowsService
    #Region "API"
    	'API required to open the service control manager.
    	Private Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" (ByVal lpMachineName As String, ByVal lpDatabaseName As String, ByVal dwDesiredAccess As Integer) As Integer
    	'API to create the service.
    	Private Declare Auto Function CreateService Lib "advapi32.dll" (ByVal hSCManager As IntPtr, ByVal lpServiceName As String, ByVal lpDisplayName As String, ByVal dwDesiredAccess As Int32, ByVal dwServiceType As Int32, ByVal dwStartType As Int32, ByVal dwErrorControl As Int32, ByVal lpBinaryPathName As String, ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As Int32, ByVal lpDependencies As String, ByVal serviceStartName As String, ByVal lpPassword As String) As IntPtr
    #End Region
    
    #Region "CONST"
    	'Service Control Manager Security Rights
    	Private Const SC_MANAGER_QUERY_LOCK_STATUS = &H10
    	Private Const SC_MANAGER_CONNECT As Int32 = &H1
    	Private Const SC_MANAGER_CREATE_SERVICE As Int32 = &H2
    	Private Const SC_MANAGER_ENUMERATE_SERVICE As Int32 = &H4
    	Private Const SC_MANAGER_LOCK As Int32 = &H8
    	Private Const SC_MANAGER_MODIFY_BOOT_CONFIG As Int32 = &H20
    
    	Private Const SC_MANAGER_ALL_ACCESS As Int32 = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED Or _
    	  SC_MANAGER_CONNECT Or _
    	  SC_MANAGER_CREATE_SERVICE Or _
    	  SC_MANAGER_ENUMERATE_SERVICE Or _
    	  SC_MANAGER_LOCK Or _
    	  SC_MANAGER_QUERY_LOCK_STATUS Or _
    	  SC_MANAGER_MODIFY_BOOT_CONFIG
    
    	'Service Type Constants
    	Private Const SERVICE_WIN32_OWN_PROCESS As Int32 = &H10
    	Private Const SERVICE_INTERACTIVE_PROCESS As Int32 = &H100
    
    	'Service Startup Constants
    	Private Const SERVICE_DEMAND_START As Int32 = &H3
    
    	'Service Error Constants
    	Private Const SERVICE_ERROR_NORMAL As Int32 = &H1
    #End Region
    
    #Region "Enum"
    	<Flags()> Private Enum ACCESS_MASK : Uint32
    		DELETE = &H10000
    		READ_CONTROL = &H20000
    		WRITE_DAC = &H40000
    		WRITE_OWNER = &H80000
    		SYNCHRONIZE = &H100000
    
    		STANDARD_RIGHTS_REQUIRED = &HF0000
    
    		STANDARD_RIGHTS_READ = &H20000
    		STANDARD_RIGHTS_WRITE = &H20000
    		STANDARD_RIGHTS_EXECUTE = &H20000
    
    		STANDARD_RIGHTS_ALL = &H1F0000
    
    		SPECIFIC_RIGHTS_ALL = &HFFFF
    
    		ACCESS_SYSTEM_SECURITY = &H1000000
    
    		MAXIMUM_ALLOWED = &H2000000
    
    		GENERIC_READ = &H80000000
    		GENERIC_WRITE = &H40000000
    		GENERIC_EXECUTE = &H20000000
    		GENERIC_ALL = &H10000000
    
    		DESKTOP_READOBJECTS = &H1
    		DESKTOP_CREATEWINDOW = &H2
    		DESKTOP_CREATEMENU = &H4
    		DESKTOP_HOOKCONTROL = &H8
    		DESKTOP_JOURNALRECORD = &H10
    		DESKTOP_JOURNALPLAYBACK = &H20
    		DESKTOP_ENUMERATE = &H40
    		DESKTOP_WRITEOBJECTS = &H80
    		DESKTOP_SWITCHDESKTOP = &H100
    
    		WINSTA_ENUMDESKTOPS = &H1
    		WINSTA_READATTRIBUTES = &H2
    		WINSTA_ACCESSCLIPBOARD = &H4
    		WINSTA_CREATEDESKTOP = &H8
    		WINSTA_WRITEATTRIBUTES = &H10
    		WINSTA_ACCESSGLOBALATOMS = &H20
    		WINSTA_EXITWINDOWS = &H40
    		WINSTA_ENUMERATE = &H100
    		WINSTA_READSCREEN = &H200
    
    		WINSTA_ALL_ACCESS = &H37F
    	End Enum
    
    	'Service Security Rights
    	<Flags()> Private Enum SERVICE_ACCESS As UInteger
    		SERVICE_QUERY_CONFIG = &H1
    		SERVICE_CHANGE_CONFIG = &H2
    		SERVICE_QUERY_STATUS = &H4
    		SERVICE_ENUMERATE_DEPENDENTS = &H8
    		SERVICE_START = &H10
    		SERVICE_STOP = &H20
    		SERVICE_PAUSE_CONTINUE = &H40
    		SERVICE_INTERROGATE = &H80
    		SERVICE_USER_DEFINED_CONTROL = &H100
    
    		SERVICE_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_REQUIRED Or _
    		  SERVICE_QUERY_CONFIG Or _
    		  SERVICE_CHANGE_CONFIG Or _
    		   SERVICE_ENUMERATE_DEPENDENTS Or _
    		 SERVICE_START Or _
    		 SERVICE_STOP Or _
    		 SERVICE_PAUSE_CONTINUE Or _
    		 SERVICE_INTERROGATE Or _
    		 SERVICE_USER_DEFINED_CONTROL)
    
    		GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ Or _
    		  SERVICE_QUERY_CONFIG Or _
    		   SERVICE_QUERY_STATUS Or _
    		  SERVICE_INTERROGATE Or _
    		 SERVICE_ENUMERATE_DEPENDENTS
    
    		GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE Or _
    		  SERVICE_CHANGE_CONFIG
    
    		GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE Or _
    		  SERVICE_START Or _
    		 SERVICE_STOP Or _
    		   SERVICE_PAUSE_CONTINUE Or _
    		  SERVICE_USER_DEFINED_CONTROL
    
    		ACCESS_SYSTEM_SECURITY = ACCESS_MASK.ACCESS_SYSTEM_SECURITY
    		DELETE = ACCESS_MASK.DELETE
    		READ_CONTROL = ACCESS_MASK.READ_CONTROL
    		WRITE_DAC = ACCESS_MASK.WRITE_DAC
    		WRITE_OWNER = ACCESS_MASK.WRITE_OWNER
    	End Enum
    #End Region
    
    	Private Function OpenServiceController(ByVal HostName As String) As IntPtr
    		Dim p_SCM As IntPtr = IntPtr.Zero 'API return pointer to service control manager database.
    
    		p_SCM = OpenSCManager(HostName, Nothing, SC_MANAGER_ALL_ACCESS)	'API call to obtain handle.
    
    		Return p_SCM 'If p_SCM is nothing then call failed.
    	End Function
    
    	Public Function Create(ByVal HostName As String, ByVal ServiceName As String, ByVal DisplayName As String, ByVal BinaryPath As String) As IntPtr
    		Dim p_SCManager As IntPtr = OpenServiceController(HostName)	'Obtain pointer to service control manager database
    
    		If p_SCManager = Nothing Then
    			Console.WriteLine("Error obtaining pointer to SCM database: Error#" & Marshal.GetLastWin32Error.ToString)
    			Return Nothing
    		End If
    
    		'Create the service and return the pointer to the service. Value is null if call fails.
    		Dim p_SVCHandle As IntPtr = CreateService(p_SCManager, ServiceName, DisplayName, SERVICE_ACCESS.SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS Or SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, BinaryPath, Nothing, 0, Nothing, Nothing, Nothing)
    
    		Return p_SVCHandle 'Return the pointer to the service.
    
    	End Function
    End Class
    and here is the calling code

    Code:
    		Dim sc As New WindowsService
    
    		Dim p_svcPtr As IntPtr = sc.Create(HostName, "nRP", "NiRDs Remote Process", "C:\Windows\System32\nRP.exe")
    
    		If p_svcPtr = Nothing Then
    			Invoke(InvokeStatus, "Unable to create remote service! Error#" & Marshal.GetLastWin32Error.ToString)
    			Invoke(InvokeDone)
    			Exit Sub
    		Else
    			Invoke(InvokeStatus, "Sucessfully created remote service!")
    CloseServiceHandle(p_svcPtr)
    end if

  13. #13
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    Nice one and thanks for posting the code! I hadn't got round to trying to get CreateService working yet as I'm still struggling with reading the PEB (process environment block) from an external process via NtQueryInformationProcess as mentioned in the last post, so I'm sure when I come to trying to write my wrapper for CreateService your code will be a good reference

    So does it do exactly what you wanted then? even when no one is logged in?
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    I still need to test it now without someone logged into the machine but here is the complete code that replaces SC for my purposes anyway. I'm not going to post the calling code as it is self explanitory but here is the class.

    Code:
    Imports System.Runtime.InteropServices
    
    Public Class WindowsService
    #Region "API"
    	'API required to open the service control manager.
    	Private Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" (ByVal lpMachineName As String, ByVal lpDatabaseName As String, ByVal dwDesiredAccess As Integer) As Integer
    	'API to create the service.
    	Private Declare Auto Function CreateService Lib "advapi32.dll" (ByVal hSCManager As IntPtr, ByVal lpServiceName As String, ByVal lpDisplayName As String, ByVal dwDesiredAccess As Int32, ByVal dwServiceType As Int32, ByVal dwStartType As Int32, ByVal dwErrorControl As Int32, ByVal lpBinaryPathName As String, ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As Int32, ByVal lpDependencies As String, ByVal serviceStartName As String, ByVal lpPassword As String) As IntPtr
    	Private Declare Auto Function StartService Lib "advapi32.dll" (ByVal hService As IntPtr, ByVal dwNumServiceArgs As Int32, ByVal lpServiceArgVectors As String) As Boolean
    	Private Declare Auto Function ControlService Lib "advapi32.dll" (ByVal hService As IntPtr, ByVal dwControl As Int32, ByRef lpServiceStatus As SERVICE_STATUS) As Boolean
    	Private Declare Auto Function QueryServiceStatus Lib "advapi32.dll" (ByVal hService As IntPtr, ByRef lpServiceStatus As SERVICE_STATUS) As Boolean
    	Private Declare Auto Function DeleteService Lib "advapi32.dll" (ByVal hService As IntPtr) As Boolean
    #End Region
    
    #Region "CONST"
    	'Service Control Manager Security Rights
    	Private Const SC_MANAGER_QUERY_LOCK_STATUS = &H10
    	Private Const SC_MANAGER_CONNECT As Int32 = &H1
    	Private Const SC_MANAGER_CREATE_SERVICE As Int32 = &H2
    	Private Const SC_MANAGER_ENUMERATE_SERVICE As Int32 = &H4
    	Private Const SC_MANAGER_LOCK As Int32 = &H8
    	Private Const SC_MANAGER_MODIFY_BOOT_CONFIG As Int32 = &H20
    
    	Private Const SC_MANAGER_ALL_ACCESS As Int32 = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED Or _
    	  SC_MANAGER_CONNECT Or _
    	  SC_MANAGER_CREATE_SERVICE Or _
    	  SC_MANAGER_ENUMERATE_SERVICE Or _
    	  SC_MANAGER_LOCK Or _
    	  SC_MANAGER_QUERY_LOCK_STATUS Or _
    	  SC_MANAGER_MODIFY_BOOT_CONFIG
    
    	'Service Type Constants
    	Private Const SERVICE_WIN32_OWN_PROCESS As Int32 = &H10
    	Private Const SERVICE_INTERACTIVE_PROCESS As Int32 = &H100
    
    	'Service Startup Constants
    	Private Const SERVICE_DEMAND_START As Int32 = &H3
    
    	'Service Error Constants
    	Private Const SERVICE_ERROR_NORMAL As Int32 = &H1
    #End Region
    
    #Region "Enum"
    	<Flags()> Private Enum ACCESS_MASK : Uint32
    		DELETE = &H10000
    		READ_CONTROL = &H20000
    		WRITE_DAC = &H40000
    		WRITE_OWNER = &H80000
    		SYNCHRONIZE = &H100000
    
    		STANDARD_RIGHTS_REQUIRED = &HF0000
    
    		STANDARD_RIGHTS_READ = &H20000
    		STANDARD_RIGHTS_WRITE = &H20000
    		STANDARD_RIGHTS_EXECUTE = &H20000
    
    		STANDARD_RIGHTS_ALL = &H1F0000
    
    		SPECIFIC_RIGHTS_ALL = &HFFFF
    
    		ACCESS_SYSTEM_SECURITY = &H1000000
    
    		MAXIMUM_ALLOWED = &H2000000
    
    		GENERIC_READ = &H80000000
    		GENERIC_WRITE = &H40000000
    		GENERIC_EXECUTE = &H20000000
    		GENERIC_ALL = &H10000000
    
    		DESKTOP_READOBJECTS = &H1
    		DESKTOP_CREATEWINDOW = &H2
    		DESKTOP_CREATEMENU = &H4
    		DESKTOP_HOOKCONTROL = &H8
    		DESKTOP_JOURNALRECORD = &H10
    		DESKTOP_JOURNALPLAYBACK = &H20
    		DESKTOP_ENUMERATE = &H40
    		DESKTOP_WRITEOBJECTS = &H80
    		DESKTOP_SWITCHDESKTOP = &H100
    
    		WINSTA_ENUMDESKTOPS = &H1
    		WINSTA_READATTRIBUTES = &H2
    		WINSTA_ACCESSCLIPBOARD = &H4
    		WINSTA_CREATEDESKTOP = &H8
    		WINSTA_WRITEATTRIBUTES = &H10
    		WINSTA_ACCESSGLOBALATOMS = &H20
    		WINSTA_EXITWINDOWS = &H40
    		WINSTA_ENUMERATE = &H100
    		WINSTA_READSCREEN = &H200
    
    		WINSTA_ALL_ACCESS = &H37F
    	End Enum
    
    	'Service Security Rights
    	<Flags()> Private Enum SERVICE_ACCESS As UInteger
    		SERVICE_QUERY_CONFIG = &H1
    		SERVICE_CHANGE_CONFIG = &H2
    		SERVICE_QUERY_STATUS = &H4
    		SERVICE_ENUMERATE_DEPENDENTS = &H8
    		SERVICE_START = &H10
    		SERVICE_STOP = &H20
    		SERVICE_PAUSE_CONTINUE = &H40
    		SERVICE_INTERROGATE = &H80
    		SERVICE_USER_DEFINED_CONTROL = &H100
    
    		SERVICE_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_REQUIRED Or _
    		  SERVICE_QUERY_CONFIG Or _
    		  SERVICE_CHANGE_CONFIG Or _
    		   SERVICE_ENUMERATE_DEPENDENTS Or _
    		 SERVICE_START Or _
    		 SERVICE_STOP Or _
    		 SERVICE_PAUSE_CONTINUE Or _
    		 SERVICE_INTERROGATE Or _
    		 SERVICE_USER_DEFINED_CONTROL Or _
    		 SERVICE_QUERY_STATUS)
    
    		GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ Or _
    		  SERVICE_QUERY_CONFIG Or _
    		   SERVICE_QUERY_STATUS Or _
    		  SERVICE_INTERROGATE Or _
    		 SERVICE_ENUMERATE_DEPENDENTS
    
    		GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE Or _
    		  SERVICE_CHANGE_CONFIG
    
    		GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE Or _
    		  SERVICE_START Or _
    		 SERVICE_STOP Or _
    		   SERVICE_PAUSE_CONTINUE Or _
    		  SERVICE_USER_DEFINED_CONTROL
    
    		ACCESS_SYSTEM_SECURITY = ACCESS_MASK.ACCESS_SYSTEM_SECURITY
    		DELETE = ACCESS_MASK.DELETE
    		READ_CONTROL = ACCESS_MASK.READ_CONTROL
    		WRITE_DAC = ACCESS_MASK.WRITE_DAC
    		WRITE_OWNER = ACCESS_MASK.WRITE_OWNER
    	End Enum
    
    	'Service states
    	Public Enum SERVICE_STATE
    		SERVICE_CONTINUE_PENDING = &H5
    		SERVICE_PAUSE_PENDING = &H6
    		SERVICE_PAUSED = &H7
    		SERVICE_RUNNING = &H4
    		SERVICE_START_PENDING = &H2
    		SERVICE_STOP_PENDING = &H3
    		SERVICE_STOPPED = &H1
    	End Enum
    #End Region
    
    #Region "Struct"
    	Public Structure SERVICE_STATUS
    		Public dwServiceType As Int32
    		Public dwCurrentState As Int32
    		Public dwControlsAccepted As Int32
    		Public dwWin32ExitCode As Int32
    		Public dwServiceSpecificExitCode As Int32
    		Public dwCheckPoint As Int32
    		Public dwWaitHint As Int32
    	End Structure
    #End Region
    
    	Private Function OpenServiceController(ByVal HostName As String) As IntPtr
    		Dim p_SCM As IntPtr = IntPtr.Zero 'API return pointer to service control manager database.
    
    		p_SCM = OpenSCManager(HostName, Nothing, SC_MANAGER_ALL_ACCESS)	'API call to obtain handle.
    
    		Return p_SCM 'If p_SCM is nothing then call failed.
    	End Function
    
    	Public Function Create(ByVal HostName As String, ByVal ServiceName As String, ByVal DisplayName As String, ByVal BinaryPath As String) As IntPtr
    		Dim p_SCManager As IntPtr = OpenServiceController(HostName)	'Obtain pointer to service control manager database
    
    		If p_SCManager = Nothing Then
    			Console.WriteLine("Error obtaining pointer to SCM database: Error#" & Marshal.GetLastWin32Error.ToString)
    			Return Nothing
    		End If
    
    		'Create the service and return the pointer to the service. Value is null if call fails.
    		Dim p_SVCHandle As IntPtr = CreateService(p_SCManager, ServiceName, DisplayName, SERVICE_ACCESS.SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS Or SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, BinaryPath, Nothing, 0, Nothing, Nothing, Nothing)
    
    		Return p_SVCHandle 'Return the pointer to the service.
    	End Function
    
    	Public Function Start(ByVal p_Service As IntPtr) As Boolean
    		If StartService(p_Service, 0, Nothing) = True Then
    			Return True
    		Else
    			Console.WriteLine("Error starting service: Error#" & Marshal.GetLastWin32Error.ToString)
    			Return False
    		End If
    	End Function
    
    	Public Function cStop(ByVal p_Service As IntPtr) As Boolean
    		Dim ss As New SERVICE_STATUS
    
    		ss = Control(p_Service, &H1)
    
    		If ss.dwCurrentState = Nothing Then
    			Return False
    		Else
    			Return True
    		End If
    	End Function
    
    	Public Function Delete(ByVal p_Service As IntPtr) As Boolean
    		If DeleteService(p_Service) = True Then
    			Return True
    		Else
    			Console.WriteLine("Error deleting service: Error#" & Marshal.GetLastWin32Error.ToString)
    			Return False
    		End If
    	End Function
    
    	Public Function Control(ByVal p_Service As IntPtr, ByVal ControlCode As Int32) As SERVICE_STATUS
    		Dim SS As New SERVICE_STATUS
    
    		If ControlService(p_Service, ControlCode, SS) = True Then
    			Control = SS
    		Else
    			Console.WriteLine("Error controlling service: Error#" & Marshal.GetLastWin32Error.ToString)
    			Control = Nothing
    		End If
    	End Function
    
    	Public Function GetStatus(ByVal p_Service As IntPtr) As SERVICE_STATUS
    		Dim SS As New SERVICE_STATUS
    
    		If QueryServiceStatus(p_Service, SS) = True Then
    			GetStatus = SS
    		Else
    			Console.WriteLine("Error querying service status: Error#" & Marshal.GetLastWin32Error.ToString)
    			GetStatus = Nothing
    		End If
    	End Function
    End Class

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Maybe you can also help me find some API that will allow me to check who the currently logged in user is and if no user is logged in, to report that back to me. I'm currently using WMI, but yet again, it seems to be quite unstable. It works on most machines when a user is logged in but when no one is logged in, the calls fail.

    Code:
    	Public Function GetCurrentUser() As Boolean
    		Try
    			Dim MyConnectionOptions As New System.Management.ConnectionOptions
    			MyConnectionOptions.Authentication = AuthenticationLevel.Connect
    			MyConnectionOptions.EnablePrivileges = True
    			MyConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
    
    			Dim MScope As New ManagementScope("\\" & HostName & "\root\cimv2")
    			Dim OQ As New ObjectQuery("SELECT * FROM WIN32_ComputerSystem")
    			Dim MS As New ManagementObjectSearcher(MScope, OQ)
    			Dim MC As ManagementObjectCollection = Nothing
    
    			Try
    				MC = MS.Get
    
    			Catch ex As System.Runtime.InteropServices.COMException
    				If ex.Message = "The RPC server is unavailable." And ex.Source = "System.Management" Then
    					MsgBox("The machine may be shutdown or RPC Server is not running on that machine.")
    				End If
    			Catch ex As Exception
    				MsgBox("Other" & ex.ToString)
    			End Try
    
    			Dim MO As ManagementObject
    
    			For Each MO In MC
    				CurrentUser = MO("UserName")
    				Exit For
    			Next
    
    			Return True
    		Catch ex As Exception
    			If ex.Message = "Object reference not set to an instance of an object." And ex.Source = "NiRDs" Then
    				MsgBox(HostName & " no user is currently logged in!")
    				rdoCurrent.Visible = False
    				cbInteractive.Checked = False
    				cbInteractive.Visible = False
    				rdoSystemAccount.Checked = True
    			Else
    				MsgBox(ex.ToString)
    				Me.Dispose()
    			End If
    		End Try
    
    		Return False
    
    	End Function

  16. #16

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    I just tried using this to create a process on the remote machine while no one is logged in, and it worked perfectly! now to start working on re-directing the input/output/error. Also I still need to validate whether or not a user is logged in to determine an interactive process or not.

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Actually, I finally created a class that will return the first logged on user which should work for what I need to do

    Code:
    Imports System.Net.NetworkInformation
    Imports System.Text
    Imports System.Collections.Specialized
    Imports System.Runtime.InteropServices
    
    Public Class NetworkTools
    
    #Region "API"
    	' ******** Code Start ********
    	' -----------------------
    	' The code for retrieving remote user name was
    	' translated into VBA from source code provided by
    	' SysInternals - www.sysinternals.com
    	' Copyright (C) 1999-2000 Mark Russinovich
    	' as part of the LoggedOn console app
    	'
    	' Translated by: Dev Ashish
    	' www.mvps.org/access
    	'
    	' This code was originally written by Dev Ashish.
    	' It is not to be altered or distributed,
    	' except as part of an application.
    	' You are free to use it in any application,
    	' provided the copyright notice is left unchanged.
    	'
    	' Modified version 2003-26-03 by Andreas Schubert
    	'   See description of fGetRemoteLoggedUserID function for details
    
    	Private Declare Function apiNetAPIBufferFree Lib "netapi32.dll" Alias "NetApiBufferFree" (ByVal buffer As Long) As Long
    	Private Declare Function apiFormatMsgLong Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, ByVal lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, ByVal Arguments As Long) As Long
    	Private Declare Auto Function RegConnectRegistry Lib "Advapi32" (ByVal lpMachineName As String, ByVal hKey As IntPtr, ByRef phkResult As IntPtr) As Integer
    	Private Declare Auto Function RegEnumKeyEx Lib "Advapi32" (ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpName As StringBuilder, ByRef lpcName As Integer, ByVal lpReserved As IntPtr, ByVal lpClass As IntPtr, ByVal lpcClass As IntPtr, ByVal lpftLastWriteTime As IntPtr) As Integer
    	Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As IntPtr) As Integer
    	Private Declare Function AllocateAndInitializeSid Lib "advapi32.dll" (ByRef pIdentifierAuthority As SID_IDENTIFIER_AUTHORITY, ByVal nSubAuthorityCount As Byte, ByVal nSubAuthority0 As Integer, ByVal nSubAuthority1 As Integer, ByVal nSubAuthority2 As Integer, ByVal nSubAuthority3 As Integer, ByVal nSubAuthority4 As Integer, ByVal nSubAuthority5 As Integer, ByVal nSubAuthority6 As Integer, ByVal nSubAuthority7 As Integer, ByRef lpPSid As IntPtr) As Integer
    	Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias "LookupAccountSidA" (ByVal systemName As String, ByVal psid As IntPtr, ByVal accountName As String, ByRef cbAccount As Integer, ByVal domainName As String, ByRef cbDomainName As Integer, ByRef use As Integer) As Integer
    	Private Declare Function apiIsValidSid Lib "advapi32.dll" Alias "IsValidSid" (ByVal pSid As String) As Long
    	Private Declare Function FreeSid Lib "advapi32.dll" (ByVal pSid As IntPtr) As IntPtr
    #End Region
    
    #Region "Struct"
    	Private Structure FILETIME
    		Public dwLowDateTime As Long
    		Public dwHighDateTime As Long
    	End Structure
    
    	Public Structure SID_IDENTIFIER_AUTHORITY
    		<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> Dim Value() As Byte
    	End Structure
    
    #End Region
    
    #Region "CONST"
    	Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
    	Private Const ERROR_SUCCESS = 0&
    	Private Const HKEY_USERS = &H80000003
    	Private Const MAX_REG_KEYNAME_SIZE = 260
    	Private Const ERROR_MORE_DATA = 234
    	Private Const MAX_NAME_STRING = 1024
    	Private Const SECURITY_NT_AUTHORITY = 5
    #End Region
    
    	Public Shared Function fGetRemoteLoggedUserID(ByVal strMachineName As String) As String
    		'
    		' Retrieves the id of the user currently logged into the specified
    		' local or remote machine in the format DOMAIN\UserName
    		'
    		' Usage:
    		' ?fGetRemoteLoggedUserID("springfield")
    		'
    		' Retrieves the id of the user currently logged into the specified
    		' local or remote machine in the format DOMAIN\UserName
    		'
    		' Translated into VBA from source code provided by
    		' SysInternals - www.sysinternals.com
    		' Copyright (C) 1999-2000 Mark Russinovich
    		' as part of the LoggedOn console app
    		'
    		' Translated by: Dev Ashish
    		' www.mvps.org/access
    		' [email protected]
    		'
    		'
    		' modified 2003-26-03 by: Andreas Schubert
    		' [email protected]
    		' eliminated a view bugs:
    		' 1. converting the registry subkey to SubAuthorities sometimes caused an
    		'       overflow error because of the difference between C's DWORD and VB's Long.
    		'       so I first convert them to a double and if it exceeds 2147483647,
    		'       I substract 4294967296 and then convert it to long
    		'       For j = 3 To lngSubAuthorityCount
    		'           adblTemp = 0
    		'           adblTemp = CDbl(astrTmpSubAuthority(j))
    		'           If adblTemp > 2147483647 Then
    		'               adblTemp = adblTemp - 4294967296#
    		'           End If
    		'           alngSubAuthority(j - 3) = CLng(adblTemp)
    		'       Next
    		'
    		' 2. sometimes a subkey won't consist of 7 parts. If so, the function
    		'           crashed with an Index error.
    		'           Solving this was pretty easy by inserting
    		'       If UBound(alngSubAuthority) < 7 Then ReDim Preserve alngSubAuthority(7)
    		'
    		' 3. It is possible that the function finds more than 1 active user
    		'       at the remote workstation. This may for instance be the cause
    		'       if you are running an Microsoft SMS Server in your network.
    		'       The SMS client will run under an local account on your machine
    		'       (like \Computername\SMSCliSvsAcct)
    		'       So, I modified the function to get all accounts separated by vbcrlf - character(s)
    		'
    
    		Dim p_RemoteUser As IntPtr = IntPtr.Zero
    		Dim j As Long
    		Dim lRet As Long, i As Long
    		Dim alngSubAuthority() As Long, astrTmpSubAuthority() As String
    		Dim ntAuthority As New SID_IDENTIFIER_AUTHORITY
    		Dim pSid As IntPtr, lngUserNameSize As Long, lngDomainNameSize As Long
    		Dim lngSubAuthorityCount As Long, intSidType As Integer
    		Dim strUserName As String, strDomainName As String, strSubKeyName As String
    
    		Dim sc As New StringCollection
    		Dim sb As New StringBuilder(MAX_REG_KEYNAME_SIZE + 1)
    		Dim NameSize As Integer
    
    		Dim adblTemp As Double
    		Const ERR_GENERIC = vbObjectError + 5555
    		Const KEY_TO_SKIP_1 = "classes"
    		Const KEY_TO_SKIP_2 = ".default"
    
    		lRet = RegConnectRegistry("\\" & strMachineName, New IntPtr(HKEY_USERS), p_RemoteUser)
    
    		If lRet <> ERROR_SUCCESS Then
    			Throw New Exception(ERR_GENERIC)
    		End If
    
    		ReDim ntAuthority.Value(6)
    		ntAuthority.Value(5) = SECURITY_NT_AUTHORITY
    
    		i = 0
    
    		strSubKeyName = New String(vbNullChar, NameSize)
    
    		NameSize = MAX_REG_KEYNAME_SIZE + 1
    		lRet = RegEnumKeyEx(p_RemoteUser, i, sb, NameSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
    
    		Do While (lRet = ERROR_SUCCESS Or lRet = ERROR_MORE_DATA)
    			If (InStr(1, sb.ToString, KEY_TO_SKIP_1, CompareMethod.Text) = 0 And InStr(1, sb.ToString, KEY_TO_SKIP_2, CompareMethod.Text) = 0) Then
    				strSubKeyName = Strings.Left(sb.ToString, NameSize)
    				astrTmpSubAuthority = Split(strSubKeyName, "-")
    				lngSubAuthorityCount = UBound(astrTmpSubAuthority)
    
    				ReDim alngSubAuthority(lngSubAuthorityCount)
    
    				For j = 3 To lngSubAuthorityCount
    					adblTemp = 0
    					adblTemp = CDbl(astrTmpSubAuthority(j))
    
    					If adblTemp > 2147483647 Then
    						adblTemp = adblTemp - 4294967296.0#
    					End If
    					alngSubAuthority(j - 3) = CLng(adblTemp)
    				Next
    				lngSubAuthorityCount = UBound(alngSubAuthority) - 2
    
    				If UBound(alngSubAuthority) < 7 Then ReDim Preserve alngSubAuthority(7)
    
    				If (AllocateAndInitializeSid(ntAuthority, CByte(lngSubAuthorityCount), alngSubAuthority(0), alngSubAuthority(1), alngSubAuthority(2), alngSubAuthority(3), alngSubAuthority(4), alngSubAuthority(5), alngSubAuthority(6), alngSubAuthority(7), pSid)) Then
    					If (apiIsValidSid(pSid)) Then
    						lngUserNameSize = MAX_NAME_STRING
    						lngDomainNameSize = MAX_NAME_STRING
    						strUserName = New String(vbNullChar, lngUserNameSize - 1)
    						strDomainName = New String(vbNullChar, lngDomainNameSize - 1)
    						lRet = LookupAccountSid(strMachineName, pSid, strUserName, lngUserNameSize, strDomainName, lngDomainNameSize, intSidType)
    
    						If fTrimNull(strDomainName) <> "NT AUTHORITY" Then
    							FreeSid(pSid)
    							RegCloseKey(p_RemoteUser)
    							Return fTrimNull(strDomainName) & "\" & fTrimNull(strUserName)
    						End If
    
    					End If
    				End If
    
    				FreeSid(pSid)
    			End If
    			i = i + 1
    			NameSize = MAX_REG_KEYNAME_SIZE + 1
    			strSubKeyName = New String(vbNullChar, NameSize)
    			lRet = RegEnumKeyEx(p_RemoteUser, i, sb, NameSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
    		Loop
    
    		RegCloseKey(p_RemoteUser)
    
    		Return Nothing
    	End Function
    
    	Private Shared Function fTrimNull(ByVal strIn As String) As String
    		Dim intPos As Integer
    		intPos = InStr(1, strIn, vbNullChar)
    		If intPos Then
    			fTrimNull = Mid$(strIn, 1, intPos - 1)
    		Else
    			fTrimNull = strIn
    		End If
    	End Function
    
    
    End Class

  18. #18
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: WMI Win32_Service Create Fails when No User Logged On

    Cool I'm sure you could eliminate half of the API stuff in there and replace it with built in .NET methods though - like anything to do with reading the registry for example (which accounts for a fair bit of that code)
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  19. #19

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: WMI Win32_Service Create Fails when No User Logged On

    Well it seems to work so I'm not going to change it right now, lol. I'm going to start working on re-directing the input for remote process through the named pipe, to my client application....fuuuuun....I'm going to close this post and will re-post if need be

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width