From dbb5a1fdabf8e66343cd2a4a2dda79cef95e14b1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Mar 2005 22:32:31 +0000 Subject: r6046: $ net -S block -U % -W VALE rpc service status spooler spooler service is SVCCTL_RUNNING. Configuration details: Service Type = 0x110 Start Type = 0x2 Error Control = 0x1 Tag ID = 0x0 Executable Path = C:\WINNT\system32\spoolsv.exe Load Order Group = SpoolerGroup Dependencies = RPCSS/ Start Name = LocalSystem Display Name = Print Spooler (This used to be commit b921bf568835042a43bb0bcb2abd9d36c9d2e43f) --- source3/rpc_client/cli_svcctl.c | 192 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 181 insertions(+), 11 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index 74d6483b17..c9fdc61379 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -22,6 +22,42 @@ #include "includes.h" #include "rpc_client.h" +struct svc_state_msg { + uint32 flag; + const char *message; +}; + +static struct svc_state_msg state_msg_table[] = { + { SVCCTL_STOPPED, "SVCCTL_STOPPED" }, + { SVCCTL_START_PENDING, "SVCCTL_START_PENDING" }, + { SVCCTL_STOP_PENDING, "SVCCTL_STOP_PENDING" }, + { SVCCTL_RUNNING, "SVCCTL_RUNNING" }, + { SVCCTL_CONTINUE_PENDING, "SVCCTL_CONTINUE_PENDING" }, + { SVCCTL_PAUSE_PENDING, "SVCCTL_PAUSE_PENDING" }, + { SVCCTL_PAUSED, "SVCCTL_PAUSED" }, + { 0, NULL } +}; + + +/******************************************************************** +********************************************************************/ +const char* svc_status_string( uint32 state ) +{ + static fstring msg; + int i; + + fstr_sprintf( msg, "Unknown State [%d]", state ); + + for ( i=0; state_msg_table[i].message; i++ ) { + if ( state_msg_table[i].flag == state ) { + fstrcpy( msg, state_msg_table[i].message ); + break; + } + } + + return msg; +} + /******************************************************************** ********************************************************************/ @@ -67,6 +103,39 @@ WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx, /******************************************************************** ********************************************************************/ +WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hSCM, POLICY_HND *hService, + const char *servicename, uint32 access_desired ) +{ + SVCCTL_Q_OPEN_SERVICE in; + SVCCTL_R_OPEN_SERVICE out; + prs_struct qbuf, rbuf; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + memcpy( &in.handle, hSCM, sizeof(POLICY_HND) ); + init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE ); + in.access = access_desired; + + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W, + in, out, + qbuf, rbuf, + svcctl_io_q_open_service, + svcctl_io_r_open_service, + WERR_GENERAL_FAILURE ); + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + memcpy( hService, &out.handle, sizeof(POLICY_HND) ); + + return out.status; +} + +/******************************************************************** +********************************************************************/ + WERROR close_service_handle( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService ) { SVCCTL_Q_CLOSE_SERVICE in; @@ -125,7 +194,7 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx /* second time with correct buffer size...should be ok */ - if ( !W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { + if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { in.buffer_size = out.needed; CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, @@ -150,33 +219,98 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx *service_array = services; *returned = out.returned; - - return out.status; } /******************************************************************* *******************************************************************/ -WERROR cli_svcctl_start_service(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hService, SERVICE_STATUS *status ) { + SVCCTL_Q_QUERY_STATUS in; + SVCCTL_R_QUERY_STATUS out; + prs_struct qbuf, rbuf; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + memcpy( &in.handle, hService, sizeof(POLICY_HND) ); + + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS, + in, out, + qbuf, rbuf, + svcctl_io_q_query_status, + svcctl_io_r_query_status, + WERR_GENERAL_FAILURE ); + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; - return WERR_OK; + memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) ); + + return out.status; } /******************************************************************* *******************************************************************/ -WERROR cli_svcctl_control_service(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hService, SERVICE_CONFIG *config ) { + SVCCTL_Q_QUERY_SERVICE_CONFIG in; + SVCCTL_R_QUERY_SERVICE_CONFIG out; + prs_struct qbuf, rbuf; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + memcpy( &in.handle, hService, sizeof(POLICY_HND) ); + in.buffer_size = 0; + + + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W, + in, out, + qbuf, rbuf, + svcctl_io_q_query_service_config, + svcctl_io_r_query_service_config, + WERR_GENERAL_FAILURE ); + + if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { + in.buffer_size = out.needed; - return WERR_OK; + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W, + in, out, + qbuf, rbuf, + svcctl_io_q_query_service_config, + svcctl_io_r_query_service_config, + WERR_GENERAL_FAILURE ); + } + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + memcpy( config, &out.config, sizeof(SERVICE_CONFIG) ); + + config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 ); + config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 ); + config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 ); + config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 ); + config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 ); + + copy_unistr2( config->executablepath, out.config.executablepath ); + copy_unistr2( config->loadordergroup, out.config.loadordergroup ); + copy_unistr2( config->dependencies, out.config.dependencies ); + copy_unistr2( config->startname, out.config.startname ); + copy_unistr2( config->displayname, out.config.displayname ); + + return out.status; } /******************************************************************* *******************************************************************/ -WERROR cli_svcctl_query_status(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_start_service(struct cli_state *cli, TALLOC_CTX *mem_ctx ) { return WERR_OK; @@ -185,18 +319,54 @@ WERROR cli_svcctl_query_status(struct cli_state *cli, TALLOC_CTX *mem_ctx ) /******************************************************************* *******************************************************************/ -WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_control_service(struct cli_state *cli, TALLOC_CTX *mem_ctx ) { return WERR_OK; } + /******************************************************************* *******************************************************************/ -WERROR cli_svcctl_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hService, fstring displayname ) { + SVCCTL_Q_GET_DISPLAY_NAME in; + SVCCTL_R_GET_DISPLAY_NAME out; + prs_struct qbuf, rbuf; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + memcpy( &in.handle, hService, sizeof(POLICY_HND) ); + in.display_name_len = 0; + + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, + in, out, + qbuf, rbuf, + svcctl_io_q_get_display_name, + svcctl_io_r_get_display_name, + WERR_GENERAL_FAILURE ); + + /* second time with correct buffer size...should be ok */ + + if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { + in.display_name_len = out.display_name_len; - return WERR_OK; + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, + in, out, + qbuf, rbuf, + svcctl_io_q_get_display_name, + svcctl_io_r_get_display_name, + WERR_GENERAL_FAILURE ); + } + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE ); + + return out.status; } -- cgit