services: Make ChangeServiceConfig2W() rpc call compatible with native one.

This commit is contained in:
Nikolay Sivov 2015-02-25 08:57:20 +03:00 committed by Alexandre Julliard
parent 08900265a0
commit 3c186a65d3
3 changed files with 46 additions and 20 deletions

View File

@ -2155,7 +2155,11 @@ BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel,
__TRY __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) __EXCEPT(rpc_filter)
{ {

View File

@ -114,6 +114,18 @@ typedef struct _SERVICE_FAILURE_ACTIONSW {
[size_is(cActions)] SC_ACTION *lpsaActions; [size_is(cActions)] SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW; } 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 { typedef struct _SERVICE_PRESHUTDOWN_INFO {
DWORD dwPreshutdownTimeout; DWORD dwPreshutdownTimeout;
} SERVICE_PRESHUTDOWN_INFO,*LPSERVICE_PRESHUTDOWN_INFO; } SERVICE_PRESHUTDOWN_INFO,*LPSERVICE_PRESHUTDOWN_INFO;
@ -134,12 +146,23 @@ typedef struct _ENUM_SERVICE_STATUSW {
cpp_quote("#endif") cpp_quote("#endif")
typedef [switch_type(DWORD)] union typedef struct _SERVICE_RPC_REQUIRED_PRIVILEGES_INFO {
{ DWORD cbRequiredPrivileges;
[case (SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONW descr; [size_is(cbRequiredPrivileges)] BYTE *pRequiredPrivileges;
[case (SERVICE_CONFIG_FAILURE_ACTIONS)] SERVICE_FAILURE_ACTIONSW actions; } SERVICE_RPC_REQUIRED_PRIVILEGES_INFO;
[case (SERVICE_CONFIG_PRESHUTDOWN_INFO)] SERVICE_PRESHUTDOWN_INFO preshutdown;
} SERVICE_CONFIG2W; 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 */ /* Compatible with Windows function 0x00 */
DWORD svcctl_CloseServiceHandle( DWORD svcctl_CloseServiceHandle(
@ -331,11 +354,10 @@ typedef [switch_type(DWORD)] union
/* Not compatible with Windows function 0x24 */ /* Not compatible with Windows function 0x24 */
DWORD svcctl_ChangeServiceConfig2A(/* FIXME */); DWORD svcctl_ChangeServiceConfig2A(/* FIXME */);
/* Untested with Windows function 0x25 */ /* Compatible with Windows function 0x25 */
DWORD svcctl_ChangeServiceConfig2W( DWORD svcctl_ChangeServiceConfig2W(
[in] SC_RPC_HANDLE hService, [in] SC_RPC_HANDLE hService,
[in] DWORD InfoLevel, [in] SC_RPC_CONFIG_INFOW config);
[in,switch_is(InfoLevel)] SERVICE_CONFIG2W *config );
/* Not compatible with Windows function 0x26 */ /* Not compatible with Windows function 0x26 */
DWORD svcctl_QueryServiceConfig2A(/* FIXME */); DWORD svcctl_QueryServiceConfig2A(/* FIXME */);

View File

@ -755,7 +755,7 @@ DWORD __cdecl svcctl_SetServiceStatus(
return ERROR_SUCCESS; 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; struct sc_service_handle *service;
DWORD err; 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) if ((err = validate_service_handle(hService, SERVICE_CHANGE_CONFIG, &service)) != 0)
return err; return err;
switch (level) switch (config.dwInfoLevel)
{ {
case SERVICE_CONFIG_DESCRIPTION: case SERVICE_CONFIG_DESCRIPTION:
{ {
WCHAR *descr = NULL; 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; return ERROR_NOT_ENOUGH_MEMORY;
} }
@ -785,20 +785,20 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
break; break;
case SERVICE_CONFIG_FAILURE_ACTIONS: case SERVICE_CONFIG_FAILURE_ACTIONS:
WINE_FIXME( "SERVICE_CONFIG_FAILURE_ACTIONS not implemented: period %u msg %s cmd %s\n", WINE_FIXME( "SERVICE_CONFIG_FAILURE_ACTIONS not implemented: period %u msg %s cmd %s\n",
config->actions.dwResetPeriod, config.actions->dwResetPeriod,
wine_dbgstr_w(config->actions.lpRebootMsg), wine_dbgstr_w(config.actions->lpRebootMsg),
wine_dbgstr_w(config->actions.lpCommand) ); wine_dbgstr_w(config.actions->lpCommand) );
break; break;
case SERVICE_CONFIG_PRESHUTDOWN_INFO: case SERVICE_CONFIG_PRESHUTDOWN_INFO:
WINE_TRACE( "changing service %p preshutdown timeout to %d\n", 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_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 ); save_service_config( service->service_entry );
service_unlock( service->service_entry ); service_unlock( service->service_entry );
break; break;
default: default:
WINE_FIXME("level %u not implemented\n", level); WINE_FIXME("level %u not implemented\n", config.dwInfoLevel);
err = ERROR_INVALID_LEVEL; err = ERROR_INVALID_LEVEL;
break; break;
} }