mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
r7563: svcctl patches from Marcin; have cleaned up formating and am checking the code in to snapshot it before I start changing more things
(This used to be commit 560ce111ce8de37d02bce64d2ca60a5f471d5477)
This commit is contained in:
parent
33a4c0b5a1
commit
d559edcce2
@ -36,6 +36,7 @@
|
||||
#define SVCCTL_START_SERVICE_W 0x13
|
||||
#define SVCCTL_GET_DISPLAY_NAME 0x14
|
||||
#define SVCCTL_QUERY_SERVICE_CONFIG2_W 0x27
|
||||
#define SVCCTL_QUERY_SERVICE_STATUSEX_W 0x28
|
||||
|
||||
/* ANSI versions not implemented currently
|
||||
#define SVCCTL_ENUM_SERVICES_STATUS_A 0x0e
|
||||
@ -72,11 +73,43 @@
|
||||
#define SVCCTL_ACCEPT_HARDWAREPROFILECHANGE 0x00000020
|
||||
#define SVCCTL_ACCEPT_POWEREVENT 0x00000040
|
||||
|
||||
/* SERVER_STATUS - ControlAccepted */
|
||||
#define SVCCTL_SVC_ERROR_IGNORE 0x00000000
|
||||
#define SVCCTL_SVC_ERROR_NORMAL 0x00000001
|
||||
#define SVCCTL_SVC_ERROR_CRITICAL 0x00000002
|
||||
#define SVCCTL_SVC_ERROR_SEVERE 0x00000003
|
||||
|
||||
/* QueryServiceConfig2 options */
|
||||
#define SERVICE_CONFIG_DESCRIPTION 0x00000001
|
||||
#define SERVICE_CONFIG_FAILURE_ACTIONS 0x00000002
|
||||
|
||||
|
||||
/* Service Config - values for ServiceType field*/
|
||||
|
||||
#define SVCCTL_KERNEL_DRVR 0x00000001 /* doubtful we'll have these */
|
||||
#define SVCCTL_FILE_SYSTEM_DRVR 0x00000002
|
||||
#define SVCCTL_WIN32_OWN_PROC 0x00000010
|
||||
#define SVCCTL_WIN32_SHARED_PROC 0x00000020
|
||||
#define SVCCTL_WIN32_INTERACTIVE 0x00000100
|
||||
|
||||
/* Service Config - values for StartType field */
|
||||
#define SVCCTL_BOOT_START 0x00000000
|
||||
#define SVCCTL_SYSTEM_START 0x00000001
|
||||
#define SVCCTL_AUTO_START 0x00000002
|
||||
#define SVCCTL_DEMAND_START 0x00000003
|
||||
#define SVCCTL_DISABLED 0x00000004
|
||||
|
||||
/* Service Controls */
|
||||
|
||||
#define SVCCTL_CONTROL_STOP 0x00000001
|
||||
#define SVCCTL_CONTROL_PAUSE 0x00000002
|
||||
#define SVCCTL_CONTROL_CONTINUE 0x00000003
|
||||
#define SVCCTL_CONTROL_SHUTDOWN 0x00000004
|
||||
|
||||
#define SVC_HANDLE_IS_SCM 0x0000001
|
||||
#define SVC_HANDLE_IS_SERVICE 0x0000002
|
||||
|
||||
#define SVC_STATUS_PROCESS_INFO 0x00000001
|
||||
|
||||
/* utility structures for RPCs */
|
||||
|
||||
@ -90,6 +123,19 @@ typedef struct {
|
||||
uint32 wait_hint;
|
||||
} SERVICE_STATUS;
|
||||
|
||||
typedef struct {
|
||||
uint32 type;
|
||||
uint32 state;
|
||||
uint32 controls_accepted;
|
||||
uint32 win32_exit_code;
|
||||
uint32 service_exit_code;
|
||||
uint32 check_point;
|
||||
uint32 wait_hint;
|
||||
uint32 process_id;
|
||||
uint32 service_flags;
|
||||
} SERVICE_STATUS_PROCESS;
|
||||
|
||||
|
||||
typedef struct {
|
||||
UNISTR servicename;
|
||||
UNISTR displayname;
|
||||
@ -108,6 +154,47 @@ typedef struct {
|
||||
UNISTR2 *displayname;
|
||||
} SERVICE_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *description;
|
||||
} SERVICE_DESCRIPTION;
|
||||
|
||||
typedef struct {
|
||||
uint32 type;
|
||||
uint32 delay;
|
||||
} SC_ACTION;
|
||||
|
||||
typedef struct {
|
||||
uint32 reset_period;
|
||||
UNISTR2 *rebootmsg;
|
||||
UNISTR2 *command;
|
||||
uint32 nActions;
|
||||
SC_ACTION *saActions;
|
||||
UNISTR2 *description;
|
||||
} SERVICE_FAILURE_ACTIONS;
|
||||
|
||||
|
||||
typedef struct SCM_info_struct {
|
||||
uint32 type; /* should be SVC_HANDLE_IS_SCM */
|
||||
pstring target_server_name; /* name of the server on which the operation is taking place */
|
||||
pstring target_db_name; /* name of the database that we're opening */
|
||||
} SCM_info;
|
||||
|
||||
typedef struct Service_info_struct {
|
||||
uint32 type; /* should be SVC_HANDLE_IS_SERVICE */
|
||||
pstring servicename; /* the name of the service */
|
||||
pstring servicetype; /* internal or external */
|
||||
pstring filename; /* what file name we can find this in,
|
||||
as well as the "index" for what the
|
||||
service name is */
|
||||
pstring provides;
|
||||
pstring dependencies;
|
||||
pstring shouldstart;
|
||||
pstring shouldstop;
|
||||
pstring requiredstart;
|
||||
pstring requiredstop;
|
||||
pstring shortdescription;
|
||||
pstring description;
|
||||
} Service_info;
|
||||
|
||||
/* rpc structures */
|
||||
|
||||
@ -118,6 +205,7 @@ typedef struct {
|
||||
} SVCCTL_Q_CLOSE_SERVICE;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
WERROR status;
|
||||
} SVCCTL_R_CLOSE_SERVICE;
|
||||
|
||||
@ -242,5 +330,32 @@ typedef struct {
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 info_level;
|
||||
uint32 buffer_size;
|
||||
} SVCCTL_Q_QUERY_SERVICE_CONFIG2;
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *description;
|
||||
uint32 returned;
|
||||
uint32 needed;
|
||||
uint32 offset;
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_CONFIG2;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 info_level;
|
||||
uint32 buffer_size;
|
||||
} SVCCTL_Q_QUERY_SERVICE_STATUSEX;
|
||||
|
||||
typedef struct {
|
||||
RPC_BUFFER buffer;
|
||||
uint32 returned;
|
||||
uint32 needed;
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_STATUSEX;
|
||||
|
||||
#endif /* _RPC_SVCCTL_H */
|
||||
|
||||
|
@ -566,7 +566,7 @@ BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
|
||||
Allocate the RPC_DATA_BLOB memory.
|
||||
********************************************************************/
|
||||
|
||||
static size_t create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
|
||||
size_t create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
|
||||
{
|
||||
str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
|
||||
if (str->buffer == NULL)
|
||||
|
@ -100,6 +100,21 @@ static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config,
|
||||
|
||||
return True;
|
||||
}
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL svcctl_io_service_description( const char *desc, UNISTR2 *svcdesc, prs_struct *ps, int depth )
|
||||
{
|
||||
|
||||
prs_debug(ps, depth, desc, "svcctl_io_service_description");
|
||||
depth++;
|
||||
|
||||
//DEBUG(10, ("_svcctl_io_service_description: descrption is [%s]\n",svcdesc));
|
||||
if (!prs_io_unistr2("", ps, depth, svcdesc))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
@ -142,6 +157,7 @@ uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status )
|
||||
|
||||
BOOL svcctl_io_q_close_service(const char *desc, SVCCTL_Q_CLOSE_SERVICE *q_u, prs_struct *ps, int depth)
|
||||
{
|
||||
|
||||
if (q_u == NULL)
|
||||
return False;
|
||||
|
||||
@ -170,7 +186,10 @@ BOOL svcctl_io_r_close_service(const char *desc, SVCCTL_R_CLOSE_SERVICE *r_u, pr
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("pol_handle", &r_u->handle, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_werror("status", ps, depth, &r_u->status))
|
||||
return False;
|
||||
@ -642,6 +661,7 @@ BOOL svcctl_io_r_query_service_config(const char *desc, SVCCTL_R_QUERY_SERVICE_C
|
||||
prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config");
|
||||
depth++;
|
||||
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
@ -654,6 +674,158 @@ BOOL svcctl_io_r_query_service_config(const char *desc, SVCCTL_R_QUERY_SERVICE_C
|
||||
if(!prs_werror("status", ps, depth, &r_u->status))
|
||||
return False;
|
||||
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL svcctl_io_q_query_service_config2(const char *desc, SVCCTL_Q_QUERY_SERVICE_CONFIG2 *q_u, prs_struct *ps, int depth)
|
||||
{
|
||||
if (q_u == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "svcctl_io_q_query_service_config2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("info_level", ps, depth, &q_u->info_level))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Creates a service description response buffer.
|
||||
The format seems to be DWORD:length of buffer
|
||||
DWORD:offset (fixed as four)
|
||||
UNISTR: unicode description in the rest of the buffer
|
||||
********************************************************************/
|
||||
|
||||
void init_service_description_buffer(RPC_DATA_BLOB *str, const char *service_desc, int blob_length)
|
||||
{
|
||||
uint32 offset;
|
||||
char *bp;
|
||||
|
||||
ZERO_STRUCTP(str);
|
||||
|
||||
offset = 4;
|
||||
|
||||
/* set up string lengths. */
|
||||
|
||||
str->buf_len = create_rpc_blob(str, blob_length);
|
||||
DEBUG(10, ("init_service_description buffer: Allocated a blob of [%d] \n",str->buf_len));
|
||||
|
||||
if ( str && str->buffer && str->buf_len) {
|
||||
memset(str->buffer,0,str->buf_len);
|
||||
memcpy(str->buffer, &offset, sizeof(uint32));
|
||||
bp = &str->buffer[4];
|
||||
if (service_desc) {
|
||||
rpcstr_push(bp, service_desc,str->buf_len-4,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL svcctl_io_q_query_service_status_ex(const char *desc, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, prs_struct *ps, int depth)
|
||||
{
|
||||
if (q_u == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "svcctl_io_q_query_service_status_ex");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("info_level", ps, depth, &q_u->info_level))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u, prs_struct *ps, int depth)
|
||||
{
|
||||
if ( !r_u )
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "svcctl_io_r_query_service_status_ex");
|
||||
depth++;
|
||||
|
||||
if (!prs_rpcbuffer("", ps, depth, &r_u->buffer))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("needed", ps, depth, &r_u->needed))
|
||||
return False;
|
||||
|
||||
if(!prs_werror("status", ps, depth, &r_u->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u, prs_struct *ps, int depth)
|
||||
{
|
||||
if ( !r_u )
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("returned", ps, depth, &r_u->returned))
|
||||
return False;
|
||||
|
||||
if (r_u->returned > 4) {
|
||||
if (!prs_uint32("offset", ps, depth, &r_u->offset))
|
||||
return False;
|
||||
if(!prs_unistr2(True, "description ", ps, depth, r_u->description))
|
||||
return False;
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
} else {
|
||||
/* offset does double duty here */
|
||||
r_u->offset = 0;
|
||||
if (!prs_uint32("offset", ps, depth, &r_u->offset))
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!prs_uint32("needed", ps, depth, &r_u->needed))
|
||||
return False;
|
||||
|
||||
if(!prs_werror("status", ps, depth, &r_u->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,29 @@ static BOOL api_svcctl_enum_services_status(pipes_struct *p)
|
||||
|
||||
return True;
|
||||
}
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
static BOOL api_svcctl_query_service_status_ex(pipes_struct *p)
|
||||
{
|
||||
SVCCTL_Q_QUERY_SERVICE_STATUSEX q_u;
|
||||
SVCCTL_R_QUERY_SERVICE_STATUSEX r_u;
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
if(!svcctl_io_q_query_service_status_ex("", &q_u, data, 0))
|
||||
return False;
|
||||
|
||||
r_u.status = _svcctl_query_service_status_ex(p, &q_u, &r_u);
|
||||
|
||||
if(!svcctl_io_r_query_service_status_ex("", &r_u, rdata, 0))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
@ -263,6 +285,30 @@ static BOOL api_svcctl_query_service_config(pipes_struct *p)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
static BOOL api_svcctl_query_service_config2(pipes_struct *p)
|
||||
{
|
||||
SVCCTL_Q_QUERY_SERVICE_CONFIG2 q_u;
|
||||
SVCCTL_R_QUERY_SERVICE_CONFIG2 r_u;
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
if(!svcctl_io_q_query_service_config2("", &q_u, data, 0))
|
||||
return False;
|
||||
|
||||
r_u.status = _svcctl_query_service_config2(p, &q_u, &r_u);
|
||||
|
||||
if(!svcctl_io_r_query_service_config2("", &r_u, rdata, 0))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
\PIPE\svcctl commands
|
||||
********************************************************************/
|
||||
@ -275,12 +321,15 @@ static struct api_struct api_svcctl_cmds[] =
|
||||
{ "SVCCTL_GET_DISPLAY_NAME" , SVCCTL_GET_DISPLAY_NAME , api_svcctl_get_display_name },
|
||||
{ "SVCCTL_QUERY_STATUS" , SVCCTL_QUERY_STATUS , api_svcctl_query_status },
|
||||
{ "SVCCTL_QUERY_SERVICE_CONFIG_W", SVCCTL_QUERY_SERVICE_CONFIG_W, api_svcctl_query_service_config },
|
||||
{ "SVCCTL_QUERY_SERVICE_CONFIG2_W", SVCCTL_QUERY_SERVICE_CONFIG2_W, api_svcctl_query_service_config2 },
|
||||
{ "SVCCTL_ENUM_SERVICES_STATUS_W", SVCCTL_ENUM_SERVICES_STATUS_W, api_svcctl_enum_services_status },
|
||||
{ "SVCCTL_ENUM_DEPENDENT_SERVICES_W", SVCCTL_ENUM_DEPENDENT_SERVICES_W, api_svcctl_enum_dependent_services },
|
||||
{ "SVCCTL_START_SERVICE_W" , SVCCTL_START_SERVICE_W , api_svcctl_start_service },
|
||||
{ "SVCCTL_CONTROL_SERVICE" , SVCCTL_CONTROL_SERVICE , api_svcctl_control_service }
|
||||
{ "SVCCTL_CONTROL_SERVICE" , SVCCTL_CONTROL_SERVICE , api_svcctl_control_service },
|
||||
{ "SVCCTL_QUERY_SERVICE_STATUSEX_W", SVCCTL_QUERY_SERVICE_STATUSEX_W, api_svcctl_query_service_status_ex }
|
||||
};
|
||||
|
||||
|
||||
void svcctl_get_pipe_fns( struct api_struct **fns, int *n_fns )
|
||||
{
|
||||
*fns = api_svcctl_cmds;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -887,6 +887,9 @@ void build_options(BOOL screen);
|
||||
if (!init_registry())
|
||||
exit(1);
|
||||
|
||||
if (!init_svcctl_db())
|
||||
exit(1);
|
||||
|
||||
if (!print_backend_init())
|
||||
exit(1);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user