Jump to content
engine

Windows Services UDF

Recommended Posts

I recently needed a way to enumerate services, I found this UDF but when running _Service_Enum the 300 ms delay was too long for me so I went and optimized the code now it runs over 10x quicker (~20ms) I may update the other functions if I have a use for them.

Func _Service_Enum($iServiceType, $iServiceState = $SERVICE_STATE_ALL, $sLoadOrderGroup = Default, $sComputerName = "")
    ;Local $SC_ENUM_PROCESS_INFO = 0
    Local $tLoadOrderGroup, $iErr
    Local $hSCM, $uEBuf, $tEBuf, $avEnumSvc

    $tLoadOrderGroup = DllStructCreate("char[" & Number($sLoadOrderGroup <> Default) * (StringLen($sLoadOrderGroup) + 1) & "]")
    DllStructSetData($tLoadOrderGroup, 1, $sLoadOrderGroup)

    ;open service manager
    $hSCM = OpenSCManager($sComputerName, $SC_MANAGER_ENUMERATE_SERVICE)
    ; Determine needed size of the struct in bytes
    $avEnumSvc = DllCall("advapi32.dll", "int", "EnumServicesStatusEx", _
            "hwnd", $hSCM, _
            "dword", $SC_ENUM_PROCESS_INFO, _
            "dword", $iServiceType, _
            "dword", $iServiceState, _
            "ptr", 0, _
            "dword", 0, _
            "dword*", 0, _
            "dword*", 0, _
            "dword*", 0, _
            "ptr", DllStructGetPtr($tLoadOrderGroup))

    ; Load buffer with Service data
    $uEBuf = DllStructCreate("ubyte[" & $avEnumSvc[7] & "]") ;ubyte buffer

    $avEnumSvc = DllCall("advapi32.dll", "int", "EnumServicesStatusEx", _
            "hwnd", $hSCM, _
            "dword", $SC_ENUM_PROCESS_INFO, _
            "dword", $iServiceType, _
            "dword", $iServiceState, _
            "ptr", DllStructGetPtr($uEBuf), _        ;5-lpServices
            "dword", DllStructGetSize($uEBuf), _ ;6-cbBufSize
            "dword*", 0, _                       ;7-pcbBytesNeeded
            "dword*", 0, _                       ;8-lpServicesReturned
            "dword*", 0, _                       ;9-lpResumeHandle
            "ptr", DllStructGetPtr($tLoadOrderGroup)) ;10-pszGroupName

    ; Get last error and close service control manager database handle
    If $avEnumSvc[0] = 0 Then $iErr = _WinAPI_GetLastError()
    CloseServiceHandle($hSCM)


    Local $asSvcsStatus[$avEnumSvc[8] + 1][11] = [[$avEnumSvc[8], 11]] ;Prepare return Array

    ; Decode the ubyte structure

    For $i = 1 To $avEnumSvc[8]
        $tEBuf = DllStructCreate("uint_ptr[2];dword[9]", $avEnumSvc[5] + (DllStructGetSize($tEBuf) * ($i - 1))) ;Prepare buffer increment pointer by struct sz

        For $k = 0 To 1
            $asSvcsStatus[$i][$k] = DllStructGetData(DllStructCreate("char[257]", DllStructGetData($tEBuf, 1, $k + 1)), 1) ;fill char array with info from ptr
        Next

        For $k = 1 To UBound($asSvcsStatus, 2) - 2
            $asSvcsStatus[$i][$k + 1] = DllStructGetData($tEBuf, 2, $k)
        Next

    Next

    Return SetError($iErr, 0, $asSvcsStatus)
EndFunc   ;==>_Service_Enum

I reworked the parsing to use less temporary variables and less copying, Should be a drop in replacement.

Edited by Bilgus
fixed typo in buffer name

Share this post


Link to post
Share on other sites

Sorry for the Nekro.

This is the best services UDF I have seen.

I used it with great success to fix a bad application that was growing out of control with temp files.

I have a new project I am working on right now, and unlike last time I used it I am not running it local, but instead trying to start/stop/query services on a remote server as I have a cluster of servers that need services stopped/started in a special order.

 

I made the code, and now in testing it is not working.

I get an Error Code of 6 for @Error for Service_Stop and I am a admin on the remote server.

I am not sure if its security/permissions issues, or something else.

 

#Edit#

Still works - We had a crazy server name and I was missing a letter.

:)

 

Edited by ViciousXUSMC

Share this post


Link to post
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

×
×
  • Create New...