@@ -254,7 +254,8 @@ Module WindowsServiceHelper
254254 serviceType As WindowsService.ServiceType = WindowsService.ServiceType.Unknown,
255255 serviceErrorControl As WindowsService.ServiceErrorControl = WindowsService.ServiceErrorControl.Unknown,
256256 serviceRequiredPrivilegesString() As String = New String () {},
257- serviceDependencies() As String = New String () {}
257+ serviceDependencies() As String = New String () {},
258+ serviceFailActionByteArr() As Byte = New Byte () {}
258259 Using ServiceInfoRk As RegistryKey = Registry.LocalMachine.OpenSubKey( String .Format( "zSYS\ControlSet{0}\Services\{1}" , DefaultControlSet.ToString().PadLeft( 3 , "0" ), ServiceName), False )
259260 ' We explicitly tell that we want to grab the raw data without env var expansion because REG_EXPAND_SZ values
260261 ' are still string values, but with unexpanded environment variables. If the variable exists in the target system,
@@ -286,6 +287,7 @@ Module WindowsServiceHelper
286287 serviceRequiredPrivilegesString = ServiceInfoRk.GetValue( "RequiredPrivileges" , New String () {})
287288 ' Same goes for dependencies
288289 serviceDependencies = ServiceInfoRk.GetValue( "DependOnService" , New String () {})
290+ serviceFailActionByteArr = ServiceInfoRk.GetValue( "FailureActions" , New Byte () {})
289291
290292 Dim serviceRequiredPrivilegeList As New List( Of NTSecurityPrivilegeConstant)
291293
@@ -311,7 +313,8 @@ Module WindowsServiceHelper
311313 serviceType,
312314 serviceErrorControl,
313315 serviceRequiredPrivilegeList,
314- serviceDependencies))
316+ serviceDependencies,
317+ ParseFailureActionByteArray(serviceFailActionByteArr)))
315318 End Using
316319 Next
317320 Catch ex As Exception
@@ -325,4 +328,51 @@ Module WindowsServiceHelper
325328 Return serviceList
326329 End Function
327330
331+ Private Function ParseFailureActionByteArray(FailureActions As Byte ()) As WindowsService.ServiceFailureActions
332+ Dim scFailure As WindowsService.ServiceFailureActions = New WindowsService.ServiceFailureActions()
333+ Dim firstFail As WindowsService.ServiceFailureAction = WindowsService.ServiceFailureAction.Unknown,
334+ secondFail As WindowsService.ServiceFailureAction = WindowsService.ServiceFailureAction.Unknown,
335+ subsequentFails As WindowsService.ServiceFailureAction = WindowsService.ServiceFailureAction.Unknown
336+ Dim firstDelay As Long = 0 ,
337+ secondDelay As Long = 0 ,
338+ subsequentDelay As Long = 0
339+ Dim resetDelay As Integer = 0
340+
341+ If FailureActions.Count >= 1 Then
342+ Try
343+ resetDelay = GetDelay(FailureActions.Skip( 0 ).Take( 4 ).ToArray())
344+
345+ ' We have to get the number of byte elements twice because undefined failure measures
346+ ' cause our byte array to be smaller than expected, therefore causing indexes out of bounds.
347+ firstFail = FailureActions( 20 )
348+ firstDelay = GetDelay(FailureActions.Skip( 24 ).Take( 4 ).ToArray())
349+ If FailureActions.Count > 28 Then
350+ ' We have defined second failure measures
351+ secondFail = FailureActions( 28 )
352+ secondDelay = GetDelay(FailureActions.Skip( 32 ).Take( 4 ).ToArray())
353+ End If
354+ If FailureActions.Count > 36 Then
355+ ' We have defined subsequent failure measures
356+ subsequentFails = FailureActions( 36 )
357+ subsequentDelay = GetDelay(FailureActions.Skip( 40 ).Take( 4 ).ToArray())
358+ End If
359+ Catch ex As Exception
360+
361+ End Try
362+
363+ scFailure = New WindowsService.ServiceFailureActions(firstFail, firstDelay, secondFail, secondDelay, subsequentFails, subsequentDelay, resetDelay)
364+ End If
365+ Return scFailure
366+ End Function
367+
368+ Private Function GetDelay(ByteArray As Byte ()) As Long
369+ Dim binary As String = ""
370+
371+ For x = ByteArray.Length - 1 To 0 Step - 1
372+ binary &= Convert.ToString(ByteArray(x), 2 ).PadLeft( 8 , "0"c )
373+ Next
374+
375+ Return Convert.ToInt32(binary, 2 )
376+ End Function
377+
328378End Module
0 commit comments