From 3c186a65d3e52428924ba3e513961b0c569e567c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 25 Feb 2015 08:57:20 +0300 Subject: [PATCH] services: Make ChangeServiceConfig2W() rpc call compatible with native one. --- dlls/advapi32/service.c | 6 +++++- include/wine/svcctl.idl | 40 +++++++++++++++++++++++++++++++--------- programs/services/rpc.c | 20 ++++++++++---------- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 23ff2f048a1..e0f7312fd57 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -2155,7 +2155,11 @@ BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel, __TRY { - err = svcctl_ChangeServiceConfig2W( hService, dwInfoLevel, lpInfo ); + SC_RPC_CONFIG_INFOW info; + + info.dwInfoLevel = dwInfoLevel; + info.descr = lpInfo; + err = svcctl_ChangeServiceConfig2W( hService, info ); } __EXCEPT(rpc_filter) { diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl index f261702a72e..b5a8c4d59fa 100644 --- a/include/wine/svcctl.idl +++ b/include/wine/svcctl.idl @@ -114,6 +114,18 @@ typedef struct _SERVICE_FAILURE_ACTIONSW { [size_is(cActions)] SC_ACTION *lpsaActions; } SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW; +typedef struct _SERVICE_DELAYED_AUTO_START_INFO { + BOOL fDelayedAutostart; +} SERVICE_DELAYED_AUTO_START_INFO; + +typedef struct _SERVICE_FAILURE_ACTIONS_FLAG { + BOOL fFailureActionsOnNonCrashFailures; +} SERVICE_FAILURE_ACTIONS_FLAG; + +typedef struct _SERVICE_SID_INFO { + DWORD dwServiceSidType; +} SERVICE_SID_INFO; + typedef struct _SERVICE_PRESHUTDOWN_INFO { DWORD dwPreshutdownTimeout; } SERVICE_PRESHUTDOWN_INFO,*LPSERVICE_PRESHUTDOWN_INFO; @@ -134,12 +146,23 @@ typedef struct _ENUM_SERVICE_STATUSW { cpp_quote("#endif") -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; +typedef struct _SERVICE_RPC_REQUIRED_PRIVILEGES_INFO { + DWORD cbRequiredPrivileges; + [size_is(cbRequiredPrivileges)] BYTE *pRequiredPrivileges; +} SERVICE_RPC_REQUIRED_PRIVILEGES_INFO; + +typedef struct _SC_RPC_CONFIG_INFOW { + DWORD dwInfoLevel; + [switch_is(dwInfoLevel)] union { + [case(SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONW *descr; + [case(SERVICE_CONFIG_FAILURE_ACTIONS)] SERVICE_FAILURE_ACTIONSW *actions; + [case(SERVICE_CONFIG_DELAYED_AUTO_START_INFO)] SERVICE_DELAYED_AUTO_START_INFO *delayedstart; + [case(SERVICE_CONFIG_FAILURE_ACTIONS_FLAG)] SERVICE_FAILURE_ACTIONS_FLAG *actionsflag; + [case(SERVICE_CONFIG_SERVICE_SID_INFO)] SERVICE_SID_INFO *sid; + [case(SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO)] SERVICE_RPC_REQUIRED_PRIVILEGES_INFO *privinfo; + [case(SERVICE_CONFIG_PRESHUTDOWN_INFO)] SERVICE_PRESHUTDOWN_INFO *preshutdown; + }; +} SC_RPC_CONFIG_INFOW; /* Compatible with Windows function 0x00 */ DWORD svcctl_CloseServiceHandle( @@ -331,11 +354,10 @@ typedef [switch_type(DWORD)] union /* Not compatible with Windows function 0x24 */ DWORD svcctl_ChangeServiceConfig2A(/* FIXME */); - /* Untested with Windows function 0x25 */ + /* Compatible with Windows function 0x25 */ DWORD svcctl_ChangeServiceConfig2W( [in] SC_RPC_HANDLE hService, - [in] DWORD InfoLevel, - [in,switch_is(InfoLevel)] SERVICE_CONFIG2W *config ); + [in] SC_RPC_CONFIG_INFOW config); /* Not compatible with Windows function 0x26 */ DWORD svcctl_QueryServiceConfig2A(/* FIXME */); diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 3955e098765..34d012d69b4 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -755,7 +755,7 @@ DWORD __cdecl svcctl_SetServiceStatus( return ERROR_SUCCESS; } -DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, SERVICE_CONFIG2W *config ) +DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOW config ) { struct sc_service_handle *service; DWORD err; @@ -763,15 +763,15 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, if ((err = validate_service_handle(hService, SERVICE_CHANGE_CONFIG, &service)) != 0) return err; - switch (level) + switch (config.dwInfoLevel) { case SERVICE_CONFIG_DESCRIPTION: { WCHAR *descr = NULL; - if (config->descr.lpDescription[0]) + if (config.descr->lpDescription[0]) { - if (!(descr = strdupW( config->descr.lpDescription ))) + if (!(descr = strdupW( config.descr->lpDescription ))) return ERROR_NOT_ENOUGH_MEMORY; } @@ -785,20 +785,20 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, break; case SERVICE_CONFIG_FAILURE_ACTIONS: WINE_FIXME( "SERVICE_CONFIG_FAILURE_ACTIONS not implemented: period %u msg %s cmd %s\n", - config->actions.dwResetPeriod, - wine_dbgstr_w(config->actions.lpRebootMsg), - wine_dbgstr_w(config->actions.lpCommand) ); + config.actions->dwResetPeriod, + 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, config.preshutdown->dwPreshutdownTimeout ); service_lock_exclusive( service->service_entry ); - service->service_entry->preshutdown_timeout = config->preshutdown.dwPreshutdownTimeout; + 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); + WINE_FIXME("level %u not implemented\n", config.dwInfoLevel); err = ERROR_INVALID_LEVEL; break; }