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