services: Added support for SERVICE_CONFIG_PRESHUTDOWN_INFO.

This commit is contained in:
Piotr Caban 2011-11-30 15:28:26 +01:00 committed by Alexandre Julliard
parent eeb5c93ac7
commit b8704a4929
4 changed files with 33 additions and 1 deletions

View File

@ -114,6 +114,10 @@ typedef struct _SERVICE_FAILURE_ACTIONSW {
[size_is(cActions)] SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW;
typedef struct _SERVICE_PRESHUTDOWN_INFO {
DWORD dwPreshutdownTimeout;
} SERVICE_PRESHUTDOWN_INFO,*LPSERVICE_PRESHUTDOWN_INFO;
#define SERVICE_CONFIG_DESCRIPTION 1
#define SERVICE_CONFIG_FAILURE_ACTIONS 2
#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
@ -134,6 +138,7 @@ typedef [switch_type(DWORD)] union
{
[case (SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONW descr;
[case (SERVICE_CONFIG_FAILURE_ACTIONS)] SERVICE_FAILURE_ACTIONSW actions;
[case (SERVICE_CONFIG_PRESHUTDOWN_INFO)] SERVICE_PRESHUTDOWN_INFO preshutdown;
} SERVICE_CONFIG2W;
/* Compatible with Windows function 0x00 */

View File

@ -737,6 +737,14 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
wine_dbgstr_w(config->actions.lpRebootMsg),
wine_dbgstr_w(config->actions.lpCommand) );
break;
case SERVICE_CONFIG_PRESHUTDOWN_INFO:
WINE_TRACE( "changing service %p preshutdown timeout to %d\n",
service, config->preshutdown.dwPreshutdownTimeout );
service_lock_exclusive( service->service_entry );
service->service_entry->preshutdown_timeout = config->preshutdown.dwPreshutdownTimeout;
save_service_config( service->service_entry );
service_unlock( service->service_entry );
break;
default:
WINE_FIXME("level %u not implemented\n", level);
err = ERROR_INVALID_LEVEL;
@ -781,6 +789,18 @@ DWORD __cdecl svcctl_QueryServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
}
break;
case SERVICE_CONFIG_PRESHUTDOWN_INFO:
service_lock_shared(service->service_entry);
*needed = sizeof(SERVICE_PRESHUTDOWN_INFO);
if (size >= *needed)
((LPSERVICE_PRESHUTDOWN_INFO)buffer)->dwPreshutdownTimeout =
service->service_entry->preshutdown_timeout;
else err = ERROR_INSUFFICIENT_BUFFER;
service_unlock(service->service_entry);
break;
default:
WINE_FIXME("level %u not implemented\n", level);
err = ERROR_INVALID_LEVEL;

View File

@ -41,6 +41,7 @@ struct scmdatabase *active_database;
DWORD service_pipe_timeout = 10000;
DWORD service_kill_timeout = 20000;
static DWORD default_preshutdown_timeout = 180000;
static void *env = NULL;
static const int is_win64 = (sizeof(void *) > sizeof(int));
@ -64,6 +65,7 @@ static const WCHAR SZ_DEPEND_ON_GROUP[] = {'D','e','p','e','n','d','O','n','G'
static const WCHAR SZ_OBJECT_NAME[] = {'O','b','j','e','c','t','N','a','m','e',0};
static const WCHAR SZ_TAG[] = {'T','a','g',0};
static const WCHAR SZ_DESCRIPTION[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
static const WCHAR SZ_PRESHUTDOWN[] = {'P','r','e','s','h','u','t','d','o','w','n','T','i','m','e','o','u','t',0};
DWORD service_create(LPCWSTR name, struct service_entry **entry)
@ -80,6 +82,7 @@ DWORD service_create(LPCWSTR name, struct service_entry **entry)
(*entry)->control_pipe = INVALID_HANDLE_VALUE;
(*entry)->status.dwCurrentState = SERVICE_STOPPED;
(*entry)->status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED;
(*entry)->preshutdown_timeout = default_preshutdown_timeout;
/* all other fields are zero */
return ERROR_SUCCESS;
}
@ -130,6 +133,8 @@ static DWORD load_service_config(HKEY hKey, struct service_entry *entry)
return err;
if ((err = load_reg_dword(hKey, SZ_TAG, &entry->config.dwTagId)) != 0)
return err;
if ((err = load_reg_dword(hKey, SZ_PRESHUTDOWN, &entry->preshutdown_timeout)) != 0)
return err;
WINE_TRACE("Image path = %s\n", wine_dbgstr_w(entry->config.lpBinaryPathName) );
WINE_TRACE("Group = %s\n", wine_dbgstr_w(entry->config.lpLoadOrderGroup) );
@ -206,9 +211,10 @@ DWORD save_service_config(struct service_entry *entry)
goto cleanup;
if ((err = RegSetValueExW(hKey, SZ_ERROR, 0, REG_DWORD, (LPBYTE)&entry->config.dwErrorControl, sizeof(DWORD))) != 0)
goto cleanup;
if ((err = RegSetValueExW(hKey, SZ_TYPE, 0, REG_DWORD, (LPBYTE)&entry->config.dwServiceType, sizeof(DWORD))) != 0)
goto cleanup;
if ((err = RegSetValueExW(hKey, SZ_PRESHUTDOWN, 0, REG_DWORD, (LPBYTE)&entry->preshutdown_timeout, sizeof(DWORD))) != 0)
goto cleanup;
if (entry->config.dwTagId)
err = RegSetValueExW(hKey, SZ_TAG, 0, REG_DWORD, (LPBYTE)&entry->config.dwTagId, sizeof(DWORD));

View File

@ -39,6 +39,7 @@ struct service_entry
LPWSTR name;
SERVICE_STATUS_PROCESS status;
QUERY_SERVICE_CONFIGW config;
DWORD preshutdown_timeout;
LPWSTR description;
LPWSTR dependOnServices;
LPWSTR dependOnGroups;