Jump to content

DllCall


Recommended Posts

How robust is the DllCall function? I was hoping I might be able to integrate functions from advapi32.dll, ws2_32.dll, ntdll.dll among others. I'd like to be able to stop using psservice.exe to check, start and stop services on remote machines and integrate that functionality into my own script. I've used Dependency Walker, figured out what functions psservice.exe calls and in what DLLs they exist. I've been to MSDN and discovered the parameters of most of the functions, some are undocumented. I don't know if I'm doing it properly though.

Here's an example:

ControlService() in advapi32.dll requires OpenService() which requires OpenSCManager().

I figure that with those functions, I should be able to do what I need to do without the use of an external program. I've tried to implement them, but I can't seem to figure it out. Unfortunately I lost the code I had for it, it wasn't that long anyway. I'm just curious if it's even possible at this stage or if I'm wasting my time trying to get it to work. I've tried to get the handles for each subsequent function and passing it on to the next as a parameter, which sounds like what I need to do. It returns a NULL string though. I've gotten the DllCall to work though, I've set up a script that locks the Desktop:

DllCall("user32.dll", "int", "LockWorkstation")

Obviously a lot easier than what I'm trying to accomplish, but at least I'm doing something right.

Link to comment
Share on other sites

Global $STANDARD_RIGHTS_REQUIRED = 0x000F0000
Global $SC_MANAGER_CONNECT = 0x0001
Global $SC_MANAGER_CREATE_SERVICE = 0x0002
Global $SC_MANAGER_ENUMERATE_SERVICE = 0x0004
Global $SC_MANAGER_LOCK = 0x0008
Global $SC_MANAGER_QUERY_LOCK_STATUS = 0x0010
Global $SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020

Global $SC_MANAGER_ALL_ACCESS = BitOR($STANDARD_RIGHTS_REQUIRED, _
                                     $SC_MANAGER_CONNECT, _
                                     $SC_MANAGER_CREATE_SERVICE, _
                                     $SC_MANAGER_ENUMERATE_SERVICE, _
                                     $SC_MANAGER_LOCK, _
                                     $SC_MANAGER_QUERY_LOCK_STATUS, _
                                     $SC_MANAGER_MODIFY_BOOT_CONFIG)
                                     
Global $SERVICE_QUERY_CONFIG = 0x0001
Global $SERVICE_CHANGE_CONFIG = 0x0002
Global $SERVICE_QUERY_STATUS = 0x0004
Global $SERVICE_ENUMERATE_DEPENDENTS = 0x0008
Global $SERVICE_START = 0x0010
Global $SERVICE_STOP = 0x0020
Global $SERVICE_PAUSE_CONTINUE = 0x0040
Global $SERVICE_INTERROGATE = 0x0080
Global $SERVICE_CONTROL_INTERROGATE = 0x00000004
Global $SERVICE_USER_DEFINED_CONTROL = 0x0100

Global $SERVICE_ALL_ACCESS = BitOR($STANDARD_RIGHTS_REQUIRED, _
                                  $SERVICE_QUERY_CONFIG, _
                                  $SERVICE_CHANGE_CONFIG, _
                                  $SERVICE_QUERY_STATUS, _
                                  $SERVICE_ENUMERATE_DEPENDENTS, _
                                  $SERVICE_START, _
                                  $SERVICE_STOP, _
                                  $SERVICE_PAUSE_CONTINUE, _
                                  $SERVICE_INTERROGATE, _
                                  $SERVICE_USER_DEFINED_CONTROL)

Global $SERVICE_CONTROL_STOP = 0x00000001

; Example - start print spooler
If _ServiceExists("Spooler") Then _StopService("Spooler")


Func _StartService($sServiceName)
  Local $arRet
  Local $hSC
  Local $hService
  Local $lError = -1

  $arRet = DllCall("advapi32.dll", "long", "OpenSCManager", _
                    "str", "", _
                    "str", "ServicesActive", _ 
                    "long", $SC_MANAGER_CONNECT)
  If $arRet[0] = 0 Then
     $arRet = DllCall("kernel32.dll", "long", "GetLastError")
     $lError = $arRet[0]
  Else
     $hSC = $arRet[0]
     $arRet = DllCall("advapi32.dll", "long", "OpenService", _
                      "long", $hSC, _
                      "str", $sServiceName, _
                      "long", $SERVICE_START)
     If $arRet[0] = 0 Then
        $arRet = DllCall("kernel32.dll", "long", "GetLastError")
        $lError = $arRet[0]
     Else
        $hService = $arRet[0]
        $arRet = DllCall("advapi32.dll", "int", "StartService", _
                         "long", $hService, _
                         "long", 0, _
                         "str", "")
        If $arRet[0] = 0 Then
           $arRet = DllCall("kernel32.dll", "long", "GetLastError")
           $lError = $arRet[0]
        EndIf
        DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hService)         
     EndIf
     DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hSC)
  EndIf
  If $lError <> -1 Then SetError($lError)
EndFunc

Func _StopService($sServiceName)
  Local $arRet
  Local $hSC
  Local $hService
  Local $lError = -1

  $arRet = DllCall("advapi32.dll", "long", "OpenSCManager", _
                    "str", "", _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_CONNECT)
  If $arRet[0] = 0 Then
     $arRet = DllCall("kernel32.dll", "long", "GetLastError")
     $lError = $arRet[0]
  Else
     $hSC = $arRet[0]
     $arRet = DllCall("advapi32.dll", "long", "OpenService", _
                      "long", $hSC, _
                      "str", $sServiceName, _
                      "long", $SERVICE_STOP)
     If $arRet[0] = 0 Then
        $arRet = DllCall("kernel32.dll", "long", "GetLastError")
        $lError = $arRet[0]
     Else
        $hService = $arRet[0]
        $arRet = DllCall("advapi32.dll", "int", "ControlService", _
                         "long", $hService, _
                         "long", $SERVICE_CONTROL_STOP, _
                         "str", "")
        If $arRet[0] = 0 Then
           $arRet = DllCall("kernel32.dll", "long", "GetLastError")
           $lError = $arRet[0]
        EndIf
        DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hService)         
     EndIf
     DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hSC)
  EndIf
  If $lError <> -1 Then SetError($lError)
EndFunc

Func _ServiceExists($sServiceName)
  Local $arRet
  Local $hSC
  Local $bExist = 0
  
  $arRet = DllCall("advapi32.dll", "long", "OpenSCManager", _
                    "str", "", _
                    "str", "ServicesActive", _
                    "long", $SC_MANAGER_CONNECT)
  If $arRet[0] <> 0 Then
     $hSC = $arRet[0]
     $arRet = DllCall("advapi32.dll", "long", "OpenService", _
                      "long", $hSC, _
                      "str", $sServiceName, _
                      "long", $SERVICE_INTERROGATE)
     If $arRet[0] <> 0 Then
        $bExist = 1
        DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $arRet[0])
     EndIf
     DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hSC)
  EndIf
  Return $bExist
EndFunc

Func _ServiceRunning($sServiceName)
  Local $arRet
  Local $hSC
  Local $hService   
  Local $bRunning = 0
 
  $arRet = DllCall("advapi32.dll", "long", "OpenSCManager", _
                   "str", "", _
                   "str", "ServicesActive", _
                   "long", $SC_MANAGER_CONNECT)
  If $arRet[0] <> 0 Then
     $hSC = $arRet[0]
     $arRet = DllCall("advapi32.dll", "long", "OpenService", _
                      "long", $hSC, _
                      "str", $sServiceName, _
                      "long", $SERVICE_INTERROGATE)
     If $arRet[0] <> 0 Then
        $hService = $arRet[0]
        $arRet = DllCall("advapi32.dll", "int", "ControlService", _
                         "long", $hService, _
                         "long", $SERVICE_CONTROL_INTERROGATE, _
                         "long_ptr", 0)
        $bRunning = $arRet[0]
        DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hService)
     EndIf
     DllCall("advapi32.dll", "int", "CloseServiceHandle", "long", $hSC)
  EndIf
  Return $bRunning
EndFunc

Who else would I be?
Link to comment
Share on other sites

BTW, that was not my code. I happened to have it laying around. This code has been submitted here at the forum before. For an FYI, the search feature at the top of this forum is extremey handy in finding code like the one above.

Who else would I be?
Link to comment
Share on other sites

BTW, that was not my code. I happened to have it laying around. This code has been submitted here at the forum before. For an FYI, the search feature at the top of this forum is extremey handy in finding code like the one above.

<{POST_SNAPBACK}>

Yes, I know. Honestly, I never expected someone to have written exactly what I needed, it never even crossed my mind to search. Thankfully someone did and saved me the effort, although I'm definitely going to make sure I understand it, so it will almost be like I wrote it myself... :idiot: It seemed so obscure. Obviously, I'm going to need to modify it to work on networked machines, but if I recall that's only one parameter on one of those functions, OpenSCManager if I recall correctly.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...