Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What REG-BINARY to set for FailureAction for service

I have a service for which I want to set Data value for FailureAction in registry. Currently there is value set in registry. Value is set using RegKey.SetValue("FailureActions", Value);

I would like to know:

1) How these bytes of Value correspond to recovery option of service (like how to find out particular sequence in registry means setting 'First failure' as 'Restart the Service')

2) Also I need to change in registry FailureAction which will correspond to 'Subsequent failures' as 'Restart the Service'

Here is my finding using trial and error method:

a)Manually change setting of recovery for service then registry entry changes. Copy that value and use in code. It set 'Subsequent failures'

b)Change original value in code. It set 'Subsequent failures'

But value from a) and b) does not match but I see same result if I right click on service and see recovery option. To understand this I would like to know answers to question 1) and 2).

Appreciate your comment\clue.

like image 500
Magg Avatar asked Apr 06 '16 21:04

Magg


1 Answers

To explain the meaning of bytes in data value of FailureActions registry key, I will take this example:

enter image description here

The bytes in this representation correspond to this structure:

typedef struct _SERVICE_FAILURE_ACTIONS {
    DWORD     dwResetPeriod;
    LPTSTR    lpRebootMsg;
    LPTSTR    lpCommand;
    DWORD     cActions;
    SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;

The first four bytes 80 51 01 00 are the value of dwResetPeriod structure's member. It is the time after which to reset the failure count to zero if there are no failures. It is counted in seconds. In this example the reset period is 0x15180 sec (because of little endian). In decimal it is equivalent of 86400 sec or equal to 24 hours. So, if in a period of 24 hours there are no failures then the failure count is reset to zero.

The next four bytes 00 00 00 00 correspond to lpRebootMsg. More info about this structure's member and the next one can be found here

The next four bytes 00 00 00 00 correspond to lpCommand.

The next four bytes 03 00 00 00 correspond to cActions. This member is the number of elements in the lpsaActions array. In this case we have 3 elements.

The next four bytes 14 00 00 00 correspond to lpsaActions which is a pointer to an array of type SA_ACTION.

Finally, 01 00 00 00 60 EA 00 00 01 00 00 00 60 EA 00 00 00 00 00 00 00 00 00 00 is the content of an array of type SC_ACTION pointed by lpsaActions. We have 3 instances of this structure corresponding to the 3 lines of bytes. The structure SC_ACTION is declared below:

typedef struct _SC_ACTION {
    SC_ACTION_TYPE Type;
    DWORD          Delay;
} SC_ACTION, *LPSC_ACTION;

More info about SC_ACTION and SC_ACTION_TYPE can be found here.

So, first line 01 00 00 00 60 EA 00 00 means: : "In case of a failure, restart the service (01 00 00 00) after 60 sec (60 EA 00 00 == to 0xEA60 ms == 60000 ms == 60 sec)." The second line means the same. The third line means "In case of failure, take no action(00 00 00 00) after 0 sec (00 00 00 00)"

How this works? Each time a service fails, the service controller increments a failure count N and take the action N-1 specified in the array pointed by lpsaActions. In our case, first time the service fails, N is incremented to 1 and the controller will execute the actions indexed by 0 which means, restart the service after 60 sec. Second time it fails the N is incremented to 2 and the action N-1 = 1 is taken which means, restart the service after 60 sec. The third time the service fails the controller executes the last action in array which in our case is, take no action. If N is greater than cActions, the service controller repeats the last action in the array. In this case the service is no started anymore.

like image 63
Developer Avatar answered Oct 19 '22 13:10

Developer