HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / dissectors / packet-dcerpc-svcctl.c
1 /* packet-dcerpc-svcctl.c
2  * Routines for SMB \PIPE\svcctl packet disassembly
3  * Copyright 2003, Tim Potter <tpot@samba.org>
4  * Copyright 2003, Ronnie Sahlberg,  added function dissectors
5  * Copyright 2010, Brett Kuskie <fullaxx@gmail.com>
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * SPDX-License-Identifier: GPL-2.0-or-later
12  */
13
14 #include "config.h"
15
16 #include <epan/packet.h>
17 #include "packet-dcerpc.h"
18 #include "packet-dcerpc-svcctl.h"
19 #include "packet-dcerpc-nt.h"
20 #include "packet-windows-common.h"
21
22 void proto_register_dcerpc_svcctl(void);
23 void proto_reg_handoff_dcerpc_svcctl(void);
24
25 static int proto_dcerpc_svcctl = -1;
26 static int hf_svcctl_opnum = -1;
27 static int hf_svcctl_machinename = -1;
28 static int hf_svcctl_database = -1;
29 static int hf_svcctl_access_mask = -1;
30 static int hf_svcctl_scm_rights_connect = -1;
31 static int hf_svcctl_scm_rights_create_service = -1;
32 static int hf_svcctl_scm_rights_enumerate_service = -1;
33 static int hf_svcctl_scm_rights_lock = -1;
34 static int hf_svcctl_scm_rights_query_lock_status = -1;
35 static int hf_svcctl_scm_rights_modify_boot_config = -1;
36 static int hf_svcctl_hnd = -1;
37 static int hf_svcctl_lock = -1;
38 static int hf_svcctl_rc = -1;
39 static int hf_svcctl_size = -1;
40 static int hf_svcctl_required_size = -1;
41 static int hf_svcctl_is_locked = -1;
42 static int hf_svcctl_lock_duration = -1;
43 static int hf_svcctl_lock_owner = -1;
44 static int hf_svcctl_service_type = -1;
45 static int hf_svcctl_service_type_kernel_driver = -1;
46 static int hf_svcctl_service_type_fs_driver = -1;
47 static int hf_svcctl_service_type_win32_own_process = -1;
48 static int hf_svcctl_service_type_win32_share_process = -1;
49 static int hf_svcctl_service_type_interactive_process = -1;
50 static int hf_svcctl_service_state = -1;
51 static int hf_svcctl_buffer = -1;
52 /* static int hf_svcctl_bytes_needed = -1; */
53 /* static int hf_svcctl_services_returned = -1; */
54 static int hf_svcctl_resume = -1;
55 static int hf_svcctl_service_name = -1;
56 static int hf_svcctl_display_name = -1;
57 static int hf_svcctl_service_start_type = -1;
58 static int hf_svcctl_service_error_control = -1;
59 static int hf_svcctl_binarypathname = -1;
60 static int hf_svcctl_loadordergroup = -1;
61 static int hf_svcctl_tagid = -1;
62 static int hf_svcctl_dependencies = -1;
63 static int hf_svcctl_depend_size = -1;
64 static int hf_svcctl_service_start_name = -1;
65 static int hf_svcctl_password = -1;
66 static int hf_svcctl_password_size = -1;
67
68 static gint ett_dcerpc_svcctl = -1;
69 static gint ett_dcerpc_svcctl_service_type_bits = -1;
70
71 static e_guid_t uuid_dcerpc_svcctl = {
72         0x367abb81, 0x9844, 0x35f1,
73         { 0xad, 0x32, 0x98, 0xf0, 0x38, 0x00, 0x10, 0x03 }
74 };
75
76 static guint16 ver_dcerpc_svcctl = 2;
77
78 #define SVCCTL_SERVICE_TYPE_KERNEL_DRIVER       0x01
79 #define SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER  0x02
80 #define SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS   0x10
81 #define SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS 0x20
82 #define SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS 0x100
83 #define SVCCTL_SERVICE_TYPE_NO_CHANGE           0xffffffff
84 static const true_false_string tfs_svcctl_service_type_kernel_driver = {
85         "Is a kernel driver service",
86         "Is not a kernel driver service"
87 };
88 static const true_false_string tfs_svcctl_service_type_fs_driver = {
89         "Is a file system driver service",
90         "Is not a file system driver service"
91 };
92 static const true_false_string tfs_svcctl_service_type_win32_own_process = {
93         "Service runs its own processes",
94         "Service does not run its own process"
95 };
96 static const true_false_string tfs_svcctl_service_type_win32_share_process = {
97         "Service shares its process",
98         "Service does not share its process"
99 };
100 static const true_false_string tfs_svcctl_service_type_interactive_process = {
101         "Service can interact with the desktop",
102         "Service cannot interact with the desktop"
103 };
104
105 static int
106 svcctl_dissect_dwServiceType_flags(tvbuff_t *tvb, int offset,
107                         packet_info *pinfo, proto_tree *parent_tree,
108                         guint8 *drep, int opnum)
109 {
110         guint32 value, len = 4;
111         proto_item *item = NULL;
112         proto_tree *tree = NULL;
113
114         (void) dissect_dcerpc_uint32 (tvb, offset, pinfo, NULL, drep, 0, &value);
115         if(parent_tree) {
116                 item = proto_tree_add_uint(parent_tree, hf_svcctl_service_type, tvb, offset, len, value);
117                 tree = proto_item_add_subtree(item, ett_dcerpc_svcctl_service_type_bits);
118         }
119
120         switch(opnum) {
121         case SVC_CREATE_SERVICE_W:
122                 proto_tree_add_boolean(tree, hf_svcctl_service_type_interactive_process,
123                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS);
124                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
125                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
126                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
127                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
128                 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
129                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
130                 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
131                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
132                 break;
133         case SVC_ENUM_SERVICES_STATUS_W:
134                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
135                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
136                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
137                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
138                 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
139                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
140                 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
141                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
142                 break;
143         case SVC_QUERY_SERVICE_CONFIG_W:
144                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
145                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
146                 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
147                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
148                 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
149                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
150                 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
151                         tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
152                 break;
153         }
154
155         offset += len;
156         return offset;
157 }
158
159 #define SVCCTL_SERVICE_ACTIVE       0x01
160 #define SVCCTL_SERVICE_INACTIVE     0x02
161 #define SVCCTL_SERVICE_STATE_ALL    0x03
162 static const value_string svcctl_service_status_vals[] = {
163         { SVCCTL_SERVICE_ACTIVE,    "SERVICE_ACTIVE" },
164         { SVCCTL_SERVICE_INACTIVE,  "SERVICE_INACTIVE" },
165         { SVCCTL_SERVICE_STATE_ALL, "SERVICE_STATE_ALL" },
166         { 0, NULL }
167 };
168
169 #define SVCCTL_SERVICE_BOOT_START       0x00
170 #define SVCCTL_SERVICE_SYSTEM_START     0x01
171 #define SVCCTL_SERVICE_AUTO_START       0x02
172 #define SVCCTL_SERVICE_DEMAND_START     0x03
173 #define SVCCTL_SERVICE_DISABLED         0x04
174 static const value_string svcctl_service_start_type_vals[] = {
175         { SVCCTL_SERVICE_BOOT_START,    "SERVICE_BOOT_START" },
176         { SVCCTL_SERVICE_SYSTEM_START,  "SERVICE_SYSTEM_START" },
177         { SVCCTL_SERVICE_AUTO_START,    "SERVICE_AUTO_START" },
178         { SVCCTL_SERVICE_DEMAND_START,  "SERVICE_DEMAND_START" },
179         { SVCCTL_SERVICE_DISABLED,      "SERVICE_DISABLED" },
180         { 0, NULL }
181 };
182
183 #define SVCCTL_SERVICE_ERROR_IGNORE     0x00
184 #define SVCCTL_SERVICE_ERROR_NORMAL     0x01
185 #define SVCCTL_SERVICE_ERROR_SEVERE     0x02
186 #define SVCCTL_SERVICE_ERROR_CRITICAL   0x03
187 static const value_string svcctl_service_error_control_vals[] = {
188         { SVCCTL_SERVICE_ERROR_IGNORE,   "SERVICE_ERROR_IGNORE" },
189         { SVCCTL_SERVICE_ERROR_NORMAL,   "SERVICE_ERROR_NORMAL" },
190         { SVCCTL_SERVICE_ERROR_SEVERE,   "SERVICE_ERROR_SEVERE" },
191         { SVCCTL_SERVICE_ERROR_CRITICAL, "SERVICE_ERROR_CRITICAL" },
192         { 0, NULL }
193 };
194
195 static int
196 svcctl_dissect_pointer_long(tvbuff_t *tvb, int offset,
197                             packet_info *pinfo, proto_tree *tree,
198                             dcerpc_info *di, guint8 *drep)
199 {
200         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
201                                      di->hf_index, NULL);
202         return offset;
203 }
204
205 static void
206 svcctl_scm_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree,
207                     guint32 access)
208 {
209         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_modify_boot_config, tvb, offset, 4, access);
210         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_query_lock_status, tvb, offset, 4, access);
211         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_lock, tvb, offset, 4, access);
212         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_enumerate_service, tvb, offset, 4, access);
213         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_create_service, tvb, offset, 4, access);
214         proto_tree_add_boolean(tree, hf_svcctl_scm_rights_connect, tvb, offset, 4, access);
215 }
216
217 struct access_mask_info svcctl_scm_access_mask_info = {
218         "SVCCTL",
219         svcctl_scm_specific_rights,
220         NULL,                   /* Generic mapping table */
221         NULL                    /* Standard mapping table */
222 };
223
224 /*
225  * IDL long OpenSCManager(
226  * IDL      [in] [string] [unique] char *MachineName,
227  * IDL      [in] [string] [unique] char *DatabaseName,
228  * IDL      [in] long access_mask,
229  * IDL      [out] SC_HANDLE handle,
230  * IDL );
231  */
232 static int
233 svcctl_dissect_OpenSCManager_rqst(tvbuff_t *tvb, int offset,
234                                   packet_info *pinfo, proto_tree *tree,
235                                   dcerpc_info *di, guint8 *drep)
236 {
237         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
238         const char *mn, *dn;
239
240         /* MachineName */
241         dcv->private_data=NULL;
242         offset = dissect_ndr_pointer_cb(
243                 tvb, offset, pinfo, tree, di, drep,
244                 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
245                 "MachineName", hf_svcctl_machinename, cb_str_postprocess,
246                 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
247         mn=(const char *)dcv->private_data;
248         if(!mn)
249                 mn="";
250
251         /* DatabaseName */
252         dcv->private_data=NULL;
253         offset = dissect_ndr_pointer_cb(
254                 tvb, offset, pinfo, tree, di, drep,
255                 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
256                 "Database", hf_svcctl_database, cb_str_postprocess,
257                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
258         dn=(const char *)dcv->private_data;
259         if(!dn)
260                 dn="";
261
262         /* OpenSCManager() stores the server\database  in se_data */
263         if(!pinfo->fd->visited){
264                 if(!dcv->se_data){
265                         dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
266                 }
267         }
268
269         /* access mask */
270         offset = dissect_nt_access_mask(
271                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
272                 &svcctl_scm_access_mask_info, NULL);
273
274         return offset;
275 }
276
277 static int
278 svcctl_dissect_OpenSCManager_reply(tvbuff_t *tvb, int offset,
279                                   packet_info *pinfo, proto_tree *tree,
280                                   dcerpc_info *di, guint8 *drep)
281 {
282         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
283         e_ctx_hnd policy_hnd;
284         proto_item *hnd_item;
285         guint32 status;
286
287         /* Parse packet */
288
289         offset = dissect_nt_policy_hnd(
290                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
291                 &hnd_item, TRUE, FALSE);
292
293         offset = dissect_doserror(
294                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
295
296         if( status == 0 ){
297                 const char *pol_name;
298
299                 if (dcv->se_data){
300                         pol_name = wmem_strdup_printf(wmem_packet_scope(),
301                                 "OpenSCManagerW(%s)", (char *)dcv->se_data);
302                 } else {
303                         pol_name = "Unknown OpenSCManagerW() handle";
304                 }
305                 if(!pinfo->fd->visited){
306                         dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
307                 }
308
309                 if(hnd_item)
310                         proto_item_append_text(hnd_item, ": %s", pol_name);
311         }
312
313         return offset;
314 }
315
316 static int
317 svcctl_dissect_OpenSCManagerW_rqst(tvbuff_t *tvb, int offset,
318                                   packet_info *pinfo, proto_tree *tree,
319                                   dcerpc_info *di, guint8 *drep)
320 {
321         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
322         const char *mn, *dn;
323
324         /* MachineName */
325         dcv->private_data=NULL;
326         offset = dissect_ndr_pointer_cb(
327                 tvb, offset, pinfo, tree, di, drep,
328                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
329                 "MachineName", hf_svcctl_machinename, cb_wstr_postprocess,
330                 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
331         mn=(const char *)dcv->private_data;
332         if(!mn)
333                 mn="";
334
335         /* DatabaseName */
336         dcv->private_data=NULL;
337         offset = dissect_ndr_pointer_cb(
338                 tvb, offset, pinfo, tree, di, drep,
339                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
340                 "Database", hf_svcctl_database, cb_wstr_postprocess,
341                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
342         dn=(const char *)dcv->private_data;
343         if(!dn)
344                 dn="";
345
346         /* OpenSCManager() stores the server\database  in se_data */
347         if(!pinfo->fd->visited){
348                 if(!dcv->se_data){
349                         dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
350                 }
351         }
352
353         /* access mask */
354         offset = dissect_nt_access_mask(
355                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
356                 &svcctl_scm_access_mask_info, NULL);
357
358         return offset;
359 }
360
361 static int
362 svcctl_dissect_OpenSCManagerW_reply(tvbuff_t *tvb, int offset,
363                                   packet_info *pinfo, proto_tree *tree,
364                                   dcerpc_info *di, guint8 *drep)
365 {
366         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
367         e_ctx_hnd policy_hnd;
368         proto_item *hnd_item;
369         guint32 status;
370
371         /* Parse packet */
372
373         offset = dissect_nt_policy_hnd(
374                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
375                 &hnd_item, TRUE, FALSE);
376
377         offset = dissect_doserror(
378                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
379
380         if( status == 0 ){
381                 const char *pol_name;
382
383                 if (dcv->se_data){
384                         pol_name = wmem_strdup_printf(wmem_packet_scope(),
385                                 "OpenSCManagerW(%s)", (char *)dcv->se_data);
386                 } else {
387                         pol_name = "Unknown OpenSCManagerW() handle";
388                 }
389                 if(!pinfo->fd->visited){
390                         dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
391                 }
392
393                 if(hnd_item)
394                         proto_item_append_text(hnd_item, ": %s", pol_name);
395         }
396
397         return offset;
398 }
399
400 static int
401 svcctl_dissect_CreateServiceW_rqst(tvbuff_t *tvb, int offset,
402                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
403 {
404         /* policy handle */
405         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
406                 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
407
408         /* service name */
409         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
410                 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
411
412         /* display name */
413         offset = dissect_ndr_pointer_cb(
414                 tvb, offset, pinfo, tree, di, drep,
415                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
416                 "Display Name", hf_svcctl_display_name, cb_wstr_postprocess,
417                 GINT_TO_POINTER(1));
418
419         /* access mask */
420         offset = dissect_nt_access_mask(
421                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
422                 &svcctl_scm_access_mask_info, NULL);
423
424         /* service type */
425         offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_CREATE_SERVICE_W);
426
427         /* service start type */
428         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
429                 hf_svcctl_service_start_type, NULL);
430
431         /* service error control */
432         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
433                 hf_svcctl_service_error_control, NULL);
434
435         /* binary path name */
436         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
437                 sizeof(guint16), hf_svcctl_binarypathname, TRUE, NULL);
438
439         /* load order group */
440         offset = dissect_ndr_pointer_cb(
441                 tvb, offset, pinfo, tree, di, drep,
442                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
443                 "Load Order Group", hf_svcctl_loadordergroup, cb_wstr_postprocess,
444                 GINT_TO_POINTER(1));
445
446         /* tag id */
447         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
448                 hf_svcctl_tagid, NULL);
449
450         /* dependencies */
451         offset = dissect_ndr_pointer_cb(
452                 tvb, offset, pinfo, tree, di, drep,
453                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
454                 "Dependencies", hf_svcctl_dependencies, cb_wstr_postprocess,
455                 GINT_TO_POINTER(1));
456
457         /* depend size */
458         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
459                 hf_svcctl_depend_size, NULL);
460
461         /* service start name */
462         offset = dissect_ndr_pointer_cb(
463                 tvb, offset, pinfo, tree, di, drep,
464                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
465                 "Service Start Name", hf_svcctl_service_start_name, cb_wstr_postprocess,
466                 GINT_TO_POINTER(1));
467
468         /* password */
469         offset = dissect_ndr_pointer_cb(
470                 tvb, offset, pinfo, tree, di, drep,
471                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
472                 "Password", hf_svcctl_password, cb_wstr_postprocess,
473                 GINT_TO_POINTER(1));
474
475         /* password size */
476         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
477                 hf_svcctl_password_size, NULL);
478
479         return offset;
480 }
481
482 static int
483 svcctl_dissect_CreateServiceW_reply(tvbuff_t *tvb, int offset,
484                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
485 {
486         /* tag id */
487         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
488                 hf_svcctl_tagid, NULL);
489
490         /* policy handle */
491         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
492                 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
493
494         offset = dissect_doserror(
495                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
496
497         return offset;
498 }
499
500
501 /*
502  * IDL BOOL CloseServiceHandle(
503  * IDL      [in][out] SC_HANDLE handle
504  * IDL );
505  */
506 static int
507 svcctl_dissect_CloseServiceHandle_rqst(tvbuff_t *tvb, int offset,
508                                   packet_info *pinfo, proto_tree *tree,
509                                   dcerpc_info *di, guint8 *drep)
510 {
511         e_ctx_hnd policy_hnd;
512         char *pol_name;
513
514         /* Parse packet */
515
516         offset = dissect_nt_policy_hnd(
517                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
518                 NULL, FALSE, TRUE);
519
520         dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
521                              pinfo->num);
522
523         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
524                                 pol_name);
525
526         return offset;
527 }
528
529 static int
530 svcctl_dissect_CloseServiceHandle_reply(tvbuff_t *tvb, int offset,
531                                   packet_info *pinfo, proto_tree *tree,
532                                   dcerpc_info *di, guint8 *drep)
533 {
534         offset = dissect_nt_policy_hnd(
535                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
536                 NULL, FALSE, TRUE);
537
538         offset = dissect_doserror(
539                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
540
541         return offset;
542 }
543
544
545
546 /*
547  * IDL long LockServiceDatabase(
548  * IDL      [in] SC_HANDLE dbhandle,
549  * IDL      [out] SC_HANDLE lock,
550  * IDL );
551  */
552 static int
553 svcctl_dissect_LockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
554                                   packet_info *pinfo, proto_tree *tree,
555                                   dcerpc_info *di, guint8 *drep)
556 {
557         /* XXX - why is the "is a close" argument TRUE? */
558         offset = dissect_nt_policy_hnd(
559                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
560                 NULL, FALSE, TRUE);
561
562         return offset;
563 }
564 static int
565 svcctl_dissect_LockServiceDatabase_reply(tvbuff_t *tvb, int offset,
566                                   packet_info *pinfo, proto_tree *tree,
567                                   dcerpc_info *di, guint8 *drep)
568 {
569         /* XXX - why is the "is an open" argument TRUE? */
570         offset = dissect_nt_policy_hnd(
571                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
572                 NULL, TRUE, FALSE);
573
574         offset = dissect_doserror(
575                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
576
577         return offset;
578 }
579
580
581
582 /*
583  * IDL long UnlockServiceDatabase(
584  * IDL      [in][out] SC_HANDLE lock,
585  * IDL );
586  */
587 static int
588 svcctl_dissect_UnlockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
589                                   packet_info *pinfo, proto_tree *tree,
590                                   dcerpc_info *di, guint8 *drep)
591 {
592         /* XXX - why is the "is a close" argument TRUE? */
593         offset = dissect_nt_policy_hnd(
594                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
595                 NULL, FALSE, TRUE);
596
597         return offset;
598 }
599 static int
600 svcctl_dissect_UnlockServiceDatabase_reply(tvbuff_t *tvb, int offset,
601                                   packet_info *pinfo, proto_tree *tree,
602                                   dcerpc_info *di, guint8 *drep)
603 {
604         /* XXX - why is the "is an open" argument TRUE? */
605         offset = dissect_nt_policy_hnd(
606                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
607                 NULL, TRUE, FALSE);
608
609         offset = dissect_doserror(
610                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
611
612         return offset;
613 }
614
615
616 /*
617  * IDL typedef struct {
618  * IDL     long is_locked,
619  * IDL     [unique][string] char *lock_owner,
620  * IDL     long lock_duration,
621  * IDL };
622  */
623 static int
624 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS(tvbuff_t *tvb, int offset,
625                                   packet_info *pinfo, proto_tree *tree,
626                                   dcerpc_info *di, guint8 *drep)
627 {
628         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
629                                     hf_svcctl_is_locked, NULL);
630
631         offset = dissect_ndr_pointer(
632                 tvb, offset, pinfo, tree, di, drep,
633                 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
634                 "Owner", hf_svcctl_lock_owner);
635
636         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
637                                     hf_svcctl_lock_duration, NULL);
638
639         return offset;
640 }
641
642 /*
643  * IDL long QueryServiceLockStatus(
644  * IDL      [in] SC_HANDLE db_handle,
645  * IDL      [in] long buf_size,
646  * IDL      [out][ref] QUERY_SERVICE_LOCK_STATUS *status,
647  * IDL      [out][ref] long *required_buf_size
648  * IDL );
649  */
650 static int
651 svcctl_dissect_QueryServiceLockStatus_rqst(tvbuff_t *tvb, int offset,
652                                   packet_info *pinfo, proto_tree *tree,
653                                   dcerpc_info *di, guint8 *drep)
654 {
655         /* XXX - why is the "is a close" argument TRUE? */
656         offset = dissect_nt_policy_hnd(
657                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
658                 NULL, FALSE, TRUE);
659
660         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
661                                     hf_svcctl_size, NULL);
662
663         return offset;
664 }
665 static int
666 svcctl_dissect_QueryServiceLockStatus_reply(tvbuff_t *tvb, int offset,
667                                   packet_info *pinfo, proto_tree *tree,
668                                   dcerpc_info *di, guint8 *drep)
669 {
670         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
671                 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS, NDR_POINTER_REF,
672                 "LOCK_STATUS", -1);
673
674         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
675                                     hf_svcctl_required_size, NULL);
676
677         offset = dissect_doserror(
678                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
679
680         return offset;
681 }
682
683 /*
684  * IDL long EnumServicesStatus(
685  * IDL      [in] SC_HANDLE db_handle,
686  * IDL      [in] long type,
687  * IDL      [in] long status,
688  * IDL      [in] long buf_size,
689  * IDL      [in][unique] long *resume_handle,
690  * IDL );
691  */
692
693 static int
694 svcctl_dissect_EnumServicesStatus_rqst(tvbuff_t *tvb, int offset,
695                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
696 {
697         /* policy handle */
698         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
699                         hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
700
701         /* service type */
702         offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_ENUM_SERVICES_STATUS_W);
703
704         /* service state */
705         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
706                         hf_svcctl_service_state, NULL);
707
708         /* size */
709         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
710                         hf_svcctl_size, NULL);
711
712         /* resume handle */
713         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
714                         svcctl_dissect_pointer_long, NDR_POINTER_UNIQUE,
715                         "Resume Handle", hf_svcctl_resume);
716
717         return offset;
718 }
719
720 static int
721 svcctl_dissect_OpenServiceW_rqst(tvbuff_t *tvb, int offset,
722                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
723 {
724         /* policy handle */
725         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
726                 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
727
728         /* service name */
729         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
730                 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
731
732         /* access mask */
733         offset = dissect_nt_access_mask(
734                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
735                 &svcctl_scm_access_mask_info, NULL);
736
737         return offset;
738 }
739
740 static int
741 svcctl_dissect_OpenServiceW_reply(tvbuff_t *tvb, int offset,
742                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
743 {
744         /* policy handle */
745         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
746                 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
747
748         offset = dissect_doserror(
749                 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
750
751         return offset;
752 }
753
754 static int
755 svcctl_dissect_QueryServiceConfigW_rqst(tvbuff_t *tvb, int offset,
756                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
757 {
758         /* policy handle */
759         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
760                 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
761
762         /* cbBufSize */
763         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
764                 hf_svcctl_buffer, NULL);
765
766         return offset;
767 }
768
769 static dcerpc_sub_dissector dcerpc_svcctl_dissectors[] = {
770         { SVC_CLOSE_SERVICE_HANDLE, "CloseServiceHandle",
771                 svcctl_dissect_CloseServiceHandle_rqst,
772                 svcctl_dissect_CloseServiceHandle_reply  },
773         { SVC_CONTROL_SERVICE, "ControlService", NULL, NULL },
774         { SVC_DELETE_SERVICE, "DeleteService", NULL, NULL },
775         { SVC_LOCK_SERVICE_DATABASE, "LockServiceDatabase",
776                 svcctl_dissect_LockServiceDatabase_rqst,
777                 svcctl_dissect_LockServiceDatabase_reply  },
778         { SVC_QUERY_SERVICE_OBJECT_SECURITY, "QueryServiceObjectSecurity",
779           NULL, NULL },
780         { SVC_SET_SERVICE_OBJECT_SECURITY, "SetServiceObjectSecurity",
781           NULL, NULL },
782         { SVC_QUERY_SERVICE_STATUS, "QueryServiceStatus",
783           NULL, NULL },
784         { SVC_SET_SERVICE_STATUS, "SetServiceStatus",
785           NULL, NULL },
786         { SVC_UNLOCK_SERVICE_DATABASE, "UnlockServiceDatabase",
787                 svcctl_dissect_UnlockServiceDatabase_rqst,
788                 svcctl_dissect_UnlockServiceDatabase_reply  },
789         { SVC_NOTIFY_BOOT_CONFIG_STATUS, "NotifyBootConfigStatus",
790           NULL, NULL },
791         { SVC_SC_SET_SERVICE_BITS_W, "ScSetServiceBitsW",
792           NULL, NULL },
793         { SVC_CHANGE_SERVICE_CONFIG_W, "ChangeServiceConfigW",
794           NULL, NULL },
795         { SVC_CREATE_SERVICE_W, "CreateServiceW",
796           svcctl_dissect_CreateServiceW_rqst,
797           svcctl_dissect_CreateServiceW_reply },
798         { SVC_ENUM_DEPENDENT_SERVICES_W, "EnumDependentServicesW",
799           NULL, NULL },
800         { SVC_ENUM_SERVICES_STATUS_W, "EnumServicesStatusW",
801           svcctl_dissect_EnumServicesStatus_rqst, NULL },
802         { SVC_OPEN_SC_MANAGER_W, "OpenSCManagerW",
803                 svcctl_dissect_OpenSCManagerW_rqst,
804                 svcctl_dissect_OpenSCManagerW_reply },
805         { SVC_OPEN_SERVICE_W, "OpenServiceW",
806                 svcctl_dissect_OpenServiceW_rqst,
807                 svcctl_dissect_OpenServiceW_reply },
808         { SVC_QUERY_SERVICE_CONFIG_W, "QueryServiceConfigW",
809                 svcctl_dissect_QueryServiceConfigW_rqst, NULL },
810         { SVC_QUERY_SERVICE_LOCK_STATUS_W, "QueryServiceLockStatusW",
811           NULL, NULL },
812         { SVC_START_SERVICE_W, "StartServiceW", NULL, NULL },
813         { SVC_GET_SERVICE_DISPLAY_NAME_W, "GetServiceDisplayNameW",
814           NULL, NULL },
815         { SVC_GET_SERVICE_KEY_NAME_W, "GetServiceKeyNameW", NULL, NULL },
816         { SVC_SC_SET_SERVICE_BITS_A, "ScSetServiceBitsA", NULL, NULL },
817         { SVC_CHANGE_SERVICE_CONFIG_A, "ChangeServiceConfigA", NULL, NULL },
818         { SVC_CREATE_SERVICE_A, "CreateServiceA", NULL, NULL },
819         { SVC_ENUM_DEPENDENT_SERVICES_A, "EnumDependentServicesA",
820           NULL, NULL },
821         { SVC_ENUM_SERVICES_STATUS_A, "EnumServicesStatusA",
822                 svcctl_dissect_EnumServicesStatus_rqst,
823                 NULL },
824         { SVC_OPEN_SC_MANAGER_A, "OpenSCManagerA",
825                 svcctl_dissect_OpenSCManager_rqst,
826                 svcctl_dissect_OpenSCManager_reply },
827         { SVC_OPEN_SERVICE_A, "OpenServiceA", NULL, NULL },
828         { SVC_QUERY_SERVICE_CONFIG_A, "QueryServiceConfigA", NULL, NULL },
829         { SVC_QUERY_SERVICE_LOCK_STATUS_A, "QueryServiceLockStatusA",
830                 svcctl_dissect_QueryServiceLockStatus_rqst,
831                 svcctl_dissect_QueryServiceLockStatus_reply },
832         { SVC_START_SERVICE_A, "StartServiceA", NULL, NULL },
833         { SVC_GET_SERVICE_DISPLAY_NAME_A, "GetServiceDisplayNameA",
834           NULL, NULL },
835         { SVC_GET_SERVICE_KEY_NAME_A, "GetServiceKeyNameA", NULL, NULL },
836         { SVC_SC_GET_CURRENT_GROUPE_STATE_W, "ScGetCurrentGroupStateW",
837           NULL, NULL },
838         { SVC_ENUM_SERVICE_GROUP_W, "EnumServiceGroupW",
839           NULL, NULL },
840         { SVC_CHANGE_SERVICE_CONFIG2_A, "ChangeServiceConfig2A",
841           NULL, NULL },
842         { SVC_CHANGE_SERVICE_CONFIG2_W, "ChangeServiceConfig2W",
843           NULL, NULL },
844         { SVC_QUERY_SERVICE_CONFIG2_A, "QueryServiceConfig2A",
845           NULL, NULL },
846         { SVC_QUERY_SERVICE_CONFIG2_W, "QueryServiceConfig2W",
847           NULL, NULL },
848         { SVC_QUERY_SERVICE_STATUS_EX, "QueryServiceStatusEx",
849           NULL, NULL },
850         { SVC_ENUM_SERVICES_STATUS_EX_A, "EnumServicesStatusExA",
851           NULL, NULL },
852         { SVC_ENUM_SERVICES_STATUS_EX_W, "EnumServicesStatusExW",
853           NULL, NULL },
854         { SVC_SC_SEND_TS_MESSAGE, "ScSendTSMessage",
855           NULL, NULL },
856         {0, NULL, NULL, NULL}
857 };
858
859 void
860 proto_register_dcerpc_svcctl(void)
861 {
862         static hf_register_info hf[] = {
863                 { &hf_svcctl_opnum,
864                   { "Operation", "svcctl.opnum", FT_UINT16, BASE_DEC,
865                     NULL, 0x0, NULL, HFILL }},
866                 { &hf_svcctl_machinename,
867                   { "MachineName", "svcctl.machinename", FT_STRING, BASE_NONE,
868                     NULL, 0x0, "Name of the host we want to open the database on", HFILL }},
869                 { &hf_svcctl_database,
870                   { "Database", "svcctl.database", FT_STRING, BASE_NONE,
871                     NULL, 0x0, "Name of the database to open", HFILL }},
872                 { &hf_svcctl_access_mask,
873                   { "Access Mask", "svcctl.access_mask", FT_UINT32, BASE_HEX,
874                     NULL, 0x0, "SVCCTL Access Mask", HFILL }},
875                 { &hf_svcctl_scm_rights_connect,
876                   { "Connect", "svcctl.scm_rights_connect", FT_BOOLEAN, 32,
877                     TFS(&tfs_set_notset), 0x00000001, "SVCCTL Rights to connect to SCM", HFILL }},
878                 { &hf_svcctl_scm_rights_create_service,
879                   { "Create Service", "svcctl.scm_rights_create_service", FT_BOOLEAN, 32,
880                     TFS(&tfs_set_notset), 0x00000002, "SVCCTL Rights to create services", HFILL }},
881                 { &hf_svcctl_scm_rights_enumerate_service,
882                   { "Enumerate Service", "svcctl.scm_rights_enumerate_service", FT_BOOLEAN, 32,
883                     TFS(&tfs_set_notset), 0x00000004, "SVCCTL Rights to enumerate services", HFILL }},
884                 { &hf_svcctl_scm_rights_lock,
885                   { "Lock", "svcctl.scm_rights_lock", FT_BOOLEAN, 32,
886                     TFS(&tfs_set_notset), 0x00000008, "SVCCTL Rights to lock database", HFILL }},
887                 { &hf_svcctl_scm_rights_query_lock_status,
888                   { "Query Lock Status", "svcctl.scm_rights_query_lock_status", FT_BOOLEAN, 32,
889                     TFS(&tfs_set_notset), 0x00000010, "SVCCTL Rights to query database lock status", HFILL }},
890                 { &hf_svcctl_scm_rights_modify_boot_config,
891                   { "Modify Boot Config", "svcctl.scm_rights_modify_boot_config", FT_BOOLEAN, 32,
892                     TFS(&tfs_set_notset), 0x00000020, "SVCCTL Rights to modify boot config", HFILL }},
893                 { &hf_svcctl_hnd,
894                   { "Context Handle", "svcctl.hnd", FT_BYTES, BASE_NONE,
895                     NULL, 0x0, "SVCCTL Context handle", HFILL }},
896                 { &hf_svcctl_lock,
897                   { "Lock", "svcctl.lock", FT_BYTES, BASE_NONE,
898                     NULL, 0x0, "SVCCTL Database Lock", HFILL }},
899                 { &hf_svcctl_rc,
900                   { "Return code", "svcctl.rc", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
901                     &DOS_errors_ext, 0x0, "SVCCTL return code", HFILL }},
902                 { &hf_svcctl_size,
903                   { "Size", "svcctl.size", FT_UINT32, BASE_DEC,
904                     NULL, 0x0, "SVCCTL size of buffer", HFILL }},
905                 { &hf_svcctl_required_size,
906                   { "Required Size", "svcctl.required_size", FT_UINT32, BASE_DEC,
907                     NULL, 0x0, "SVCCTL required size of buffer for data to fit", HFILL }},
908                 { &hf_svcctl_is_locked,
909                   { "IsLocked", "svcctl.is_locked", FT_UINT32, BASE_DEC,
910                     NULL, 0x0, "SVCCTL whether the database is locked or not", HFILL }},
911                 { &hf_svcctl_lock_duration,
912                   { "Duration", "svcctl.lock_duration", FT_UINT32, BASE_DEC,
913                     NULL, 0x0, "SVCCTL number of seconds the database has been locked", HFILL }},
914                 { &hf_svcctl_lock_owner,
915                   { "Owner", "svcctl.lock_owner", FT_STRING, BASE_NONE,
916                     NULL, 0x0, "SVCCTL the user that holds the database lock", HFILL }},
917                 { &hf_svcctl_service_type,
918                   { "Service Type", "svcctl.service_type", FT_UINT32, BASE_HEX,
919                     NULL, 0x0, "SVCCTL type of service", HFILL }},
920                 { &hf_svcctl_service_type_kernel_driver,
921                   { "Kernel Driver Service", "svcctl.service_type.kernel", FT_BOOLEAN, 32,
922                     TFS(&tfs_svcctl_service_type_kernel_driver), SVCCTL_SERVICE_TYPE_KERNEL_DRIVER, "Request includes kernel driver services?", HFILL }},
923                 { &hf_svcctl_service_type_fs_driver,
924                   { "File System Driver Service", "svcctl.service_type.fs", FT_BOOLEAN, 32,
925                     TFS(&tfs_svcctl_service_type_fs_driver), SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER, "Request includes file system driver services?", HFILL }},
926                 { &hf_svcctl_service_type_win32_own_process,
927                   { "Self Process Service", "svcctl.service_type.win32_own", FT_BOOLEAN, 32,
928                     TFS(&tfs_svcctl_service_type_win32_own_process), SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS, "Request includes services that run their own process?", HFILL }},
929                 { &hf_svcctl_service_type_win32_share_process,
930                   { "Shared Process Service", "svcctl.service_type.win32_shared", FT_BOOLEAN, 32,
931                     TFS(&tfs_svcctl_service_type_win32_share_process), SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS, "Request includes services that share their process?", HFILL }},
932                 { &hf_svcctl_service_type_interactive_process,
933                   { "Interactive Process Service", "svcctl.service_type.interactive", FT_BOOLEAN, 32,
934                     TFS(&tfs_svcctl_service_type_interactive_process), SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS, "Request includes services that can interact with the desktop?", HFILL }},
935                 { &hf_svcctl_service_state,
936                   { "Service State", "svcctl.service_state", FT_UINT32, BASE_DEC,
937                     VALS(svcctl_service_status_vals), 0x0, "SVCCTL service state", HFILL }},
938                 { &hf_svcctl_buffer,
939                   { "Buffer", "svcctl.buffer", FT_UINT32, BASE_DEC,
940                     NULL, 0x0, "SVCCTL buffer", HFILL }},
941 #if 0
942                 { &hf_svcctl_bytes_needed,
943                   { "Bytes Needed", "svcctl.bytes_needed", FT_UINT32, BASE_DEC,
944                     NULL, 0x0, "SVCCTL bytes needed", HFILL }},
945                 { &hf_svcctl_services_returned,
946                   { "Services Returned", "svcctl.services_returned", FT_UINT32, BASE_DEC,
947                     NULL, 0x0, "SVCCTL services returned", HFILL }},
948 #endif
949                 { &hf_svcctl_service_name,
950                   { "Service Name", "svcctl.servicename", FT_STRING, BASE_NONE,
951                     NULL, 0x0, "SVCCTL name of service", HFILL }},
952                 { &hf_svcctl_display_name,
953                   { "Display Name", "svcctl.displayname", FT_STRING, BASE_NONE,
954                     NULL, 0x0, "SVCCTL display name", HFILL }},
955                 { &hf_svcctl_service_start_type,
956                   { "Service Start Type", "svcctl.service_start_type", FT_UINT32, BASE_DEC,
957                     VALS(svcctl_service_start_type_vals), 0x0, "SVCCTL service start type", HFILL }},
958                 { &hf_svcctl_service_error_control,
959                   { "Service Error Control", "svcctl.service_error_control", FT_UINT32, BASE_DEC,
960                     VALS(svcctl_service_error_control_vals), 0x0, "SVCCTL service error control", HFILL }},
961                 { &hf_svcctl_binarypathname,
962                   { "Binary Path Name", "svcctl.binarypathname", FT_STRING, BASE_NONE,
963                     NULL, 0x0, "SVCCTL binary path name", HFILL }},
964                 { &hf_svcctl_loadordergroup,
965                   { "Load Order Group", "svcctl.loadordergroup", FT_STRING, BASE_NONE,
966                     NULL, 0x0, "SVCCTL load order group", HFILL }},
967                 { &hf_svcctl_tagid,
968                   { "Tag Id", "svcctl.tagid", FT_UINT32, BASE_DEC,
969                     NULL, 0x0, "SVCCTL tag id", HFILL }},
970                 { &hf_svcctl_dependencies,
971                   { "Dependencies", "svcctl.dependencies", FT_STRING, BASE_NONE,
972                     NULL, 0x0, "SVCCTL dependencies", HFILL }},
973                 { &hf_svcctl_depend_size,
974                   { "Depend Size", "svcctl.depend_size", FT_UINT32, BASE_DEC,
975                     NULL, 0x0, "SVCCTL depend size", HFILL }},
976                 { &hf_svcctl_service_start_name,
977                   { "Service Start Name", "svcctl.service_start_name", FT_STRING, BASE_NONE,
978                     NULL, 0x0, "SVCCTL service start name", HFILL }},
979                 { &hf_svcctl_password,
980                   { "Password", "svcctl.password", FT_STRING, BASE_NONE,
981                     NULL, 0x0, "SVCCTL password", HFILL }},
982                 { &hf_svcctl_password_size,
983                   { "Password Size", "svcctl.password_size", FT_UINT32, BASE_DEC,
984                     NULL, 0x0, "SVCCTL password size", HFILL }},
985                 { &hf_svcctl_resume,
986                   { "Resume Handle", "svcctl.resume", FT_UINT32, BASE_DEC,
987                     NULL, 0x0, "SVCCTL resume handle", HFILL }},
988         };
989
990         static gint *ett[] = {
991                 &ett_dcerpc_svcctl,
992                 &ett_dcerpc_svcctl_service_type_bits,
993         };
994
995         proto_dcerpc_svcctl = proto_register_protocol(
996                 "Microsoft Service Control", "SVCCTL", "svcctl");
997
998         proto_register_field_array(proto_dcerpc_svcctl, hf, array_length(hf));
999         proto_register_subtree_array(ett, array_length(ett));
1000 }
1001
1002 void
1003 proto_reg_handoff_dcerpc_svcctl(void)
1004 {
1005         /* Register protocol as dcerpc */
1006
1007         dcerpc_init_uuid(proto_dcerpc_svcctl, ett_dcerpc_svcctl,
1008                          &uuid_dcerpc_svcctl, ver_dcerpc_svcctl,
1009                          dcerpc_svcctl_dissectors, hf_svcctl_opnum);
1010 }
1011
1012 /*
1013  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1014  *
1015  * Local variables:
1016  * c-basic-offset: 8
1017  * tab-width: 8
1018  * indent-tabs-mode: t
1019  * End:
1020  *
1021  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1022  * :indentSize=8:tabSize=8:noTabs=false:
1023  */