1# Copyright (c) 2003-2016 CORE Security Technologies
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# Author: Alberto Solino (@agsolino)
8#
9# Description:
10#   [MS-TSCH] ITaskSchedulerService Interface implementation
11#
12#   Best way to learn how to use these calls is to grab the protocol standard
13#   so you understand what the call does, and then read the test case located
14#   at https://github.com/CoreSecurity/impacket/tree/master/impacket/testcases/SMB_RPC
15#
16#   Some calls have helper functions, which makes it even easier to use.
17#   They are located at the end of this file.
18#   Helper functions start with "h"<name of the call>.
19#   There are test cases for them too.
20#
21from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray
22from impacket.dcerpc.v5.dtypes import DWORD, LPWSTR, ULONG, WSTR, NULL, GUID, PSYSTEMTIME, SYSTEMTIME
23from impacket.structure import Structure
24from impacket import hresult_errors, system_errors
25from impacket.uuid import uuidtup_to_bin
26from impacket.dcerpc.v5.rpcrt import DCERPCException
27
28MSRPC_UUID_TSCHS  = uuidtup_to_bin(('86D35949-83C9-4044-B424-DB363231FD0C','1.0'))
29
30class DCERPCSessionError(DCERPCException):
31    def __init__(self, error_string=None, error_code=None, packet=None):
32        DCERPCException.__init__(self, error_string, error_code, packet)
33
34    def __str__( self ):
35        key = self.error_code
36        if hresult_errors.ERROR_MESSAGES.has_key(key):
37            error_msg_short = hresult_errors.ERROR_MESSAGES[key][0]
38            error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1]
39            return 'TSCH SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
40        elif system_errors.ERROR_MESSAGES.has_key(key & 0xffff):
41            error_msg_short = system_errors.ERROR_MESSAGES[key & 0xffff][0]
42            error_msg_verbose = system_errors.ERROR_MESSAGES[key & 0xffff][1]
43            return 'TSCH SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
44        else:
45            return 'TSCH SessionError: unknown error code: 0x%x' % self.error_code
46
47################################################################################
48# CONSTANTS
49################################################################################
50# 2.3.1 Constant Values
51CNLEN = 15
52DNLEN = CNLEN
53UNLEN = 256
54MAX_BUFFER_SIZE = (DNLEN+UNLEN+1+1)
55
56# 2.3.7 Flags
57TASK_FLAG_INTERACTIVE                  = 0x1
58TASK_FLAG_DELETE_WHEN_DONE             = 0x2
59TASK_FLAG_DISABLED                     = 0x4
60TASK_FLAG_START_ONLY_IF_IDLE           = 0x10
61TASK_FLAG_KILL_ON_IDLE_END             = 0x20
62TASK_FLAG_DONT_START_IF_ON_BATTERIES   = 0x40
63TASK_FLAG_KILL_IF_GOING_ON_BATTERIES   = 0x80
64TASK_FLAG_RUN_ONLY_IF_DOCKED           = 0x100
65TASK_FLAG_HIDDEN                       = 0x200
66TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = 0x400
67TASK_FLAG_RESTART_ON_IDLE_RESUME       = 0x800
68TASK_FLAG_SYSTEM_REQUIRED              = 0x1000
69TASK_FLAG_RUN_ONLY_IF_LOGGED_ON        = 0x2000
70
71# 2.3.9 TASK_LOGON_TYPE
72TASK_LOGON_NONE                          = 0
73TASK_LOGON_PASSWORD                      = 1
74TASK_LOGON_S4U                           = 2
75TASK_LOGON_INTERACTIVE_TOKEN             = 3
76TASK_LOGON_GROUP                         = 4
77TASK_LOGON_SERVICE_ACCOUNT               = 5
78TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 6
79
80# 2.3.13 TASK_STATE
81TASK_STATE_UNKNOWN  = 0
82TASK_STATE_DISABLED = 1
83TASK_STATE_QUEUED   = 2
84TASK_STATE_READY    = 3
85TASK_STATE_RUNNING  = 4
86
87# 2.4.1 FIXDLEN_DATA
88SCHED_S_TASK_READY         = 0x00041300
89SCHED_S_TASK_RUNNING       = 0x00041301
90SCHED_S_TASK_NOT_SCHEDULED = 0x00041301
91
92# 2.4.2.11 Triggers
93TASK_TRIGGER_FLAG_HAS_END_DATE         = 0
94TASK_TRIGGER_FLAG_KILL_AT_DURATION_END = 0
95TASK_TRIGGER_FLAG_DISABLED             = 0
96
97# ToDo: Change this to enums
98ONCE                 = 0
99DAILY                = 1
100WEEKLY               = 2
101MONTHLYDATE          = 3
102MONTHLYDOW           = 4
103EVENT_ON_IDLE        = 5
104EVENT_AT_SYSTEMSTART = 6
105EVENT_AT_LOGON       = 7
106
107SUNDAY    = 0
108MONDAY    = 1
109TUESDAY   = 2
110WEDNESDAY = 3
111THURSDAY  = 4
112FRIDAY    = 5
113SATURDAY  = 6
114
115JANUARY   = 1
116FEBRUARY  = 2
117MARCH     = 3
118APRIL     = 4
119MAY       = 5
120JUNE      = 6
121JULY      = 7
122AUGUST    = 8
123SEPTEMBER = 9
124OCTOBER   = 10
125NOVEMBER  = 11
126DECEMBER  = 12
127
128# 2.4.2.11.8 MONTHLYDOW Trigger
129FIRST_WEEK  = 1
130SECOND_WEEK = 2
131THIRD_WEEK  = 3
132FOURTH_WEEK = 4
133LAST_WEEK   = 5
134
135# 2.3.12 TASK_NAMES
136TASK_NAMES = LPWSTR
137
138# 3.2.5.4.2 SchRpcRegisterTask (Opnum 1)
139TASK_VALIDATE_ONLY                = 1<<(31-31)
140TASK_CREATE                       = 1<<(31-30)
141TASK_UPDATE                       = 1<<(31-29)
142TASK_DISABLE                      = 1<<(31-28)
143TASK_DON_ADD_PRINCIPAL_ACE        = 1<<(31-27)
144TASK_IGNORE_REGISTRATION_TRIGGERS = 1<<(31-26)
145
146# 3.2.5.4.7 SchRpcEnumFolders (Opnum 6)
147TASK_ENUM_HIDDEN = 1
148
149# 3.2.5.4.13 SchRpcRun (Opnum 12)
150TASK_RUN_AS_SELF            = 1<<(31-31)
151TASK_RUN_IGNORE_CONSTRAINTS = 1<<(31-30)
152TASK_RUN_USE_SESSION_ID     = 1<<(31-29)
153TASK_RUN_USER_SID           = 1<<(31-28)
154
155class SYSTEMTIME_ARRAY(NDRUniConformantArray):
156    item = SYSTEMTIME
157
158class PSYSTEMTIME_ARRAY(NDRPOINTER):
159    referent = (
160        ('Data',SYSTEMTIME_ARRAY),
161    )
162
163# 3.2.5.4.18 SchRpcGetTaskInfo (Opnum 17)
164SCH_FLAG_STATE            = 1<<(31-3)
165
166################################################################################
167# STRUCTURES
168################################################################################
169# 2.3.12 TASK_NAMES
170class TASK_NAMES_ARRAY(NDRUniConformantArray):
171    item = TASK_NAMES
172
173class PTASK_NAMES_ARRAY(NDRPOINTER):
174    referent = (
175        ('Data',TASK_NAMES_ARRAY),
176    )
177
178class WSTR_ARRAY(NDRUniConformantArray):
179    item = WSTR
180
181class PWSTR_ARRAY(NDRPOINTER):
182    referent = (
183        ('Data',WSTR_ARRAY),
184    )
185
186class GUID_ARRAY(NDRUniConformantArray):
187    item = GUID
188
189class PGUID_ARRAY(NDRPOINTER):
190    referent = (
191        ('Data',TASK_NAMES_ARRAY),
192    )
193
194# 3.2.5.4.13 SchRpcRun (Opnum 12)
195class SYSTEMTIME_ARRAY(NDRUniConformantArray):
196    item = SYSTEMTIME
197
198class PSYSTEMTIME_ARRAY(NDRPOINTER):
199    referent = (
200        ('Data',SYSTEMTIME_ARRAY),
201    )
202
203# 2.3.8 TASK_USER_CRED
204class TASK_USER_CRED(NDRSTRUCT):
205    structure =  (
206        ('userId',LPWSTR),
207        ('password',LPWSTR),
208        ('flags',DWORD),
209    )
210
211class TASK_USER_CRED_ARRAY(NDRUniConformantArray):
212    item = TASK_USER_CRED
213
214class LPTASK_USER_CRED_ARRAY(NDRPOINTER):
215    referent = (
216        ('Data',TASK_USER_CRED_ARRAY),
217    )
218
219# 2.3.10 TASK_XML_ERROR_INFO
220class TASK_XML_ERROR_INFO(NDRSTRUCT):
221    structure =  (
222        ('line',DWORD),
223        ('column',DWORD),
224        ('node',LPWSTR),
225        ('value',LPWSTR),
226    )
227
228class PTASK_XML_ERROR_INFO(NDRPOINTER):
229    referent = (
230        ('Data',TASK_XML_ERROR_INFO),
231    )
232
233# 2.4.1 FIXDLEN_DATA
234class FIXDLEN_DATA(Structure):
235    structure = (
236        ('Product Version','<H=0'),
237        ('File Version','<H=0'),
238        ('Job uuid','16s="'),
239        ('App Name Len Offset','<H=0'),
240        ('Trigger Offset','<H=0'),
241        ('Error Retry Count','<H=0'),
242        ('Error Retry Interval','<H=0'),
243        ('Idle Deadline','<H=0'),
244        ('Idle Wait','<H=0'),
245        ('Priority','<L=0'),
246        ('Maximum Run Time','<L=0'),
247        ('Exit Code','<L=0'),
248        ('Status','<L=0'),
249        ('Flags','<L=0'),
250    )
251
252# 2.4.2.11 Triggers
253class FIXDLEN_DATA(Structure):
254    structure = (
255        ('Trigger Size','<H=0'),
256        ('Reserved1','<H=0'),
257        ('Begin Year','<H=0'),
258        ('Begin Month','<H=0'),
259        ('Begin Day','<H=0'),
260        ('End Year','<H=0'),
261        ('End Month','<H=0'),
262        ('End Day','<H=0'),
263        ('Start Hour','<H=0'),
264        ('Start Minute','<H=0'),
265        ('Minutes Duration','<L=0'),
266        ('Minutes Interval','<L=0'),
267        ('Flags','<L=0'),
268        ('Trigger Type','<L=0'),
269        ('TriggerSpecific0','<H=0'),
270        ('TriggerSpecific1','<H=0'),
271        ('TriggerSpecific2','<H=0'),
272        ('Padding','<H=0'),
273        ('Reserved2','<H=0'),
274        ('Reserved3','<H=0'),
275    )
276
277# 2.4.2.11.6 WEEKLY Trigger
278class WEEKLY(Structure):
279    structure = (
280        ('Trigger Type','<L=0'),
281        ('Weeks Interval','<H=0'),
282        ('DaysOfTheWeek','<H=0'),
283        ('Unused','<H=0'),
284        ('Padding','<H=0'),
285    )
286
287# 2.4.2.11.7 MONTHLYDATE Trigger
288class MONTHLYDATE(Structure):
289    structure = (
290        ('Trigger Type','<L=0'),
291        ('Days','<L=0'),
292        ('Months','<H=0'),
293        ('Padding','<H=0'),
294    )
295
296# 2.4.2.11.8 MONTHLYDOW Trigger
297class MONTHLYDOW(Structure):
298    structure = (
299        ('Trigger Type','<L=0'),
300        ('WhichWeek','<H=0'),
301        ('DaysOfTheWeek','<H=0'),
302        ('Months','<H=0'),
303        ('Padding','<H=0'),
304        ('Reserved2','<H=0'),
305        ('Reserved3','<H=0'),
306    )
307
308# 2.4.2.12 Job Signature
309class JOB_SIGNATURE(Structure):
310    structure = (
311        ('SignatureVersion','<HH0'),
312        ('MinClientVersion','<H=0'),
313        ('Signature','64s="'),
314    )
315
316################################################################################
317# RPC CALLS
318################################################################################
319# 3.2.5.4.1 SchRpcHighestVersion (Opnum 0)
320class SchRpcHighestVersion(NDRCALL):
321    opnum = 0
322    structure = (
323    )
324
325class SchRpcHighestVersionResponse(NDRCALL):
326    structure = (
327        ('pVersion', DWORD),
328        ('ErrorCode',ULONG),
329    )
330
331# 3.2.5.4.2 SchRpcRegisterTask (Opnum 1)
332class SchRpcRegisterTask(NDRCALL):
333    opnum = 1
334    structure = (
335        ('path', LPWSTR),
336        ('xml', WSTR),
337        ('flags', DWORD),
338        ('sddl', LPWSTR),
339        ('logonType', DWORD),
340        ('cCreds', DWORD),
341        ('pCreds', LPTASK_USER_CRED_ARRAY),
342    )
343
344class SchRpcRegisterTaskResponse(NDRCALL):
345    structure = (
346        ('pActualPath', LPWSTR),
347        ('pErrorInfo', PTASK_XML_ERROR_INFO),
348        ('ErrorCode',ULONG),
349    )
350
351# 3.2.5.4.3 SchRpcRetrieveTask (Opnum 2)
352class SchRpcRetrieveTask(NDRCALL):
353    opnum = 2
354    structure = (
355        ('path', WSTR),
356        ('lpcwszLanguagesBuffer', WSTR),
357        ('pulNumLanguages', DWORD),
358    )
359
360class SchRpcRetrieveTaskResponse(NDRCALL):
361    structure = (
362        ('pXml', LPWSTR),
363        ('ErrorCode',ULONG),
364    )
365
366# 3.2.5.4.4 SchRpcCreateFolder (Opnum 3)
367class SchRpcCreateFolder(NDRCALL):
368    opnum = 3
369    structure = (
370        ('path', WSTR),
371        ('sddl', LPWSTR),
372        ('flags', DWORD),
373    )
374
375class SchRpcCreateFolderResponse(NDRCALL):
376    structure = (
377        ('ErrorCode',ULONG),
378    )
379
380# 3.2.5.4.7 SchRpcEnumFolders (Opnum 6)
381class SchRpcEnumFolders(NDRCALL):
382    opnum = 6
383    structure = (
384        ('path', WSTR),
385        ('flags', DWORD),
386        ('startIndex', DWORD),
387        ('cRequested', DWORD),
388    )
389
390class SchRpcEnumFoldersResponse(NDRCALL):
391    structure = (
392        ('startIndex', DWORD),
393        ('pcNames', DWORD),
394        ('pNames', PTASK_NAMES_ARRAY),
395        ('ErrorCode',ULONG),
396    )
397
398# 3.2.5.4.8 SchRpcEnumTasks (Opnum 7)
399class SchRpcEnumTasks(NDRCALL):
400    opnum = 7
401    structure = (
402        ('path', WSTR),
403        ('flags', DWORD),
404        ('startIndex', DWORD),
405        ('cRequested', DWORD),
406    )
407
408class SchRpcEnumTasksResponse(NDRCALL):
409    structure = (
410        ('startIndex', DWORD),
411        ('pcNames', DWORD),
412        ('pNames', PTASK_NAMES_ARRAY),
413        ('ErrorCode',ULONG),
414    )
415
416# 3.2.5.4.9 SchRpcEnumInstances (Opnum 8)
417class SchRpcEnumInstances(NDRCALL):
418    opnum = 8
419    structure = (
420        ('path', LPWSTR),
421        ('flags', DWORD),
422    )
423
424class SchRpcEnumInstancesResponse(NDRCALL):
425    structure = (
426        ('pcGuids', DWORD),
427        ('pGuids', PGUID_ARRAY),
428        ('ErrorCode',ULONG),
429    )
430
431# 3.2.5.4.10 SchRpcGetInstanceInfo (Opnum 9)
432class SchRpcGetInstanceInfo(NDRCALL):
433    opnum = 9
434    structure = (
435        ('guid', GUID),
436    )
437
438class SchRpcGetInstanceInfoResponse(NDRCALL):
439    structure = (
440        ('pPath', LPWSTR),
441        ('pState', DWORD),
442        ('pCurrentAction', LPWSTR),
443        ('pInfo', LPWSTR),
444        ('pcGroupInstances', DWORD),
445        ('pGroupInstances', PGUID_ARRAY),
446        ('pEnginePID', DWORD),
447        ('ErrorCode',ULONG),
448    )
449
450# 3.2.5.4.11 SchRpcStopInstance (Opnum 10)
451class SchRpcStopInstance(NDRCALL):
452    opnum = 10
453    structure = (
454        ('guid', GUID),
455        ('flags', DWORD),
456    )
457
458class SchRpcStopInstanceResponse(NDRCALL):
459    structure = (
460        ('ErrorCode',ULONG),
461    )
462
463# 3.2.5.4.12 SchRpcStop (Opnum 11)
464class SchRpcStop(NDRCALL):
465    opnum = 11
466    structure = (
467        ('path', LPWSTR),
468        ('flags', DWORD),
469    )
470
471class SchRpcStopResponse(NDRCALL):
472    structure = (
473        ('ErrorCode',ULONG),
474    )
475
476# 3.2.5.4.13 SchRpcRun (Opnum 12)
477class SchRpcRun(NDRCALL):
478    opnum = 12
479    structure = (
480        ('path', WSTR),
481        ('cArgs', DWORD),
482        ('pArgs', PWSTR_ARRAY),
483        ('flags', DWORD),
484        ('sessionId', DWORD),
485        ('user', LPWSTR),
486    )
487
488class SchRpcRunResponse(NDRCALL):
489    structure = (
490        ('pGuid', GUID),
491        ('ErrorCode',ULONG),
492    )
493
494# 3.2.5.4.14 SchRpcDelete (Opnum 13)
495class SchRpcDelete(NDRCALL):
496    opnum = 13
497    structure = (
498        ('path', WSTR),
499        ('flags', DWORD),
500    )
501
502class SchRpcDeleteResponse(NDRCALL):
503    structure = (
504        ('ErrorCode',ULONG),
505    )
506
507# 3.2.5.4.15 SchRpcRename (Opnum 14)
508class SchRpcRename(NDRCALL):
509    opnum = 14
510    structure = (
511        ('path', WSTR),
512        ('newName', WSTR),
513        ('flags', DWORD),
514    )
515
516class SchRpcRenameResponse(NDRCALL):
517    structure = (
518        ('ErrorCode',ULONG),
519    )
520
521# 3.2.5.4.16 SchRpcScheduledRuntimes (Opnum 15)
522class SchRpcScheduledRuntimes(NDRCALL):
523    opnum = 15
524    structure = (
525        ('path', WSTR),
526        ('start', PSYSTEMTIME),
527        ('end', PSYSTEMTIME),
528        ('flags', DWORD),
529        ('cRequested', DWORD),
530    )
531
532class SchRpcScheduledRuntimesResponse(NDRCALL):
533    structure = (
534        ('pcRuntimes',DWORD),
535        ('pRuntimes',PSYSTEMTIME_ARRAY),
536        ('ErrorCode',ULONG),
537    )
538
539# 3.2.5.4.17 SchRpcGetLastRunInfo (Opnum 16)
540class SchRpcGetLastRunInfo(NDRCALL):
541    opnum = 16
542    structure = (
543        ('path', WSTR),
544    )
545
546class SchRpcGetLastRunInfoResponse(NDRCALL):
547    structure = (
548        ('pLastRuntime',SYSTEMTIME),
549        ('pLastReturnCode',DWORD),
550        ('ErrorCode',ULONG),
551    )
552
553# 3.2.5.4.18 SchRpcGetTaskInfo (Opnum 17)
554class SchRpcGetTaskInfo(NDRCALL):
555    opnum = 17
556    structure = (
557        ('path', WSTR),
558        ('flags', DWORD),
559    )
560
561class SchRpcGetTaskInfoResponse(NDRCALL):
562    structure = (
563        ('pEnabled',DWORD),
564        ('pState',DWORD),
565        ('ErrorCode',ULONG),
566    )
567
568# 3.2.5.4.19 SchRpcGetNumberOfMissedRuns (Opnum 18)
569class SchRpcGetNumberOfMissedRuns(NDRCALL):
570    opnum = 18
571    structure = (
572        ('path', WSTR),
573    )
574
575class SchRpcGetNumberOfMissedRunsResponse(NDRCALL):
576    structure = (
577        ('pNumberOfMissedRuns',DWORD),
578        ('ErrorCode',ULONG),
579    )
580
581# 3.2.5.4.20 SchRpcEnableTask (Opnum 19)
582class SchRpcEnableTask(NDRCALL):
583    opnum = 19
584    structure = (
585        ('path', WSTR),
586        ('enabled', DWORD),
587    )
588
589class SchRpcEnableTaskResponse(NDRCALL):
590    structure = (
591        ('ErrorCode',ULONG),
592    )
593
594################################################################################
595# OPNUMs and their corresponding structures
596################################################################################
597OPNUMS = {
598 0 : (SchRpcHighestVersion,SchRpcHighestVersionResponse ),
599 1 : (SchRpcRegisterTask,SchRpcRegisterTaskResponse ),
600 2 : (SchRpcRetrieveTask,SchRpcRetrieveTaskResponse ),
601 3 : (SchRpcCreateFolder,SchRpcCreateFolderResponse ),
602 6 : (SchRpcEnumFolders,SchRpcEnumFoldersResponse ),
603 7 : (SchRpcEnumTasks,SchRpcEnumTasksResponse ),
604 8 : (SchRpcEnumInstances,SchRpcEnumInstancesResponse ),
605 9 : (SchRpcGetInstanceInfo,SchRpcGetInstanceInfoResponse ),
606 10 : (SchRpcStopInstance,SchRpcStopInstanceResponse ),
607 11 : (SchRpcStop,SchRpcStopResponse ),
608 12 : (SchRpcRun,SchRpcRunResponse ),
609 13 : (SchRpcDelete,SchRpcDeleteResponse ),
610 14 : (SchRpcRename,SchRpcRenameResponse ),
611 15 : (SchRpcScheduledRuntimes,SchRpcScheduledRuntimesResponse ),
612 16 : (SchRpcGetLastRunInfo,SchRpcGetLastRunInfoResponse ),
613 17 : (SchRpcGetTaskInfo,SchRpcGetTaskInfoResponse ),
614 18 : (SchRpcGetNumberOfMissedRuns,SchRpcGetNumberOfMissedRunsResponse),
615}
616
617################################################################################
618# HELPER FUNCTIONS
619################################################################################
620def checkNullString(string):
621    if string == NULL:
622        return string
623
624    if string[-1:] != '\x00':
625        return string + '\x00'
626    else:
627        return string
628
629def hSchRpcHighestVersion(dce):
630    return dce.request(SchRpcHighestVersion())
631
632def hSchRpcRegisterTask(dce, path, xml, flags, sddl, logonType, pCreds = ()):
633    request = SchRpcRegisterTask()
634    request['path'] = checkNullString(path)
635    request['xml'] = checkNullString(xml)
636    request['flags'] = flags
637    request['sddl'] = sddl
638    request['logonType'] = logonType
639    request['cCreds'] = len(pCreds)
640    if len(pCreds) == 0:
641        request['pCreds'] = NULL
642    else:
643        for cred in pCreds:
644            request['pCreds'].append(cred)
645    return dce.request(request)
646
647def hSchRpcRetrieveTask(dce, path, lpcwszLanguagesBuffer = '\x00', pulNumLanguages=0 ):
648    schRpcRetrieveTask = SchRpcRetrieveTask()
649    schRpcRetrieveTask['path'] = checkNullString(path)
650    schRpcRetrieveTask['lpcwszLanguagesBuffer'] = lpcwszLanguagesBuffer
651    schRpcRetrieveTask['pulNumLanguages'] = pulNumLanguages
652    return dce.request(schRpcRetrieveTask)
653
654def hSchRpcCreateFolder(dce, path, sddl = NULL):
655    schRpcCreateFolder = SchRpcCreateFolder()
656    schRpcCreateFolder['path'] = checkNullString(path)
657    schRpcCreateFolder['sddl'] = sddl
658    schRpcCreateFolder['flags'] = 0
659    return dce.request(schRpcCreateFolder)
660
661def hSchRpcEnumFolders(dce, path, flags=TASK_ENUM_HIDDEN, startIndex=0, cRequested=0xffffffff):
662    schRpcEnumFolders = SchRpcEnumFolders()
663    schRpcEnumFolders['path'] = checkNullString(path)
664    schRpcEnumFolders['flags'] = flags
665    schRpcEnumFolders['startIndex'] = startIndex
666    schRpcEnumFolders['cRequested'] = cRequested
667    return dce.request(schRpcEnumFolders)
668
669def hSchRpcEnumTasks(dce, path, flags=TASK_ENUM_HIDDEN, startIndex=0, cRequested=0xffffffff):
670    schRpcEnumTasks = SchRpcEnumTasks()
671    schRpcEnumTasks['path'] = checkNullString(path)
672    schRpcEnumTasks['flags'] = flags
673    schRpcEnumTasks['startIndex'] = startIndex
674    schRpcEnumTasks['cRequested'] = cRequested
675    return dce.request(schRpcEnumTasks)
676
677def hSchRpcEnumInstances(dce, path, flags=TASK_ENUM_HIDDEN):
678    schRpcEnumInstances = SchRpcEnumInstances()
679    schRpcEnumInstances['path'] = checkNullString(path)
680    schRpcEnumInstances['flags'] = flags
681    return dce.request(schRpcEnumInstances)
682
683def hSchRpcGetInstanceInfo(dce, guid):
684    schRpcGetInstanceInfo = SchRpcGetInstanceInfo()
685    schRpcGetInstanceInfo['guid'] = guid
686    return dce.request(schRpcGetInstanceInfo)
687
688def hSchRpcStopInstance(dce, guid, flags = 0):
689    schRpcStopInstance = SchRpcStopInstance()
690    schRpcStopInstance['guid'] = guid
691    schRpcStopInstance['flags'] = flags
692    return dce.request(schRpcStopInstance)
693
694def hSchRpcStop(dce, path, flags = 0):
695    schRpcStop= SchRpcStop()
696    schRpcStop['path'] = path
697    schRpcStop['flags'] = flags
698    return dce.request(schRpcStop)
699
700def hSchRpcRun(dce, path, pArgs=(), flags=0, sessionId=0, user = NULL):
701    schRpcRun = SchRpcRun()
702    schRpcRun['path'] = checkNullString(path)
703    schRpcRun['cArgs'] = len(pArgs)
704    for arg in pArgs:
705        argn = LPWSTR()
706        argn['Data'] = checkNullString(arg)
707        schRpcRun['pArgs'].append(argn)
708    schRpcRun['flags'] = flags
709    schRpcRun['sessionId'] = sessionId
710    schRpcRun['user'] = user
711    return dce.request(schRpcRun)
712
713def hSchRpcDelete(dce, path, flags = 0):
714    schRpcDelete = SchRpcDelete()
715    schRpcDelete['path'] = checkNullString(path)
716    schRpcDelete['flags'] = flags
717    return dce.request(schRpcDelete)
718
719def hSchRpcRename(dce, path, newName, flags = 0):
720    schRpcRename = SchRpcRename()
721    schRpcRename['path'] = checkNullString(path)
722    schRpcRename['newName'] = checkNullString(newName)
723    schRpcRename['flags'] = flags
724    return dce.request(schRpcRename)
725
726def hSchRpcScheduledRuntimes(dce, path, start = NULL, end = NULL, flags = 0, cRequested = 10):
727    schRpcScheduledRuntimes = SchRpcScheduledRuntimes()
728    schRpcScheduledRuntimes['path'] = checkNullString(path)
729    schRpcScheduledRuntimes['start'] = start
730    schRpcScheduledRuntimes['end'] = end
731    schRpcScheduledRuntimes['flags'] = flags
732    schRpcScheduledRuntimes['cRequested'] = cRequested
733    return dce.request(schRpcScheduledRuntimes)
734
735def hSchRpcGetLastRunInfo(dce, path):
736    schRpcGetLastRunInfo = SchRpcGetLastRunInfo()
737    schRpcGetLastRunInfo['path'] = checkNullString(path)
738    return dce.request(schRpcGetLastRunInfo)
739
740def hSchRpcGetTaskInfo(dce, path, flags = 0):
741    schRpcGetTaskInfo = SchRpcGetTaskInfo()
742    schRpcGetTaskInfo['path'] = checkNullString(path)
743    schRpcGetTaskInfo['flags'] = flags
744    return dce.request(schRpcGetTaskInfo)
745
746def hSchRpcGetNumberOfMissedRuns(dce, path):
747    schRpcGetNumberOfMissedRuns = SchRpcGetNumberOfMissedRuns()
748    schRpcGetNumberOfMissedRuns['path'] = checkNullString(path)
749    return dce.request(schRpcGetNumberOfMissedRuns)
750
751def hSchRpcEnableTask(dce, path, enabled = True):
752    schRpcEnableTask = SchRpcEnableTask()
753    schRpcEnableTask['path'] = checkNullString(path)
754    if enabled is True:
755        schRpcEnableTask['enabled'] = 1
756    else:
757        schRpcEnableTask['enabled'] = 0
758    return dce.request(schRpcEnableTask)