再聊Windows的访问控制(Access Control)(五) SDDL

        上一篇我们提到,安全描述符可通过ConvertSecurityDescriptorToStringSecurityDescriptor()和ConvertStringSecurityDescriptorToSecurityDescriptor()两个函数在二进制和字符串两种形式间转换,我们很自然地会想到,要实现这种转换,需要为字符串形式的安全描述符定义严格的语法规则,用来精确无误地描述安全描述符各个部分的格式,这就是安全描述符定义语言SDDL(Security Descriptor Definition Language)所扮演的角色。

        用SDDL定义的安全描述符是一个以空字符(null)结尾的字符串,具有复杂的语法规则,细节附在文后,现重点介绍其主要框架。

        回忆前面文章中描述的安全描述符结构,其中有四个主要部分,在SDDL中分别用四个字符标记来表示如下:

  • O:owner_sid
  • G:group_sid
  • D:dacl_flags(string_ace1)(string_ace2)...(string_acen)
  • S:sacl_flags(string_ace1)(string_ace2)...(string_acen)

        "O:"表示对象的所有者,"G:"表示对象所有者所属的主组,“D:"表示DACL,"S:"表示SACL。

        owner_sid是一个标识对象所有者的SID字符串,group_sid是标识对象所有者所属主组的SID字符串,代表各类SID的具体字符串清单附在文后。dacl_flags是应用于DACL的安全描述符控制标志,可以是以下字符串标记的组合:

控制标志的字符形式

在sddl.h中的定义

说明

"P"

SDDL_PROTECTED

设置了SE_DACL_PROTECTED标志

"AR"

SDDL_AUTO_INHERIT_REQ

设置了SE_DACL_AUTO_INHERIT_REQ标志

"AI"

SDDL_AUTO_INHERITED

设置了SE_DACL_AUTO_INHERIT标志

"NO_ACCESS_CONTROL"

SDDL_NULL_ACL

ACL为空。(Windows Server 2008,Windows Vista,Windows Server 2003本标志无效)

sacl_flags是应用于SACL的安全描述符控制标志,使用与DACL相同的控制字符串。string_ace是描述ACE的字符串,ACE字符串必须放在圆括号中。

        对于安全描述符中的各种控制位,SDDL采用不同的方式处理。SE_DACL_PRESENT和SE_SACL_PRESENT分别标识安全描述符中存在DACL和SACL,在字符串形式中体现为存在"D:"和"S:"标记,即只要这两个标记存在,就表示SE_DACL_PRESENT和SE_SACL_PRESENT被设置了。

        SE_OWNER_DEFAULTED、SE_GROUP_DEFAULTED、SE_DACL_DEFAULTED和SE_SACL_DEFAULTED不在字符串形式中出现。

        SE_SELF_RELATIVE位也不在字符串形式中出现,但调用ConvertStringSecurityDescriptorToSecurityDescriptor()从字符串形式转换到二进制形式时,该标志是被设置的。

        其他的控制标志在dacl_flags或sacl_flags字段中体现。

        在调用ConvertSecurityDescriptorToStringSecurityDescriptor()将安全描述符由二进制形式转换成字符串形式时,不存在的组件不会在字符串形式中出现,比如如果没有设置SE_DACL_PRESENT标志,字符串中不会有"D:"部分。也可以通过入口参数SECURITY_INFORMATION设置相应的标志值来指定要包含在输出字符串中的成分。

        如果字符串中包含"D:"或"S:",但后面不跟任何信息,就表示这是一个空的ACL。

  • ACE字符串

        在字符串形式的安全描述符中,每个代表ACE的串都要放在圆括号中。每个ACE字符串都遵循以下格式,每字段间用分号(;)隔离:

ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)

        act_type为ACE_HEADER中AceType成员的每个取值都赋予了一个简短的字符串标识,用来说明该ACE的类型,这些定义都在sddl.h中。

ACE 类型串

sddl.h中对应常量

AceType 值(见ACE_HEADER文档)

”A“

SDDL_ACCESS_ALLOWED

ACCESS_ALLOWED_ACE_TYPE

"D"

SDDL_ACCESS_DENIED

ACCESS_DENIED_ACE_TYPE

"OA"

SDDL_OBJECT_ACCESS_ALLOWED

ACCESS_ALLOWED_OBJECT_ACE_TYPE

"OD"

SDDL_OBJECT_ACCESS_DENIED

ACCESS_DENIED_OBJECT_ACE_TYPE

"AU"

SDDL_AUDIT

SYSTEM_AUDIT_ACE_TYPE

"AL"

SDDL_ALARM

SYSTEM_ALARM_ACE_TYPE

"OU"

SDDL_OBJECT_AUDIT

SYSTEM_AUDIT_OBJECT_ACE_TYPE

"OL"

SDDL_OBJECT_ALARM

SYSTEM_ALARM_OBJECT_ACE_TYPE

"ML"

SDDL_MANDATORY_LABEL

SYSTEM_MANDATORY_LABEL_ACE_TYPE Windows Server 2003中无效

"XA"

SDDL_CALLBACK_ACCESS_ALLOWED

ACCESS_ALLOWED_CALLBACK_ACE_TYPE Windows Server 2008, Windows Vista and Windows Server 2003中无效

"XD"

SDDL_CALLBACK_ACCESS_DENIED

ACCESS_DENIED_CALLBACK_ACE_TYPE Windows Server 2008, Windows Vista and Windows Server 2003中无效

"RA"

SDDL_RESOURCE_ATTRIBUTE

SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

"SP"

SDDL_SCOPED_POLICY_ID

SYSTEM_SCOPED_POLICY_ID_ACE_TYPE Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

"XU"

SDDL_CALLBACK_AUDIT

SYSTEM_AUDIT_CALLBACK_ACE_TYPE Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

"ZA"

SDDL_CALLBACK_OBJECT_ACCESS_ALLOWED

ACCESS_ALLOWED_CALLBACK_ACE_TYPE Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

"TL"

SDDL_PROCESS_TRUST_LABEL

SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

"FL"

SDDL_ACCESS_FILTER

SYSTEM_ACCESS_FILTER_ACE_TYPE
Windows Server 2016, Windows 10 Version 1607, Windows 10 Version 1511, Windows 10 Version 1507, Windows Server 2012 R2, Windows 8.1, Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003
中无效

        ace_flags字段为ACE_HEADER中AceFlags成员的每个取值都赋予了一个简短的字符串标识,用来在ACE字符串中说明该ACE的工作机制,这些定义也都在sddl.h中。

ACE标志串

sddl.h中对应常量

ACE标志值

"CI"

SDDL_CONTAINER_INHERIT

CONTAINER_INHERIT_ACE

"OI"

SDDL_OBJECT_INHERIT

OBJECT_INHERIT_ACE

"NP"

SDDL_NO_PROPAGATE

NO_PROPAGATE_INHERIT_ACE

"IO"

SDDL_INHERIT_ONLY

INHERIT_ONLY_ACE

"ID"

SDDL_INHERITED    INHERITED_ACE

INHERITED_ACE

"SA"

SDDL_AUDIT_SUCCESS

SUCCESSFUL_ACCESS_ACE_FLAG

"FA"

SDDL_AUDIT_FAILURE

FAILED_ACCESS_ACE_FLAG

"TP"

SDDL_TRUST_PROTECTED_FILTER

TRUST_PROTECTED_FILTER_ACE_FLAG

Windows Server 2016, Windows 10 Version 1607, Windows 10 Version 1511, Windows 10 Version 1507, Windows Server 2012 R2, Windows 8.1, Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效。

"CR"

SDDL_CRITICAL

CRITICAL_ACE_FLAG Windows Server Version 1803, Windows 10 Version 1803, Windows Server Version 1709, Windows 10 Version 1709, Windows 10 Version 1703, Windows Server 2016, Windows 10 Version 1607, Windows 10 Version 1511, Windows 10 Version 1507, Windows Server 2012 R2, Windows 8.1, Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003中无效

        ACE_HEADER中AceType和AceFlags的取值都可以在ACE_HEADDER文档(ACE_HEADER (winnt.h) - Win32 apps | Microsoft Learn)中查询到。

        rights字段是ACE控制的权限的字符串表示,它既可以用权限位的十六进制字符串表示,如"0x7800003F",也可以用下面各表中的字符串。

通用访问权限

权限字符串

sddl.h中对应常量

权限值

"GA"

SDDL_GENERIC_ALL    GENERIC

ALL

"GR"

SDDL_GENERIC_READ

GENERIC_READ

"GW"

SDDL_GENERIC_WRITE

GENERIC_WRITE

"GX"

SDDL_GENERIC_EXECUTE

GENERIC_EXECUTE

标准访问权限

权限字符串

sddl.h中对应常量

权限值

"RC"

SDDL_READ_CONTROL

READ_CONTROL

"SD"

SDDL_STANDARD_DELETE

DELETE

"WD"

SDDL_WRITE_DAC

WRITE_DAC

"WO"

SDDL_WRITE_OWNER

WRITE_OWNER

目录服务对象访问权限

权限字符串

sddl.h中对应常量

权限值

"RP"

SDDL_READ_PROPERTY

ADS_RIGHT_DS_READ_PROP

"WP"

SDDL_WRITE_PROPERTY

ADS_RIGHT_DS_WRITE_PROP

"CC"

SDDL_CREATE_CHILD

ADS_RIGHT_DS_CREATE_CHILD

"DC"

SDDL_DELETE_CHILD

ADS_RIGHT_DS_DELETE_CHILD

"LC"

SDDL_LIST_CHILDREN

ADS_RIGHT_ACTRL_DS_LIST

"SW"

SDDL_SELF_WRITE

DS_SELF

"LO"

SDDL_LIST_OBJECT

DS_LIST_OBJECT

"DT"

SDDL_DELETE_TREE

DS_DELETE_TREE

"CR"

SDDL_CONTROL_ACCESS

ADS_RIGHT_DS_CONTROL_ACCESS

文件访问权限

权限字符串

Sddl.h中对应常量

权限值

“FA”

SDDL_FILE_ALL

FILE_GENERIC_ALL

“FR”

SDDL_FILE_READ

FILE_GENERIC_READ

“FW”

SDDL_FILE_WRITE

FILE_GENERIC_WRITE

“FX”

SDDL_FILE_EXECUTE

FILE_GENERIC_EXECUTE

注册表访问权限

权限字符串

sddl.h中对应常量

权限值

"KA"

SDDL_KEY_ALL

KEY_ALL_ACCESS

"KR"

SDDL_KEY_READ

KEY_READ

"KW"

SDDL_KEY_WRITE

KEY_WRITE

"KX"

SDDL_KEY_EXECUTE    

    KEY_EXECUTE

MIC(Mandatory Integrity Control)访问权限

权限字符串

sddl.h中对应常量

权限值

"NR"

SDDL_NO_READ

    SYSTEM_MANDATORY_LABEL_NO_READ_UP

Windows Server 2008, Windows Vista and Windows Server 2003:中无效

"NW"

SDDL_NO_WRITE_UP

SYSTEM_MANDATORY_LABEL_NO_WRITE_UP Windows Server 2008, Windows Vista and Windows Server 2003:中无效

"NX"

SDDL_NO_EXECUTE_UP

SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP

Windows Server 2008, Windows Vista and Windows Server 2003:中无效

        object_guid字段是对象特定ACE中的ObjectType成员指定的GUID的字符串表示,可用UuidtoString()函数生成该字符串。下面是两个常用的GUID:

权限和GUID

权限

CR;ab721a53-1e2f-11d0-9819-00aa0040529b

更改密码

CR;00299570-246d-11d0-a768-00aa006e0529

重设密码

        inherit_object_guid字段是对象特定ACE中的InheritObjectType成员的GUID的字符串表示,该字符串可由UuidToString()生成。

        account_sid字段是ACE针对的受信任实体的SID字符串。
        最后一个字段是resource_attribute,专用于资源ACE,是可选的。资源ACE是一种新型的ACE,在Windows 7之前的Windows客户端版本和Windows Server 2008 R2之前的Windows服务器版本之前是没有资源ACE的。资源ACE可为对象指定附加的属性,以条件ACE的形式指定访问或审核策略。在下面的条件ACE部分再做一下简单介绍。

    现在我们看一下ACE的实例:

(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-1-0)

该ACE可分解成下面的ACE信息:

AceType : 0x00(ACCESS_ALLOWED_ACE_TYPE)

AceFlags: 0x00

Access Mask:0x100e003f

    READ_CONTROL

    WRITE_DAC

    WRITE_OWNER

    GENERIC_ALL

    Other access rights(0x0000003f)

Ace Sid : (S-1-1-0)

再看一个安全描述符的实例:

“O:AOG:DAD(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)”

该字符串描述了一下安全描述符:

    Revision: 0x00000001

    Control : 0x0004

       SE_DACL_PRESENT

    Owner: (S-1-5-32-548)

    PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512)

DACL

    Revision: 0x02

    Size: 0x001c

    AceCount:0x0001

    Ace[00]

       AceType: 0x00(ACCESS_ALLOWED_ACE_TYPE)

       AceSize: 0x0014

       InheritFlags: 0x00

       Access Mask: 0x100e003f

           READ_CONTROL

           WRITE_DAC

           WRITE_OWNER

           GENERIC_ALL

           Others(0x0000003f)

       Ace Sid: (S-1-0-0)

    SACL

       Not present

这两个例子都涉及到了普通ACE的SDDL表示,还有一种新型的功能更强大、结构更复杂的ACE叫条件ACE,SDDL也为其定义了语法规则,值得用比较大的篇幅去介绍,下一篇我们介绍一下条件ACE。


附:SID字符串

SDDL alias

Well-Known SID name

"DA"

DOMAIN_ADMINS

"DG"

DOMAIN_GUESTS

"DU"

DOMAIN_USERS

"ED"

ENTERPRISE_DOMAIN_CONTROLLERS

"DD"

DOMAIN_DOMAIN_CONTROLLERS

"DC"

DOMAIN_COMPUTERS

"BA"

BUILTIN_ADMINISTRATORS

"BG"

BUILTIN_GUESTS

"BU"

BUILTIN_USERS

"LA"

ADMINISTRATOR<81>

"LG"

GUEST

"AO"

ACCOUNT_OPERATORS

"BO"

BACKUP_OPERATORS

"PO"

PRINTER_OPERATORS

"SO"

SERVER_OPERATORS

"AU"

AUTHENTICATED_USERS

"PS"

PRINCIPAL_SELF

"CO"

CREATOR_OWNER

"CG"

CREATOR_GROUP

"SY"

LOCAL_SYSTEM

"PU"

POWER_USERS

"WD"

EVERYONE

"RE"

REPLICATOR

"IU"

INTERACTIVE

"NU"

NETWORK

"SU"

SERVICE

"RC"

RESTRICTED_CODE

"WR"

WRITE_RESTRICTED_CODE

"AN"

ANONYMOUS

"SA"

SCHEMA_ADMINISTRATORS

"CA"

CERT_PUBLISHERS

"RS"

RAS_SERVERS

"EA"

ENTERPRISE_ADMINS

"PA"

GROUP_POLICY_CREATOR_OWNER

"RU"

ALIAS_PREW2KCOMPACC

"LS"

LOCAL_SERVICE

"NS"

NETWORK_SERVICE

"RD"

REMOTE_DESKTOP

"NO"

NETWORK_CONFIGURATION_OPS

"MU"

PERFMON_USERS

"LU"

PERFLOG_USERS

"IS"

IIS_USERS

"CY"

CRYPTO_OPERATORS

"OW"

OWNER_RIGHTS

"ER"

EVENT_LOG_READERS

"RO"

ENTERPRISE_RO_DCS

"CD"

CERTSVC_DCOM_ACCESS

"AC"

ALL_APP_PACKAGES

"RA"

RDS_REMOTE_ACCESS_SERVERS

"ES"

RDS_ENDPOINT_SERVERS

"MS"

RDS_MANAGEMENT_SERVERS

"UD"

USER_MODE_DRIVERS

"HA"

HYPER_V_ADMINS

"CN"

CLONEABLE_CONTROLLERS

"AA"

ACCESS_CONTROL_ASSISTANCE_OPS

"RM"

REMOTE_MANAGEMENT_USERS

"LW"

ML_LOW

"ME"

ML_MEDIUM

"MP"

ML MEDIUM PLUS

"HI"

ML_HIGH

"SI"

ML_SYSTEM

附:SDDL语法结构(RFC5234 ABNF语法)

 sddl = [owner-string]  [group-string]  [dacl-string]  [sacl-string]

 owner-string = "O:"  sid-string

 group-string = "G:"  sid-string

 dacl-string = "D:"  [acl-flag-string]  [aces]

 sacl-string = "S:"  [acl-flag-string]  [aces]

 sid-string = sid-token / sid-value

 sid-value = SID

    ;defined in section 2.4.2.1  

 sid-token = "DA"/ "DG" / "DU" / "ED" / "DD" / "DC" / "BA" / "BG" / "BU" / "LA" / "LG" / "AO" / "BO" / "PO" / "SO" / "AU" / "PS" / "CO" / "CG" / "SY" / "PU" / "WD" / "RE" / "IU" / "NU" / "SU" / "RC" / "WR" / "AN" / "SA" / "CA" / "RS" / "EA" / "PA" / "RU" / "LS" / "NS" / "RD" / "NO" / "MU" / "LU" / "IS" / "CY" / "OW" / "ER" / "RO" / "CD" / "AC" / "RA" / "ES" / "MS" / "UD" / "HA" / "CN" / "AA" / "RM" / "LW" / "ME" /"MP" /  "HI" / "SI"

 acl-flag-string = *acl-flag

 acl-flag = "P" / "AR" / "AI"

 aces = *(ace / conditional-ace / resource-attribute-ace)

 ace = "(" ace-type ";" [ace-flag-string] ";" ace-rights ";" [object-guid] ";" [inherit-object-guid] ";" sid-string ")"

 ace-type = "A" / "D" / "OA" / "OD" / "AU" / "OU" / "ML" / "SP"

 conditional-ace = "(" conditional-ace-type ";" [ace-flag-string] ";" ace-rights ";" [object-guid] ";" [inherit-object-guid] ";" sid-string ";" "(" cond-expr ")" ")"

 conditional-ace-type = "XA" / "XD" / "ZA" / "XU"

 central-policy-ace = "(" "SP" ";" [ace-flag-string] ";;;;" capid-value-sid ")"

 capid-value-sid = "S-1-17-" 1*SubAuthority

   ; SubAuthority defined in section 2.4.2.1  

 resource-attribute-ace = "(" "RA" ";" [ace-flag-string] ";;;;" ( "WD" / "S-1-1-0" ) ";(" attribute-data "))"

 attribute-data = DQUOTE 1*attr-char2 DQUOTE "," ( TI-attr / TU-attr / TS-attr / TD-attr / TX-attr / TB-attr )

 TI-attr = "TI" "," attr-flags *("," int-64)

 TU-attr = "TU" "," attr-flags *("," uint-64)

 TS-attr = "TS" "," attr-flags *("," char-string)

 TD-attr = "TD" "," attr-flags *("," sid-string)

 TX-attr = "TX" "," attr-flags *("," octet-string)

 TB-attr = "TB" "," attr-flags *("," ( "0" / "1" ) )

 attr-flags = "0x" ([*4HEXDIG  "00"] sys-attr-flags / *"0" sys-attr-flags / *"0" HEXDIG)

 sys-attr-flags = ( "0"/ "1" / "2" / "3" ) HEXDIG

 ace-flag-string = ace-flag  ace-flag-string / ""

 ace-flag = "CI" / "OI" / "NP" / "IO" / "ID" / "SA" / "FA"

 ace-rights = (*text-rights-string) / ("0x" 1*8HEXDIG) / ("0" 1*%x30-37) / (1*DIGIT )

   ; numeric values must fit within 64 bits

 text-rights-string = generic-rights-string / standard-rights-string / object-specific-rights-string

 generic-rights-string = generic-right / generic-rights-string / ""

 generic-right = "GA" / "GW" / "GR" / "GX"

 standard-rights-string = standard-right / standard-rights-string / ""

 standard-right = "WO" / "WD" / "RC" / "SD"

 object-specific-rights-string = object-specific-right / object-specific-rights-string / ""

 object-specific-right = <any object-specific right, for objects like files, registry keys, directory objects, and others>

 guid = "" / 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG

 ; The second option is the GUID of the object in the form

 ; "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" Where each "X" is a Hex digit

 object-guid = guid

 inherit-object-guid = guid

 wspace = 1*(%x09-0D / %x20)

 term = [wspace] (memberof-op / exists-op / rel-op / contains-op / anyof-op / attr-name / rel-op2) [wspace]

 ; multiple rules for cond-expr to represent different precedence of || and &&

 ; super-term and factor are intermediate rules and used only in this part of the grammar

 cond-expr = expr

 expr = super-term [wspace] *( "||" [wspace] super-term )

 super-term = factor [wspace] *( "&&" [wspace] factor )

 factor = term

 factor /= "(" [wspace] expr [wspace] ")"

 factor /= "!" [wspace] factor

 ;

 memberof-op = ( "Member_of" / "Not_Member_of" / "Member_of_Any" / "Not_Member_of_Any" / "Device_Member_of" / "Device_Member_of_Any" / "Not_Device_Member_of" / "Not_Device_Member_of_Any" ) wspace sid-array

 exists-op = ( "Exists" / "Not_exists") wspace attr-name

 rel-op = attr-name [wspace] ("<" / "<=" / ">" / ">=") [wspace] (attr-name2 / value)

   ; only scalars

 rel-op2 = attr-name [wspace] ("==" / "!=") [wspace] ( attr-name2 / value-array )

   ; scalar or list

 contains-op = attr-name wspace ("Contains" / "Not_Contains") wspace (attr-name2 / value-array)

 anyof-op = attr-name wspace ("Any_of" / "Not_Any_of") wspace (attr-name2 / value-array)

 attr-name1 = attr-char1 *(attr-char1 / "@") 

   ; old simple name

 attr-char1 = 1*(ALPHA / DIGIT / ":" / "." / "/" / "_")

 attr-name2 = ("@user." / "@device." / "@resource.") 1*attr-char2

   ; new prefixed name form

 attr-char2 = attr-char1 / lit-char

 attr-name = attr-name1 / attr-name2  

   ; either name form

 sid-array = "{" [wspace] literal-SID [wspace] *( "," [wspace] literal-SID [wspace]) "}"

 literal-SID = "SID(" sid-string ")"

 value-array = value [wspace] / "{" [wspace] value [wspace] *("," [wspace] value [wspace]) "}"

 value = int-64 / char-string / octet-string

 int-64 = ["+" / "-"] ("0x" 1*HEXDIG) / ("0" 1*%x30-37) / 1*DIGIT

   ; values must fit within 64 bits in two's complement form

 uint-64 = ("0x" 1*HEXDIG) / ("0" 1*%x30-37) / 1*DIGIT 

   ; values must fit within 64 bits

 char-string = DQUOTE *(CHAR) DQUOTE

 octet-string = "#" *(2HEXDIG)

 lit-char = "#" / "$" / "'" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "?" / "@" / "[" / "\" / "]" / "^" / "_" / "`" / "{" / "}" / "~" / %x0080-FFFF / ( "%" 4HEXDIG)

   ; 4HEXDIG can have any value except 0000 (NULL)

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用Win32 API创建Windows任务计划表,可以使用Task Scheduler API。以下是创建任务计划表的步骤: 1. 初始化COM库。 ```c++ CoInitialize(NULL); ``` 2. 创建ITaskService对象。 ```c++ ITaskService *pService = NULL; HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService); ``` 3. 连接到本地计算机的任务计划程序。 ```c++ hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); ``` 4. 获取ITaskFolder对象。 ```c++ ITaskFolder *pRootFolder = NULL; hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); ``` 5. 创建任务计划表。 ```c++ IRegisteredTask *pRegisteredTask = NULL; hr = pRootFolder->RegisterTaskDefinition( _bstr_t(L"任务名称"), // 任务名称 pTask, // ITaskDefinition对象 TASK_CREATE, // 创建标志 _variant_t(), // 用户ID _variant_t(), // 密码 TASK_LOGON_INTERACTIVE_TOKEN, // 登录类型 _variant_t(L""), // SDDL字符串 &pRegisteredTask // 返回IRegisteredTask对象 ); ``` 其中,pTask是ITaskDefinition对象,可以通过该对象设置任务的各种属性,如任务的触发器、操作、设置等。 6. 释放COM对象。 ```c++ if (pRegisteredTask) pRegisteredTask->Release(); if (pTask) pTask->Release(); if (pRootFolder) pRootFolder->Release(); if (pService) pService->Release(); CoUninitialize(); ``` 以上就是使用Task Scheduler API创建Windows任务计划表的步骤。需要注意的是,此方法需要管理员权限才能创建任务计划表。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值