advapi32: Implement GetPrivateObjectSecurity (with test).
[wine/multimedia.git] / dlls / advapi32 / security.c
blobcfe73f40104b110fab32d43522a6cc2c18c07924
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
47 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
48 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
49 PACL pAcl, LPDWORD cBytes);
50 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
51 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
52 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
53 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
54 LPCWSTR StringSecurityDescriptor,
55 SECURITY_DESCRIPTOR* SecurityDescriptor,
56 LPDWORD cBytes);
57 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
59 typedef struct _ACEFLAG
61 LPCWSTR wstr;
62 DWORD value;
63 } ACEFLAG, *LPACEFLAG;
65 typedef struct _MAX_SID
67 /* same fields as struct _SID */
68 BYTE Revision;
69 BYTE SubAuthorityCount;
70 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } MAX_SID;
74 typedef struct WELLKNOWNSID
76 WCHAR wstr[2];
77 WELL_KNOWN_SID_TYPE Type;
78 MAX_SID Sid;
79 } WELLKNOWNSID;
81 static const WELLKNOWNSID WellKnownSids[] =
83 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
84 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
85 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
86 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
87 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
88 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
89 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
90 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
91 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
92 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
93 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
94 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
95 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
96 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
97 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
98 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
99 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
100 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
101 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
102 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
103 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
104 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
105 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
106 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
107 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
108 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
109 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
110 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
111 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
112 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
113 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
114 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
115 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
116 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
117 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
118 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
119 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
121 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
122 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
123 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
124 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
125 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
126 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
129 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
131 typedef struct _AccountSid {
132 WELL_KNOWN_SID_TYPE type;
133 LPCWSTR account;
134 LPCWSTR domain;
135 SID_NAME_USE name_use;
136 } AccountSid;
138 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
139 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
140 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
141 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
142 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
143 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
144 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
145 static const WCHAR Blank[] = { 0 };
146 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
147 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
148 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
149 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
150 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
151 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
152 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
153 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
154 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
155 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
156 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
157 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
158 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
159 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
160 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
161 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
162 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
163 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
164 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
165 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
166 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
167 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
168 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
169 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
170 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
171 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
172 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
173 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
174 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
175 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
176 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
177 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
178 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
179 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
180 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
181 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
182 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
183 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
184 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
185 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
186 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
187 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
188 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
189 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
190 static const WCHAR SELF[] = { 'S','E','L','F',0 };
191 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
192 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
193 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
194 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
195 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
196 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
198 static const AccountSid ACCOUNT_SIDS[] = {
199 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
200 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
201 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
202 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
203 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
204 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
205 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
206 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
207 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
208 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
209 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
210 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
211 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
212 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
213 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
214 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
215 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
216 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
217 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
218 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
219 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
220 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
221 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
222 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
223 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
224 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
225 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
226 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
227 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
228 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
229 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
230 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
231 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
232 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
233 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
234 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
235 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
236 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
242 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
245 * ACE access rights
247 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
248 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
249 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
250 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
252 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
253 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
254 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
255 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
256 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
257 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
258 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
259 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
260 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
262 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
263 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
264 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
265 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
267 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
268 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
269 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
270 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
272 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
273 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
274 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
275 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
278 * ACL flags
280 static const WCHAR SDDL_PROTECTED[] = {'P',0};
281 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
282 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
285 * ACE types
287 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
288 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
289 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
290 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
291 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
292 static const WCHAR SDDL_ALARM[] = {'A','L',0};
293 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
294 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
297 * ACE flags
299 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
300 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
301 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
302 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
303 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
304 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
305 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
307 const char * debugstr_sid(PSID sid)
309 int auth = 0;
310 SID * psid = (SID *)sid;
312 if (psid == NULL)
313 return "(null)";
315 auth = psid->IdentifierAuthority.Value[5] +
316 (psid->IdentifierAuthority.Value[4] << 8) +
317 (psid->IdentifierAuthority.Value[3] << 16) +
318 (psid->IdentifierAuthority.Value[2] << 24);
320 switch (psid->SubAuthorityCount) {
321 case 0:
322 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
323 case 1:
324 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
325 psid->SubAuthority[0]);
326 case 2:
327 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
328 psid->SubAuthority[0], psid->SubAuthority[1]);
329 case 3:
330 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
331 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
332 case 4:
333 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
334 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
335 psid->SubAuthority[3]);
336 case 5:
337 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
338 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
339 psid->SubAuthority[3], psid->SubAuthority[4]);
340 case 6:
341 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
342 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
343 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
344 case 7:
345 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
346 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
347 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
348 psid->SubAuthority[6]);
349 case 8:
350 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
351 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
352 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
353 psid->SubAuthority[6], psid->SubAuthority[7]);
355 return "(too-big)";
358 /* set last error code from NT status and get the proper boolean return value */
359 /* used for functions that are a simple wrapper around the corresponding ntdll API */
360 static inline BOOL set_ntstatus( NTSTATUS status )
362 if (status) SetLastError( RtlNtStatusToDosError( status ));
363 return !status;
366 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
368 static void GetWorldAccessACL(PACL pACL)
370 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
372 pACL->AclRevision = ACL_REVISION;
373 pACL->Sbz1 = 0;
374 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
375 pACL->AceCount = 1;
376 pACL->Sbz2 = 0;
378 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
379 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
380 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
381 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
382 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
385 /************************************************************
386 * ADVAPI_IsLocalComputer
388 * Checks whether the server name indicates local machine.
390 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
392 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
393 BOOL Result;
394 LPWSTR buf;
396 if (!ServerName || !ServerName[0])
397 return TRUE;
399 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
400 Result = GetComputerNameW(buf, &dwSize);
401 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
402 ServerName += 2;
403 Result = Result && !lstrcmpW(ServerName, buf);
404 HeapFree(GetProcessHeap(), 0, buf);
406 return Result;
409 /************************************************************
410 * ADVAPI_GetComputerSid
412 * Reads the computer SID from the registry.
414 BOOL ADVAPI_GetComputerSid(PSID sid)
416 HKEY key;
417 LONG ret;
418 BOOL retval = FALSE;
419 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
420 static const WCHAR V[] = { 'V',0 };
422 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
423 KEY_READ, &key)) == ERROR_SUCCESS)
425 DWORD size = 0;
426 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
427 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
429 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
430 if (data)
432 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
433 data, &size)) == ERROR_SUCCESS)
435 /* the SID is in the last 24 bytes of the binary data */
436 CopyMemory(sid, &data[size-24], 24);
437 retval = TRUE;
439 HeapFree(GetProcessHeap(), 0, data);
442 RegCloseKey(key);
445 if(retval == TRUE) return retval;
447 /* create a new random SID */
448 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
449 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
451 PSID new_sid;
452 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
453 DWORD id[3];
455 if (RtlGenRandom(&id, sizeof(id)))
457 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
459 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
460 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
462 FreeSid(new_sid);
465 RegCloseKey(key);
468 return retval;
471 /* ##############################
472 ###### TOKEN FUNCTIONS ######
473 ##############################
476 /******************************************************************************
477 * OpenProcessToken [ADVAPI32.@]
478 * Opens the access token associated with a process handle.
480 * PARAMS
481 * ProcessHandle [I] Handle to process
482 * DesiredAccess [I] Desired access to process
483 * TokenHandle [O] Pointer to handle of open access token
485 * RETURNS
486 * Success: TRUE. TokenHandle contains the access token.
487 * Failure: FALSE.
489 * NOTES
490 * See NtOpenProcessToken.
492 BOOL WINAPI
493 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
494 HANDLE *TokenHandle )
496 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
499 /******************************************************************************
500 * OpenThreadToken [ADVAPI32.@]
502 * Opens the access token associated with a thread handle.
504 * PARAMS
505 * ThreadHandle [I] Handle to process
506 * DesiredAccess [I] Desired access to the thread
507 * OpenAsSelf [I] ???
508 * TokenHandle [O] Destination for the token handle
510 * RETURNS
511 * Success: TRUE. TokenHandle contains the access token.
512 * Failure: FALSE.
514 * NOTES
515 * See NtOpenThreadToken.
517 BOOL WINAPI
518 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
519 BOOL OpenAsSelf, HANDLE *TokenHandle)
521 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
524 BOOL WINAPI
525 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
526 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
528 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
529 PreviousState, ReturnLength));
532 /******************************************************************************
533 * AdjustTokenPrivileges [ADVAPI32.@]
535 * Adjust the privileges of an open token handle.
537 * PARAMS
538 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
539 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
540 * NewState [I] Desired new privileges of the token
541 * BufferLength [I] Length of NewState
542 * PreviousState [O] Destination for the previous state
543 * ReturnLength [I/O] Size of PreviousState
546 * RETURNS
547 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
548 * Failure: FALSE.
550 * NOTES
551 * See NtAdjustPrivilegesToken.
553 BOOL WINAPI
554 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
555 LPVOID NewState, DWORD BufferLength,
556 LPVOID PreviousState, LPDWORD ReturnLength )
558 NTSTATUS status;
560 TRACE("\n");
562 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
563 NewState, BufferLength, PreviousState,
564 ReturnLength);
565 SetLastError( RtlNtStatusToDosError( status ));
566 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
567 return TRUE;
568 else
569 return FALSE;
572 /******************************************************************************
573 * CheckTokenMembership [ADVAPI32.@]
575 * Determine if an access token is a member of a SID.
577 * PARAMS
578 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
579 * SidToCheck [I] SID that possibly contains the token
580 * IsMember [O] Destination for result.
582 * RETURNS
583 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
584 * Failure: FALSE.
586 BOOL WINAPI
587 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
588 PBOOL IsMember )
590 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
592 *IsMember = TRUE;
593 return(TRUE);
596 /******************************************************************************
597 * GetTokenInformation [ADVAPI32.@]
599 * Get a type of information about an access token.
601 * PARAMS
602 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
603 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
604 * tokeninfo [O] Destination for token information
605 * tokeninfolength [I] Length of tokeninfo
606 * retlen [O] Destination for returned token information length
608 * RETURNS
609 * Success: TRUE. tokeninfo contains retlen bytes of token information
610 * Failure: FALSE.
612 * NOTES
613 * See NtQueryInformationToken.
615 BOOL WINAPI
616 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
617 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
619 TRACE("(%p, %s, %p, %d, %p):\n",
620 token,
621 (tokeninfoclass == TokenUser) ? "TokenUser" :
622 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
623 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
624 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
625 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
626 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
627 (tokeninfoclass == TokenSource) ? "TokenSource" :
628 (tokeninfoclass == TokenType) ? "TokenType" :
629 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
630 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
631 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
632 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
633 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
634 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
635 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
636 "Unknown",
637 tokeninfo, tokeninfolength, retlen);
638 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
639 tokeninfolength, retlen));
642 /******************************************************************************
643 * SetTokenInformation [ADVAPI32.@]
645 * Set information for an access token.
647 * PARAMS
648 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
649 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
650 * tokeninfo [I] Token information to set
651 * tokeninfolength [I] Length of tokeninfo
653 * RETURNS
654 * Success: TRUE. The information for the token is set to tokeninfo.
655 * Failure: FALSE.
657 BOOL WINAPI
658 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
659 LPVOID tokeninfo, DWORD tokeninfolength )
661 TRACE("(%p, %s, %p, %d): stub\n",
662 token,
663 (tokeninfoclass == TokenUser) ? "TokenUser" :
664 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
665 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
666 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
667 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
668 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
669 (tokeninfoclass == TokenSource) ? "TokenSource" :
670 (tokeninfoclass == TokenType) ? "TokenType" :
671 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
672 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
673 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
674 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
675 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
676 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
677 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
678 "Unknown",
679 tokeninfo, tokeninfolength);
681 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
684 /*************************************************************************
685 * SetThreadToken [ADVAPI32.@]
687 * Assigns an 'impersonation token' to a thread so it can assume the
688 * security privileges of another thread or process. Can also remove
689 * a previously assigned token.
691 * PARAMS
692 * thread [O] Handle to thread to set the token for
693 * token [I] Token to set
695 * RETURNS
696 * Success: TRUE. The threads access token is set to token
697 * Failure: FALSE.
699 * NOTES
700 * Only supported on NT or higher. On Win9X this function does nothing.
701 * See SetTokenInformation.
703 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
705 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
706 ThreadImpersonationToken, &token, sizeof token ));
709 /* ##############################
710 ###### SID FUNCTIONS ######
711 ##############################
714 /******************************************************************************
715 * AllocateAndInitializeSid [ADVAPI32.@]
717 * PARAMS
718 * pIdentifierAuthority []
719 * nSubAuthorityCount []
720 * nSubAuthority0 []
721 * nSubAuthority1 []
722 * nSubAuthority2 []
723 * nSubAuthority3 []
724 * nSubAuthority4 []
725 * nSubAuthority5 []
726 * nSubAuthority6 []
727 * nSubAuthority7 []
728 * pSid []
730 BOOL WINAPI
731 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
732 BYTE nSubAuthorityCount,
733 DWORD nSubAuthority0, DWORD nSubAuthority1,
734 DWORD nSubAuthority2, DWORD nSubAuthority3,
735 DWORD nSubAuthority4, DWORD nSubAuthority5,
736 DWORD nSubAuthority6, DWORD nSubAuthority7,
737 PSID *pSid )
739 return set_ntstatus( RtlAllocateAndInitializeSid(
740 pIdentifierAuthority, nSubAuthorityCount,
741 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
742 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
743 pSid ));
746 /******************************************************************************
747 * FreeSid [ADVAPI32.@]
749 * PARAMS
750 * pSid []
752 PVOID WINAPI
753 FreeSid( PSID pSid )
755 RtlFreeSid(pSid);
756 return NULL; /* is documented like this */
759 /******************************************************************************
760 * CopySid [ADVAPI32.@]
762 * PARAMS
763 * nDestinationSidLength []
764 * pDestinationSid []
765 * pSourceSid []
767 BOOL WINAPI
768 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
770 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
773 /******************************************************************************
774 * CreateWellKnownSid [ADVAPI32.@]
776 BOOL WINAPI
777 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
778 PSID DomainSid,
779 PSID pSid,
780 DWORD* cbSid)
782 unsigned int i;
783 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
785 if (DomainSid != NULL) {
786 FIXME("Only local computer supported!\n");
787 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME */
788 return FALSE;
791 if (cbSid == NULL || pSid == NULL) {
792 SetLastError(ERROR_INVALID_PARAMETER);
793 return FALSE;
796 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
797 if (WellKnownSids[i].Type == WellKnownSidType) {
798 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
800 if (*cbSid < length) {
801 SetLastError(ERROR_INSUFFICIENT_BUFFER);
802 return FALSE;
805 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
806 *cbSid = length;
807 return TRUE;
811 SetLastError(ERROR_INVALID_PARAMETER);
812 return FALSE;
815 /******************************************************************************
816 * IsWellKnownSid [ADVAPI32.@]
818 BOOL WINAPI
819 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
821 unsigned int i;
822 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
824 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
825 if (WellKnownSids[i].Type == WellKnownSidType)
826 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
827 return TRUE;
829 return FALSE;
832 BOOL WINAPI
833 IsTokenRestricted( HANDLE TokenHandle )
835 TOKEN_GROUPS *groups;
836 DWORD size;
837 NTSTATUS status;
838 BOOL restricted;
840 TRACE("(%p)\n", TokenHandle);
842 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
843 if (status != STATUS_BUFFER_TOO_SMALL)
844 return FALSE;
846 groups = HeapAlloc(GetProcessHeap(), 0, size);
847 if (!groups)
849 SetLastError(ERROR_OUTOFMEMORY);
850 return FALSE;
853 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
854 if (status != STATUS_SUCCESS)
856 HeapFree(GetProcessHeap(), 0, groups);
857 return set_ntstatus(status);
860 if (groups->GroupCount)
861 restricted = TRUE;
862 else
863 restricted = FALSE;
865 HeapFree(GetProcessHeap(), 0, groups);
867 return restricted;
870 /******************************************************************************
871 * IsValidSid [ADVAPI32.@]
873 * PARAMS
874 * pSid []
876 BOOL WINAPI
877 IsValidSid( PSID pSid )
879 return RtlValidSid( pSid );
882 /******************************************************************************
883 * EqualSid [ADVAPI32.@]
885 * PARAMS
886 * pSid1 []
887 * pSid2 []
889 BOOL WINAPI
890 EqualSid( PSID pSid1, PSID pSid2 )
892 return RtlEqualSid( pSid1, pSid2 );
895 /******************************************************************************
896 * EqualPrefixSid [ADVAPI32.@]
898 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
900 return RtlEqualPrefixSid(pSid1, pSid2);
903 /******************************************************************************
904 * GetSidLengthRequired [ADVAPI32.@]
906 * PARAMS
907 * nSubAuthorityCount []
909 DWORD WINAPI
910 GetSidLengthRequired( BYTE nSubAuthorityCount )
912 return RtlLengthRequiredSid(nSubAuthorityCount);
915 /******************************************************************************
916 * InitializeSid [ADVAPI32.@]
918 * PARAMS
919 * pIdentifierAuthority []
921 BOOL WINAPI
922 InitializeSid (
923 PSID pSid,
924 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
925 BYTE nSubAuthorityCount)
927 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
930 DWORD WINAPI
931 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
933 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
935 return 1;
938 DWORD WINAPI
939 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
941 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
943 return 1;
946 /******************************************************************************
947 * GetSidIdentifierAuthority [ADVAPI32.@]
949 * PARAMS
950 * pSid []
952 PSID_IDENTIFIER_AUTHORITY WINAPI
953 GetSidIdentifierAuthority( PSID pSid )
955 return RtlIdentifierAuthoritySid(pSid);
958 /******************************************************************************
959 * GetSidSubAuthority [ADVAPI32.@]
961 * PARAMS
962 * pSid []
963 * nSubAuthority []
965 PDWORD WINAPI
966 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
968 return RtlSubAuthoritySid(pSid, nSubAuthority);
971 /******************************************************************************
972 * GetSidSubAuthorityCount [ADVAPI32.@]
974 * PARAMS
975 * pSid []
977 PUCHAR WINAPI
978 GetSidSubAuthorityCount (PSID pSid)
980 return RtlSubAuthorityCountSid(pSid);
983 /******************************************************************************
984 * GetLengthSid [ADVAPI32.@]
986 * PARAMS
987 * pSid []
989 DWORD WINAPI
990 GetLengthSid (PSID pSid)
992 return RtlLengthSid(pSid);
995 /* ##############################################
996 ###### SECURITY DESCRIPTOR FUNCTIONS ######
997 ##############################################
1000 /******************************************************************************
1001 * BuildSecurityDescriptorA [ADVAPI32.@]
1003 * Builds a SD from
1005 * PARAMS
1006 * pOwner [I]
1007 * pGroup [I]
1008 * cCountOfAccessEntries [I]
1009 * pListOfAccessEntries [I]
1010 * cCountOfAuditEntries [I]
1011 * pListofAuditEntries [I]
1012 * pOldSD [I]
1013 * lpdwBufferLength [I/O]
1014 * pNewSD [O]
1016 * RETURNS
1017 * Success: ERROR_SUCCESS
1018 * Failure: nonzero error code from Winerror.h
1020 DWORD WINAPI BuildSecurityDescriptorA(
1021 IN PTRUSTEEA pOwner,
1022 IN PTRUSTEEA pGroup,
1023 IN ULONG cCountOfAccessEntries,
1024 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1025 IN ULONG cCountOfAuditEntries,
1026 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1027 IN PSECURITY_DESCRIPTOR pOldSD,
1028 IN OUT PULONG lpdwBufferLength,
1029 OUT PSECURITY_DESCRIPTOR* pNewSD)
1031 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1032 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1033 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1035 return ERROR_CALL_NOT_IMPLEMENTED;
1038 /******************************************************************************
1039 * BuildSecurityDescriptorW [ADVAPI32.@]
1041 * See BuildSecurityDescriptorA.
1043 DWORD WINAPI BuildSecurityDescriptorW(
1044 IN PTRUSTEEW pOwner,
1045 IN PTRUSTEEW pGroup,
1046 IN ULONG cCountOfAccessEntries,
1047 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1048 IN ULONG cCountOfAuditEntries,
1049 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1050 IN PSECURITY_DESCRIPTOR pOldSD,
1051 IN OUT PULONG lpdwBufferLength,
1052 OUT PSECURITY_DESCRIPTOR* pNewSD)
1054 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1055 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1056 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1058 return ERROR_CALL_NOT_IMPLEMENTED;
1061 /******************************************************************************
1062 * InitializeSecurityDescriptor [ADVAPI32.@]
1064 * PARAMS
1065 * pDescr []
1066 * revision []
1068 BOOL WINAPI
1069 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1071 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1075 /******************************************************************************
1076 * MakeAbsoluteSD [ADVAPI32.@]
1078 BOOL WINAPI MakeAbsoluteSD (
1079 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1080 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1081 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1082 OUT PACL pDacl,
1083 OUT LPDWORD lpdwDaclSize,
1084 OUT PACL pSacl,
1085 OUT LPDWORD lpdwSaclSize,
1086 OUT PSID pOwner,
1087 OUT LPDWORD lpdwOwnerSize,
1088 OUT PSID pPrimaryGroup,
1089 OUT LPDWORD lpdwPrimaryGroupSize)
1091 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1092 pAbsoluteSecurityDescriptor,
1093 lpdwAbsoluteSecurityDescriptorSize,
1094 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1095 pOwner, lpdwOwnerSize,
1096 pPrimaryGroup, lpdwPrimaryGroupSize));
1099 /******************************************************************************
1100 * GetKernelObjectSecurity [ADVAPI32.@]
1102 BOOL WINAPI GetKernelObjectSecurity(
1103 HANDLE Handle,
1104 SECURITY_INFORMATION RequestedInformation,
1105 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1106 DWORD nLength,
1107 LPDWORD lpnLengthNeeded )
1109 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1110 pSecurityDescriptor, nLength, lpnLengthNeeded);
1112 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1113 nLength, lpnLengthNeeded ));
1116 /******************************************************************************
1117 * GetPrivateObjectSecurity [ADVAPI32.@]
1119 BOOL WINAPI GetPrivateObjectSecurity(
1120 PSECURITY_DESCRIPTOR ObjectDescriptor,
1121 SECURITY_INFORMATION SecurityInformation,
1122 PSECURITY_DESCRIPTOR ResultantDescriptor,
1123 DWORD DescriptorLength,
1124 PDWORD ReturnLength )
1126 SECURITY_DESCRIPTOR desc;
1127 BOOL defaulted, present;
1128 PACL pacl;
1129 PSID psid;
1131 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1132 ResultantDescriptor, DescriptorLength, ReturnLength);
1134 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1135 return FALSE;
1137 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1139 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1140 return FALSE;
1141 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1144 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1146 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1147 return FALSE;
1148 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1151 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1153 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1154 return FALSE;
1155 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1158 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1160 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1161 return FALSE;
1162 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1165 *ReturnLength = DescriptorLength;
1166 if (!MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength))
1167 return FALSE;
1168 GetSecurityDescriptorOwner(ResultantDescriptor, &psid, &defaulted);
1169 FIXME("%p, sid=%p\n", &desc, psid);
1170 return TRUE;
1173 /******************************************************************************
1174 * GetSecurityDescriptorLength [ADVAPI32.@]
1176 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1178 return RtlLengthSecurityDescriptor(pDescr);
1181 /******************************************************************************
1182 * GetSecurityDescriptorOwner [ADVAPI32.@]
1184 * PARAMS
1185 * pOwner []
1186 * lpbOwnerDefaulted []
1188 BOOL WINAPI
1189 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1190 LPBOOL lpbOwnerDefaulted )
1192 BOOLEAN defaulted;
1193 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1194 *lpbOwnerDefaulted = defaulted;
1195 return ret;
1198 /******************************************************************************
1199 * SetSecurityDescriptorOwner [ADVAPI32.@]
1201 * PARAMS
1203 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1204 PSID pOwner, BOOL bOwnerDefaulted)
1206 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1208 /******************************************************************************
1209 * GetSecurityDescriptorGroup [ADVAPI32.@]
1211 BOOL WINAPI GetSecurityDescriptorGroup(
1212 PSECURITY_DESCRIPTOR SecurityDescriptor,
1213 PSID *Group,
1214 LPBOOL GroupDefaulted)
1216 BOOLEAN defaulted;
1217 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1218 *GroupDefaulted = defaulted;
1219 return ret;
1221 /******************************************************************************
1222 * SetSecurityDescriptorGroup [ADVAPI32.@]
1224 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1225 PSID Group, BOOL GroupDefaulted)
1227 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1230 /******************************************************************************
1231 * IsValidSecurityDescriptor [ADVAPI32.@]
1233 * PARAMS
1234 * lpsecdesc []
1236 BOOL WINAPI
1237 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1239 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1242 /******************************************************************************
1243 * GetSecurityDescriptorDacl [ADVAPI32.@]
1245 BOOL WINAPI GetSecurityDescriptorDacl(
1246 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1247 OUT LPBOOL lpbDaclPresent,
1248 OUT PACL *pDacl,
1249 OUT LPBOOL lpbDaclDefaulted)
1251 BOOLEAN present, defaulted;
1252 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1253 *lpbDaclPresent = present;
1254 *lpbDaclDefaulted = defaulted;
1255 return ret;
1258 /******************************************************************************
1259 * SetSecurityDescriptorDacl [ADVAPI32.@]
1261 BOOL WINAPI
1262 SetSecurityDescriptorDacl (
1263 PSECURITY_DESCRIPTOR lpsd,
1264 BOOL daclpresent,
1265 PACL dacl,
1266 BOOL dacldefaulted )
1268 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1270 /******************************************************************************
1271 * GetSecurityDescriptorSacl [ADVAPI32.@]
1273 BOOL WINAPI GetSecurityDescriptorSacl(
1274 IN PSECURITY_DESCRIPTOR lpsd,
1275 OUT LPBOOL lpbSaclPresent,
1276 OUT PACL *pSacl,
1277 OUT LPBOOL lpbSaclDefaulted)
1279 BOOLEAN present, defaulted;
1280 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1281 *lpbSaclPresent = present;
1282 *lpbSaclDefaulted = defaulted;
1283 return ret;
1286 /**************************************************************************
1287 * SetSecurityDescriptorSacl [ADVAPI32.@]
1289 BOOL WINAPI SetSecurityDescriptorSacl (
1290 PSECURITY_DESCRIPTOR lpsd,
1291 BOOL saclpresent,
1292 PACL lpsacl,
1293 BOOL sacldefaulted)
1295 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1297 /******************************************************************************
1298 * MakeSelfRelativeSD [ADVAPI32.@]
1300 * PARAMS
1301 * lpabssecdesc []
1302 * lpselfsecdesc []
1303 * lpbuflen []
1305 BOOL WINAPI
1306 MakeSelfRelativeSD(
1307 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1308 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1309 IN OUT LPDWORD lpdwBufferLength)
1311 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1312 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1315 /******************************************************************************
1316 * GetSecurityDescriptorControl [ADVAPI32.@]
1319 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1320 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1322 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1325 /* ##############################
1326 ###### ACL FUNCTIONS ######
1327 ##############################
1330 /*************************************************************************
1331 * InitializeAcl [ADVAPI32.@]
1333 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1335 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1338 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1340 IO_STATUS_BLOCK io_block;
1342 TRACE("(%p)\n", hNamedPipe);
1344 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1345 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1348 /******************************************************************************
1349 * AddAccessAllowedAce [ADVAPI32.@]
1351 BOOL WINAPI AddAccessAllowedAce(
1352 IN OUT PACL pAcl,
1353 IN DWORD dwAceRevision,
1354 IN DWORD AccessMask,
1355 IN PSID pSid)
1357 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1360 /******************************************************************************
1361 * AddAccessAllowedAceEx [ADVAPI32.@]
1363 BOOL WINAPI AddAccessAllowedAceEx(
1364 IN OUT PACL pAcl,
1365 IN DWORD dwAceRevision,
1366 IN DWORD AceFlags,
1367 IN DWORD AccessMask,
1368 IN PSID pSid)
1370 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1373 /******************************************************************************
1374 * AddAccessDeniedAce [ADVAPI32.@]
1376 BOOL WINAPI AddAccessDeniedAce(
1377 IN OUT PACL pAcl,
1378 IN DWORD dwAceRevision,
1379 IN DWORD AccessMask,
1380 IN PSID pSid)
1382 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1385 /******************************************************************************
1386 * AddAccessDeniedAceEx [ADVAPI32.@]
1388 BOOL WINAPI AddAccessDeniedAceEx(
1389 IN OUT PACL pAcl,
1390 IN DWORD dwAceRevision,
1391 IN DWORD AceFlags,
1392 IN DWORD AccessMask,
1393 IN PSID pSid)
1395 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1398 /******************************************************************************
1399 * AddAce [ADVAPI32.@]
1401 BOOL WINAPI AddAce(
1402 IN OUT PACL pAcl,
1403 IN DWORD dwAceRevision,
1404 IN DWORD dwStartingAceIndex,
1405 LPVOID pAceList,
1406 DWORD nAceListLength)
1408 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1411 /******************************************************************************
1412 * DeleteAce [ADVAPI32.@]
1414 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1416 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1419 /******************************************************************************
1420 * FindFirstFreeAce [ADVAPI32.@]
1422 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1424 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1427 /******************************************************************************
1428 * GetAce [ADVAPI32.@]
1430 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1432 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1435 /******************************************************************************
1436 * GetAclInformation [ADVAPI32.@]
1438 BOOL WINAPI GetAclInformation(
1439 PACL pAcl,
1440 LPVOID pAclInformation,
1441 DWORD nAclInformationLength,
1442 ACL_INFORMATION_CLASS dwAclInformationClass)
1444 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1445 nAclInformationLength, dwAclInformationClass));
1448 /******************************************************************************
1449 * IsValidAcl [ADVAPI32.@]
1451 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1453 return RtlValidAcl(pAcl);
1456 /* ##############################
1457 ###### MISC FUNCTIONS ######
1458 ##############################
1461 /******************************************************************************
1462 * AllocateLocallyUniqueId [ADVAPI32.@]
1464 * PARAMS
1465 * lpLuid []
1467 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1469 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1472 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1473 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1474 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1475 { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1476 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1477 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1478 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1479 { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1480 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1481 { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1482 static const WCHAR SE_TCB_NAME_W[] =
1483 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1484 static const WCHAR SE_SECURITY_NAME_W[] =
1485 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1486 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1487 { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1488 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1489 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1490 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1491 { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1492 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1493 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1494 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1495 { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1496 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1497 { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1498 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1499 { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1500 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1501 { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1502 static const WCHAR SE_BACKUP_NAME_W[] =
1503 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1504 static const WCHAR SE_RESTORE_NAME_W[] =
1505 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1506 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1507 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1508 static const WCHAR SE_DEBUG_NAME_W[] =
1509 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1510 static const WCHAR SE_AUDIT_NAME_W[] =
1511 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1512 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1513 { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1514 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1515 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1516 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1517 { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1518 static const WCHAR SE_UNDOCK_NAME_W[] =
1519 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1520 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1521 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1522 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1523 { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1524 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1525 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1526 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1527 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1528 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1529 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1531 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1533 NULL,
1534 NULL,
1535 SE_CREATE_TOKEN_NAME_W,
1536 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1537 SE_LOCK_MEMORY_NAME_W,
1538 SE_INCREASE_QUOTA_NAME_W,
1539 SE_MACHINE_ACCOUNT_NAME_W,
1540 SE_TCB_NAME_W,
1541 SE_SECURITY_NAME_W,
1542 SE_TAKE_OWNERSHIP_NAME_W,
1543 SE_LOAD_DRIVER_NAME_W,
1544 SE_SYSTEM_PROFILE_NAME_W,
1545 SE_SYSTEMTIME_NAME_W,
1546 SE_PROF_SINGLE_PROCESS_NAME_W,
1547 SE_INC_BASE_PRIORITY_NAME_W,
1548 SE_CREATE_PAGEFILE_NAME_W,
1549 SE_CREATE_PERMANENT_NAME_W,
1550 SE_BACKUP_NAME_W,
1551 SE_RESTORE_NAME_W,
1552 SE_SHUTDOWN_NAME_W,
1553 SE_DEBUG_NAME_W,
1554 SE_AUDIT_NAME_W,
1555 SE_SYSTEM_ENVIRONMENT_NAME_W,
1556 SE_CHANGE_NOTIFY_NAME_W,
1557 SE_REMOTE_SHUTDOWN_NAME_W,
1558 SE_UNDOCK_NAME_W,
1559 SE_SYNC_AGENT_NAME_W,
1560 SE_ENABLE_DELEGATION_NAME_W,
1561 SE_MANAGE_VOLUME_NAME_W,
1562 SE_IMPERSONATE_NAME_W,
1563 SE_CREATE_GLOBAL_NAME_W,
1566 /******************************************************************************
1567 * LookupPrivilegeValueW [ADVAPI32.@]
1569 * See LookupPrivilegeValueA.
1571 BOOL WINAPI
1572 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1574 UINT i;
1576 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1578 if (!ADVAPI_IsLocalComputer(lpSystemName))
1580 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1581 return FALSE;
1583 if (!lpName)
1585 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1586 return FALSE;
1588 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1590 if( !WellKnownPrivNames[i] )
1591 continue;
1592 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1593 continue;
1594 lpLuid->LowPart = i;
1595 lpLuid->HighPart = 0;
1596 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1597 lpLuid->HighPart, lpLuid->LowPart );
1598 return TRUE;
1600 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1601 return FALSE;
1604 /******************************************************************************
1605 * LookupPrivilegeValueA [ADVAPI32.@]
1607 * Retrieves LUID used on a system to represent the privilege name.
1609 * PARAMS
1610 * lpSystemName [I] Name of the system
1611 * lpName [I] Name of the privilege
1612 * lpLuid [O] Destination for the resulting LUID
1614 * RETURNS
1615 * Success: TRUE. lpLuid contains the requested LUID.
1616 * Failure: FALSE.
1618 BOOL WINAPI
1619 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1621 UNICODE_STRING lpSystemNameW;
1622 UNICODE_STRING lpNameW;
1623 BOOL ret;
1625 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1626 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1627 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1628 RtlFreeUnicodeString(&lpNameW);
1629 RtlFreeUnicodeString(&lpSystemNameW);
1630 return ret;
1633 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1634 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1636 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1637 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1639 return FALSE;
1642 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1643 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1645 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1646 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1648 return FALSE;
1651 /******************************************************************************
1652 * LookupPrivilegeNameA [ADVAPI32.@]
1654 * See LookupPrivilegeNameW.
1656 BOOL WINAPI
1657 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1658 LPDWORD cchName)
1660 UNICODE_STRING lpSystemNameW;
1661 BOOL ret;
1662 DWORD wLen = 0;
1664 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1666 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1667 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1668 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1670 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1672 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1673 &wLen);
1674 if (ret)
1676 /* Windows crashes if cchName is NULL, so will I */
1677 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1678 *cchName, NULL, NULL);
1680 if (len == 0)
1682 /* WideCharToMultiByte failed */
1683 ret = FALSE;
1685 else if (len > *cchName)
1687 *cchName = len;
1688 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1689 ret = FALSE;
1691 else
1693 /* WideCharToMultiByte succeeded, output length needs to be
1694 * length not including NULL terminator
1696 *cchName = len - 1;
1699 HeapFree(GetProcessHeap(), 0, lpNameW);
1701 RtlFreeUnicodeString(&lpSystemNameW);
1702 return ret;
1705 /******************************************************************************
1706 * LookupPrivilegeNameW [ADVAPI32.@]
1708 * Retrieves the privilege name referred to by the LUID lpLuid.
1710 * PARAMS
1711 * lpSystemName [I] Name of the system
1712 * lpLuid [I] Privilege value
1713 * lpName [O] Name of the privilege
1714 * cchName [I/O] Number of characters in lpName.
1716 * RETURNS
1717 * Success: TRUE. lpName contains the name of the privilege whose value is
1718 * *lpLuid.
1719 * Failure: FALSE.
1721 * REMARKS
1722 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1723 * using this function.
1724 * If the length of lpName is too small, on return *cchName will contain the
1725 * number of WCHARs needed to contain the privilege, including the NULL
1726 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1727 * On success, *cchName will contain the number of characters stored in
1728 * lpName, NOT including the NULL terminator.
1730 BOOL WINAPI
1731 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1732 LPDWORD cchName)
1734 size_t privNameLen;
1736 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1738 if (!ADVAPI_IsLocalComputer(lpSystemName))
1740 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1741 return FALSE;
1743 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1744 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1746 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1747 return FALSE;
1749 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1750 /* Windows crashes if cchName is NULL, so will I */
1751 if (*cchName <= privNameLen)
1753 *cchName = privNameLen + 1;
1754 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1755 return FALSE;
1757 else
1759 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1760 *cchName = privNameLen;
1761 return TRUE;
1765 /******************************************************************************
1766 * GetFileSecurityA [ADVAPI32.@]
1768 * Obtains Specified information about the security of a file or directory.
1770 * PARAMS
1771 * lpFileName [I] Name of the file to get info for
1772 * RequestedInformation [I] SE_ flags from "winnt.h"
1773 * pSecurityDescriptor [O] Destination for security information
1774 * nLength [I] Length of pSecurityDescriptor
1775 * lpnLengthNeeded [O] Destination for length of returned security information
1777 * RETURNS
1778 * Success: TRUE. pSecurityDescriptor contains the requested information.
1779 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1781 * NOTES
1782 * The information returned is constrained by the callers access rights and
1783 * privileges.
1785 BOOL WINAPI
1786 GetFileSecurityA( LPCSTR lpFileName,
1787 SECURITY_INFORMATION RequestedInformation,
1788 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1789 DWORD nLength, LPDWORD lpnLengthNeeded )
1791 DWORD len;
1792 BOOL r;
1793 LPWSTR name = NULL;
1795 if( lpFileName )
1797 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1798 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1799 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1802 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1803 nLength, lpnLengthNeeded );
1804 HeapFree( GetProcessHeap(), 0, name );
1806 return r;
1809 /******************************************************************************
1810 * GetFileSecurityW [ADVAPI32.@]
1812 * See GetFileSecurityA.
1814 BOOL WINAPI
1815 GetFileSecurityW( LPCWSTR lpFileName,
1816 SECURITY_INFORMATION RequestedInformation,
1817 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1818 DWORD nLength, LPDWORD lpnLengthNeeded )
1820 HANDLE hfile;
1821 NTSTATUS status;
1823 hfile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ,
1824 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1825 if ( hfile == INVALID_HANDLE_VALUE )
1826 return FALSE;
1828 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1829 nLength, lpnLengthNeeded );
1830 CloseHandle( hfile );
1831 return set_ntstatus( status );
1835 /******************************************************************************
1836 * LookupAccountSidA [ADVAPI32.@]
1838 BOOL WINAPI
1839 LookupAccountSidA(
1840 IN LPCSTR system,
1841 IN PSID sid,
1842 OUT LPSTR account,
1843 IN OUT LPDWORD accountSize,
1844 OUT LPSTR domain,
1845 IN OUT LPDWORD domainSize,
1846 OUT PSID_NAME_USE name_use )
1848 DWORD len;
1849 BOOL r;
1850 LPWSTR systemW = NULL;
1851 LPWSTR accountW = NULL;
1852 LPWSTR domainW = NULL;
1853 DWORD accountSizeW = *accountSize;
1854 DWORD domainSizeW = *domainSize;
1856 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1857 debugstr_a(system),debugstr_sid(sid),
1858 account,accountSize,accountSize?*accountSize:0,
1859 domain,domainSize,domainSize?*domainSize:0,
1860 name_use);
1862 if (system) {
1863 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1864 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1865 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1867 if (account)
1868 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1869 if (domain)
1870 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1872 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1874 if (r) {
1875 if (accountW && *accountSize) {
1876 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1877 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1878 *accountSize = len;
1879 } else
1880 *accountSize = accountSizeW + 1;
1882 if (domainW && *domainSize) {
1883 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1884 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1885 *domainSize = len;
1886 } else
1887 *domainSize = domainSizeW + 1;
1890 HeapFree( GetProcessHeap(), 0, systemW );
1891 HeapFree( GetProcessHeap(), 0, accountW );
1892 HeapFree( GetProcessHeap(), 0, domainW );
1894 return r;
1897 /******************************************************************************
1898 * LookupAccountSidW [ADVAPI32.@]
1900 * PARAMS
1901 * system []
1902 * sid []
1903 * account []
1904 * accountSize []
1905 * domain []
1906 * domainSize []
1907 * name_use []
1910 BOOL WINAPI
1911 LookupAccountSidW(
1912 IN LPCWSTR system,
1913 IN PSID sid,
1914 OUT LPWSTR account,
1915 IN OUT LPDWORD accountSize,
1916 OUT LPWSTR domain,
1917 IN OUT LPDWORD domainSize,
1918 OUT PSID_NAME_USE name_use )
1920 unsigned int i, j;
1921 const WCHAR * ac = NULL;
1922 const WCHAR * dm = NULL;
1923 SID_NAME_USE use = 0;
1924 LPWSTR computer_name = NULL;
1926 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1927 debugstr_w(system),debugstr_sid(sid),
1928 account,accountSize,accountSize?*accountSize:0,
1929 domain,domainSize,domainSize?*domainSize:0,
1930 name_use);
1932 if (!ADVAPI_IsLocalComputer(system)) {
1933 FIXME("Only local computer supported!\n");
1934 SetLastError(ERROR_NONE_MAPPED);
1935 return FALSE;
1938 /* check the well known SIDs first */
1939 for (i = 0; i <= 60; i++) {
1940 if (IsWellKnownSid(sid, i)) {
1941 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1942 if (ACCOUNT_SIDS[j].type == i) {
1943 ac = ACCOUNT_SIDS[j].account;
1944 dm = ACCOUNT_SIDS[j].domain;
1945 use = ACCOUNT_SIDS[j].name_use;
1948 break;
1952 if (dm == NULL) {
1953 MAX_SID local;
1955 /* check for the local computer next */
1956 if (ADVAPI_GetComputerSid(&local)) {
1957 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1958 BOOL result;
1960 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1961 result = GetComputerNameW(computer_name, &size);
1963 if (result) {
1964 if (EqualSid(sid, &local)) {
1965 dm = computer_name;
1966 ac = Blank;
1967 use = 3;
1968 } else {
1969 local.SubAuthorityCount++;
1971 if (EqualPrefixSid(sid, &local)) {
1972 dm = computer_name;
1973 use = 1;
1974 switch (((MAX_SID *)sid)->SubAuthority[4]) {
1975 case DOMAIN_USER_RID_ADMIN:
1976 ac = Administrator;
1977 break;
1978 case DOMAIN_USER_RID_GUEST:
1979 ac = Guest;
1980 break;
1981 case DOMAIN_GROUP_RID_ADMINS:
1982 ac = Domain_Admins;
1983 break;
1984 case DOMAIN_GROUP_RID_USERS:
1985 ac = Domain_Users;
1986 break;
1987 case DOMAIN_GROUP_RID_GUESTS:
1988 ac = Domain_Guests;
1989 break;
1990 case DOMAIN_GROUP_RID_COMPUTERS:
1991 ac = Domain_Computers;
1992 break;
1993 case DOMAIN_GROUP_RID_CONTROLLERS:
1994 ac = Domain_Controllers;
1995 break;
1996 case DOMAIN_GROUP_RID_CERT_ADMINS:
1997 ac = Cert_Publishers;
1998 break;
1999 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2000 ac = Schema_Admins;
2001 break;
2002 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2003 ac = Enterprise_Admins;
2004 break;
2005 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2006 ac = Group_Policy_Creator_Owners;
2007 break;
2008 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2009 ac = RAS_and_IAS_Servers;
2010 break;
2011 default:
2012 dm = NULL;
2013 break;
2021 if (dm) {
2022 BOOL status = TRUE;
2023 if (*accountSize > lstrlenW(ac)) {
2024 if (account)
2025 lstrcpyW(account, ac);
2027 if (*domainSize > lstrlenW(dm)) {
2028 if (domain)
2029 lstrcpyW(domain, dm);
2031 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2032 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2033 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2034 status = FALSE;
2036 if (*domainSize)
2037 *domainSize = strlenW(dm);
2038 else
2039 *domainSize = strlenW(dm) + 1;
2040 if (*accountSize)
2041 *accountSize = strlenW(ac);
2042 else
2043 *accountSize = strlenW(ac) + 1;
2044 *name_use = use;
2045 HeapFree(GetProcessHeap(), 0, computer_name);
2046 return status;
2049 HeapFree(GetProcessHeap(), 0, computer_name);
2050 SetLastError(ERROR_NONE_MAPPED);
2051 return FALSE;
2054 /******************************************************************************
2055 * SetFileSecurityA [ADVAPI32.@]
2057 * See SetFileSecurityW.
2059 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2060 SECURITY_INFORMATION RequestedInformation,
2061 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2063 DWORD len;
2064 BOOL r;
2065 LPWSTR name = NULL;
2067 if( lpFileName )
2069 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2070 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2071 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2074 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2075 HeapFree( GetProcessHeap(), 0, name );
2077 return r;
2080 /******************************************************************************
2081 * SetFileSecurityW [ADVAPI32.@]
2083 * Sets the security of a file or directory.
2085 * PARAMS
2086 * lpFileName []
2087 * RequestedInformation []
2088 * pSecurityDescriptor []
2090 * RETURNS
2091 * Success: TRUE.
2092 * Failure: FALSE.
2094 BOOL WINAPI
2095 SetFileSecurityW( LPCWSTR lpFileName,
2096 SECURITY_INFORMATION RequestedInformation,
2097 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2099 FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
2100 return TRUE;
2103 /******************************************************************************
2104 * QueryWindows31FilesMigration [ADVAPI32.@]
2106 * PARAMS
2107 * x1 []
2109 BOOL WINAPI
2110 QueryWindows31FilesMigration( DWORD x1 )
2112 FIXME("(%d):stub\n",x1);
2113 return TRUE;
2116 /******************************************************************************
2117 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2119 * PARAMS
2120 * x1 []
2121 * x2 []
2122 * x3 []
2123 * x4 []
2125 BOOL WINAPI
2126 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2127 DWORD x4 )
2129 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2130 return TRUE;
2133 /******************************************************************************
2134 * NotifyBootConfigStatus [ADVAPI32.@]
2136 * PARAMS
2137 * x1 []
2139 BOOL WINAPI
2140 NotifyBootConfigStatus( BOOL x1 )
2142 FIXME("(0x%08d):stub\n",x1);
2143 return 1;
2146 /******************************************************************************
2147 * RevertToSelf [ADVAPI32.@]
2149 * Ends the impersonation of a user.
2151 * PARAMS
2152 * void []
2154 * RETURNS
2155 * Success: TRUE.
2156 * Failure: FALSE.
2158 BOOL WINAPI
2159 RevertToSelf( void )
2161 HANDLE Token = NULL;
2162 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2163 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2166 /******************************************************************************
2167 * ImpersonateSelf [ADVAPI32.@]
2169 * Makes an impersonation token that represents the process user and assigns
2170 * to the current thread.
2172 * PARAMS
2173 * ImpersonationLevel [I] Level at which to impersonate.
2175 * RETURNS
2176 * Success: TRUE.
2177 * Failure: FALSE.
2179 BOOL WINAPI
2180 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2182 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2185 /******************************************************************************
2186 * ImpersonateLoggedOnUser [ADVAPI32.@]
2188 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2190 DWORD size;
2191 NTSTATUS Status;
2192 HANDLE ImpersonationToken;
2193 TOKEN_TYPE Type;
2195 FIXME( "(%p)\n", hToken );
2197 if (!GetTokenInformation( hToken, TokenType, &Type,
2198 sizeof(TOKEN_TYPE), &size ))
2199 return FALSE;
2201 if (Type == TokenPrimary)
2203 OBJECT_ATTRIBUTES ObjectAttributes;
2205 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2207 Status = NtDuplicateToken( hToken,
2208 TOKEN_IMPERSONATE | TOKEN_QUERY,
2209 &ObjectAttributes,
2210 SecurityImpersonation,
2211 TokenImpersonation,
2212 &ImpersonationToken );
2213 if (Status != STATUS_SUCCESS)
2215 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2216 SetLastError( RtlNtStatusToDosError( Status ) );
2217 return FALSE;
2220 else
2221 ImpersonationToken = hToken;
2223 Status = NtSetInformationThread( GetCurrentThread(),
2224 ThreadImpersonationToken,
2225 &ImpersonationToken,
2226 sizeof(ImpersonationToken) );
2228 if (Type == TokenPrimary)
2229 NtClose( ImpersonationToken );
2231 if (Status != STATUS_SUCCESS)
2233 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2234 SetLastError( RtlNtStatusToDosError( Status ) );
2235 return FALSE;
2238 return TRUE;
2241 /******************************************************************************
2242 * AccessCheck [ADVAPI32.@]
2244 BOOL WINAPI
2245 AccessCheck(
2246 PSECURITY_DESCRIPTOR SecurityDescriptor,
2247 HANDLE ClientToken,
2248 DWORD DesiredAccess,
2249 PGENERIC_MAPPING GenericMapping,
2250 PPRIVILEGE_SET PrivilegeSet,
2251 LPDWORD PrivilegeSetLength,
2252 LPDWORD GrantedAccess,
2253 LPBOOL AccessStatus)
2255 NTSTATUS access_status;
2256 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2257 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2258 GrantedAccess, &access_status) );
2259 if (ret) *AccessStatus = set_ntstatus( access_status );
2260 return ret;
2264 /******************************************************************************
2265 * AccessCheckByType [ADVAPI32.@]
2267 BOOL WINAPI AccessCheckByType(
2268 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2269 PSID PrincipalSelfSid,
2270 HANDLE ClientToken,
2271 DWORD DesiredAccess,
2272 POBJECT_TYPE_LIST ObjectTypeList,
2273 DWORD ObjectTypeListLength,
2274 PGENERIC_MAPPING GenericMapping,
2275 PPRIVILEGE_SET PrivilegeSet,
2276 LPDWORD PrivilegeSetLength,
2277 LPDWORD GrantedAccess,
2278 LPBOOL AccessStatus)
2280 FIXME("stub\n");
2282 *AccessStatus = TRUE;
2284 return !*AccessStatus;
2287 /******************************************************************************
2288 * MapGenericMask [ADVAPI32.@]
2290 * Maps generic access rights into specific access rights according to the
2291 * supplied mapping.
2293 * PARAMS
2294 * AccessMask [I/O] Access rights.
2295 * GenericMapping [I] The mapping between generic and specific rights.
2297 * RETURNS
2298 * Nothing.
2300 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2302 RtlMapGenericMask( AccessMask, GenericMapping );
2305 /*************************************************************************
2306 * SetKernelObjectSecurity [ADVAPI32.@]
2308 BOOL WINAPI SetKernelObjectSecurity (
2309 IN HANDLE Handle,
2310 IN SECURITY_INFORMATION SecurityInformation,
2311 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2313 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2317 /******************************************************************************
2318 * AddAuditAccessAce [ADVAPI32.@]
2320 BOOL WINAPI AddAuditAccessAce(
2321 IN OUT PACL pAcl,
2322 IN DWORD dwAceRevision,
2323 IN DWORD dwAccessMask,
2324 IN PSID pSid,
2325 IN BOOL bAuditSuccess,
2326 IN BOOL bAuditFailure)
2328 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2329 bAuditSuccess, bAuditFailure) );
2332 /******************************************************************************
2333 * AddAuditAccessAce [ADVAPI32.@]
2335 BOOL WINAPI AddAuditAccessAceEx(
2336 IN OUT PACL pAcl,
2337 IN DWORD dwAceRevision,
2338 IN DWORD dwAceFlags,
2339 IN DWORD dwAccessMask,
2340 IN PSID pSid,
2341 IN BOOL bAuditSuccess,
2342 IN BOOL bAuditFailure)
2344 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2345 bAuditSuccess, bAuditFailure) );
2348 /******************************************************************************
2349 * LookupAccountNameA [ADVAPI32.@]
2351 BOOL WINAPI
2352 LookupAccountNameA(
2353 IN LPCSTR system,
2354 IN LPCSTR account,
2355 OUT PSID sid,
2356 OUT LPDWORD cbSid,
2357 LPSTR ReferencedDomainName,
2358 IN OUT LPDWORD cbReferencedDomainName,
2359 OUT PSID_NAME_USE name_use )
2361 BOOL ret;
2362 UNICODE_STRING lpSystemW;
2363 UNICODE_STRING lpAccountW;
2364 LPWSTR lpReferencedDomainNameW = NULL;
2366 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2367 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2369 if (ReferencedDomainName)
2370 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2372 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2373 cbReferencedDomainName, name_use);
2375 if (ret && lpReferencedDomainNameW)
2377 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2378 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2381 RtlFreeUnicodeString(&lpSystemW);
2382 RtlFreeUnicodeString(&lpAccountW);
2383 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2385 return ret;
2388 /******************************************************************************
2389 * LookupAccountNameW [ADVAPI32.@]
2391 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2392 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2393 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2395 /* Default implementation: Always return a default SID */
2396 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2397 BOOL ret;
2398 PSID pSid;
2399 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2401 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2402 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2404 ret = AllocateAndInitializeSid(&identifierAuthority,
2406 SECURITY_BUILTIN_DOMAIN_RID,
2407 DOMAIN_ALIAS_RID_ADMINS,
2408 0, 0, 0, 0, 0, 0,
2409 &pSid);
2411 if (!ret)
2412 return FALSE;
2414 if (!RtlValidSid(pSid))
2416 FreeSid(pSid);
2417 return FALSE;
2420 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2421 CopySid(*cbSid, Sid, pSid);
2422 if (*cbSid < GetLengthSid(pSid))
2424 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2425 ret = FALSE;
2427 *cbSid = GetLengthSid(pSid);
2429 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2430 strcpyW(ReferencedDomainName, dm);
2432 if (*cchReferencedDomainName <= strlenW(dm))
2434 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2435 ret = FALSE;
2438 *cchReferencedDomainName = strlenW(dm)+1;
2440 FreeSid(pSid);
2442 return ret;
2445 /******************************************************************************
2446 * PrivilegeCheck [ADVAPI32.@]
2448 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2450 BOOL ret;
2451 BOOLEAN Result;
2453 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2455 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2456 if (ret)
2457 *pfResult = Result;
2458 return ret;
2461 /******************************************************************************
2462 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2464 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2465 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2466 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2467 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2469 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2470 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2471 SecurityDescriptor, DesiredAccess, GenericMapping,
2472 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2473 return TRUE;
2476 /******************************************************************************
2477 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2479 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2480 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2481 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2482 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2484 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2485 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2486 SecurityDescriptor, DesiredAccess, GenericMapping,
2487 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2488 return TRUE;
2491 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2493 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2495 return TRUE;
2498 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2500 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2502 return TRUE;
2505 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2507 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2509 return TRUE;
2512 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2513 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2514 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2515 LPBOOL GenerateOnClose)
2517 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2518 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2519 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2520 GenerateOnClose);
2522 return TRUE;
2525 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2526 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2527 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2528 LPBOOL GenerateOnClose)
2530 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2531 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2532 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2533 GenerateOnClose);
2535 return TRUE;
2538 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2539 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2541 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2542 DesiredAccess, Privileges, AccessGranted);
2544 return TRUE;
2547 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2548 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2550 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2551 DesiredAccess, Privileges, AccessGranted);
2553 return TRUE;
2556 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2557 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2559 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2560 ClientToken, Privileges, AccessGranted);
2562 return TRUE;
2565 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2566 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2568 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2569 ClientToken, Privileges, AccessGranted);
2571 return TRUE;
2574 /******************************************************************************
2575 * GetSecurityInfo [ADVAPI32.@]
2577 DWORD WINAPI GetSecurityInfo(
2578 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2579 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2580 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2581 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2584 FIXME("stub!\n");
2585 return ERROR_BAD_PROVIDER;
2588 /******************************************************************************
2589 * GetSecurityInfoExW [ADVAPI32.@]
2591 DWORD WINAPI GetSecurityInfoExW(
2592 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2593 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2594 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2595 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2598 FIXME("stub!\n");
2599 return ERROR_BAD_PROVIDER;
2602 /******************************************************************************
2603 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2605 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2606 LPSTR pTrusteeName, DWORD AccessPermissions,
2607 ACCESS_MODE AccessMode, DWORD Inheritance )
2609 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2610 AccessPermissions, AccessMode, Inheritance);
2612 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2613 pExplicitAccess->grfAccessMode = AccessMode;
2614 pExplicitAccess->grfInheritance = Inheritance;
2616 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2617 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2618 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2619 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2620 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2623 /******************************************************************************
2624 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2626 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2627 LPWSTR pTrusteeName, DWORD AccessPermissions,
2628 ACCESS_MODE AccessMode, DWORD Inheritance )
2630 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2631 AccessPermissions, AccessMode, Inheritance);
2633 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2634 pExplicitAccess->grfAccessMode = AccessMode;
2635 pExplicitAccess->grfInheritance = Inheritance;
2637 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2638 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2639 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2640 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2641 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2644 /******************************************************************************
2645 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2647 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2648 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2649 LPSTR InheritedObjectTypeName, LPSTR Name )
2651 DWORD ObjectsPresent = 0;
2653 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2654 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2656 /* Fill the OBJECTS_AND_NAME structure */
2657 pObjName->ObjectType = ObjectType;
2658 if (ObjectTypeName != NULL)
2660 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2663 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2664 if (InheritedObjectTypeName != NULL)
2666 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2669 pObjName->ObjectsPresent = ObjectsPresent;
2670 pObjName->ptstrName = Name;
2672 /* Fill the TRUSTEE structure */
2673 pTrustee->pMultipleTrustee = NULL;
2674 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2675 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2676 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2677 pTrustee->ptstrName = (LPSTR)pObjName;
2680 /******************************************************************************
2681 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2683 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2684 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2685 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2687 DWORD ObjectsPresent = 0;
2689 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2690 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2692 /* Fill the OBJECTS_AND_NAME structure */
2693 pObjName->ObjectType = ObjectType;
2694 if (ObjectTypeName != NULL)
2696 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2699 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2700 if (InheritedObjectTypeName != NULL)
2702 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2705 pObjName->ObjectsPresent = ObjectsPresent;
2706 pObjName->ptstrName = Name;
2708 /* Fill the TRUSTEE structure */
2709 pTrustee->pMultipleTrustee = NULL;
2710 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2711 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2712 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2713 pTrustee->ptstrName = (LPWSTR)pObjName;
2716 /******************************************************************************
2717 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2719 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2720 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2722 DWORD ObjectsPresent = 0;
2724 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2726 /* Fill the OBJECTS_AND_SID structure */
2727 if (pObjectGuid != NULL)
2729 pObjSid->ObjectTypeGuid = *pObjectGuid;
2730 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2732 else
2734 ZeroMemory(&pObjSid->ObjectTypeGuid,
2735 sizeof(GUID));
2738 if (pInheritedObjectGuid != NULL)
2740 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2741 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2743 else
2745 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2746 sizeof(GUID));
2749 pObjSid->ObjectsPresent = ObjectsPresent;
2750 pObjSid->pSid = pSid;
2752 /* Fill the TRUSTEE structure */
2753 pTrustee->pMultipleTrustee = NULL;
2754 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2755 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2756 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2757 pTrustee->ptstrName = (LPSTR) pObjSid;
2760 /******************************************************************************
2761 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2763 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2764 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2766 DWORD ObjectsPresent = 0;
2768 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2770 /* Fill the OBJECTS_AND_SID structure */
2771 if (pObjectGuid != NULL)
2773 pObjSid->ObjectTypeGuid = *pObjectGuid;
2774 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2776 else
2778 ZeroMemory(&pObjSid->ObjectTypeGuid,
2779 sizeof(GUID));
2782 if (pInheritedObjectGuid != NULL)
2784 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2785 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2787 else
2789 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2790 sizeof(GUID));
2793 pObjSid->ObjectsPresent = ObjectsPresent;
2794 pObjSid->pSid = pSid;
2796 /* Fill the TRUSTEE structure */
2797 pTrustee->pMultipleTrustee = NULL;
2798 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2799 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2800 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2801 pTrustee->ptstrName = (LPWSTR) pObjSid;
2804 /******************************************************************************
2805 * BuildTrusteeWithSidA [ADVAPI32.@]
2807 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2809 TRACE("%p %p\n", pTrustee, pSid);
2811 pTrustee->pMultipleTrustee = NULL;
2812 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2813 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2814 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2815 pTrustee->ptstrName = (LPSTR) pSid;
2818 /******************************************************************************
2819 * BuildTrusteeWithSidW [ADVAPI32.@]
2821 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2823 TRACE("%p %p\n", pTrustee, pSid);
2825 pTrustee->pMultipleTrustee = NULL;
2826 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2827 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2828 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2829 pTrustee->ptstrName = (LPWSTR) pSid;
2832 /******************************************************************************
2833 * BuildTrusteeWithNameA [ADVAPI32.@]
2835 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2837 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2839 pTrustee->pMultipleTrustee = NULL;
2840 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2841 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2842 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2843 pTrustee->ptstrName = name;
2846 /******************************************************************************
2847 * BuildTrusteeWithNameW [ADVAPI32.@]
2849 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2851 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2853 pTrustee->pMultipleTrustee = NULL;
2854 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2855 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2856 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2857 pTrustee->ptstrName = name;
2860 /******************************************************************************
2861 * GetTrusteeFormA [ADVAPI32.@]
2863 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2865 TRACE("(%p)\n", pTrustee);
2867 if (!pTrustee)
2868 return TRUSTEE_BAD_FORM;
2870 return pTrustee->TrusteeForm;
2873 /******************************************************************************
2874 * GetTrusteeFormW [ADVAPI32.@]
2876 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2878 TRACE("(%p)\n", pTrustee);
2880 if (!pTrustee)
2881 return TRUSTEE_BAD_FORM;
2883 return pTrustee->TrusteeForm;
2886 /******************************************************************************
2887 * GetTrusteeNameA [ADVAPI32.@]
2889 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2891 TRACE("(%p)\n", pTrustee);
2893 if (!pTrustee)
2894 return NULL;
2896 return pTrustee->ptstrName;
2899 /******************************************************************************
2900 * GetTrusteeNameW [ADVAPI32.@]
2902 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2904 TRACE("(%p)\n", pTrustee);
2906 if (!pTrustee)
2907 return NULL;
2909 return pTrustee->ptstrName;
2912 /******************************************************************************
2913 * GetTrusteeTypeA [ADVAPI32.@]
2915 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2917 TRACE("(%p)\n", pTrustee);
2919 if (!pTrustee)
2920 return TRUSTEE_IS_UNKNOWN;
2922 return pTrustee->TrusteeType;
2925 /******************************************************************************
2926 * GetTrusteeTypeW [ADVAPI32.@]
2928 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
2930 TRACE("(%p)\n", pTrustee);
2932 if (!pTrustee)
2933 return TRUSTEE_IS_UNKNOWN;
2935 return pTrustee->TrusteeType;
2938 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2939 DWORD nAclInformationLength,
2940 ACL_INFORMATION_CLASS dwAclInformationClass )
2942 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
2943 nAclInformationLength, dwAclInformationClass);
2945 return TRUE;
2948 /******************************************************************************
2949 * SetEntriesInAclA [ADVAPI32.@]
2951 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2952 PACL OldAcl, PACL* NewAcl )
2954 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2955 *NewAcl = NULL;
2956 return ERROR_SUCCESS;
2959 /******************************************************************************
2960 * SetEntriesInAclW [ADVAPI32.@]
2962 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2963 PACL OldAcl, PACL* NewAcl )
2965 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2966 *NewAcl = NULL;
2967 return ERROR_SUCCESS;
2970 /******************************************************************************
2971 * SetNamedSecurityInfoA [ADVAPI32.@]
2973 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2974 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2975 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2977 DWORD len;
2978 LPWSTR wstr = NULL;
2979 DWORD r;
2981 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2982 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2984 if( pObjectName )
2986 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2987 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2988 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2991 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2992 psidGroup, pDacl, pSacl );
2994 HeapFree( GetProcessHeap(), 0, wstr );
2996 return r;
2999 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3000 PSECURITY_DESCRIPTOR ModificationDescriptor,
3001 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3002 PGENERIC_MAPPING GenericMapping,
3003 HANDLE Token )
3005 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3006 ObjectsSecurityDescriptor, GenericMapping, Token);
3008 return TRUE;
3011 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
3012 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
3013 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
3015 FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
3016 ControlBitsToSet);
3018 return TRUE;
3021 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3023 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3026 /******************************************************************************
3027 * AreAnyAccessesGranted [ADVAPI32.@]
3029 * Determines whether or not any of a set of specified access permissions have
3030 * been granted or not.
3032 * PARAMS
3033 * GrantedAccess [I] The permissions that have been granted.
3034 * DesiredAccess [I] The permissions that you want to have.
3036 * RETURNS
3037 * Nonzero if any of the permissions have been granted, zero if none of the
3038 * permissions have been granted.
3041 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3043 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3046 /******************************************************************************
3047 * SetNamedSecurityInfoW [ADVAPI32.@]
3049 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3050 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3051 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3053 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3054 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3055 return ERROR_SUCCESS;
3058 /******************************************************************************
3059 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3061 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3062 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3064 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3065 return ERROR_CALL_NOT_IMPLEMENTED;
3068 /******************************************************************************
3069 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3071 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3072 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3074 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3075 return ERROR_CALL_NOT_IMPLEMENTED;
3079 /******************************************************************************
3080 * ParseAclStringFlags
3082 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3084 DWORD flags = 0;
3085 LPCWSTR szAcl = *StringAcl;
3087 while (*szAcl != '(')
3089 if (*szAcl == 'P')
3091 flags |= SE_DACL_PROTECTED;
3093 else if (*szAcl == 'A')
3095 szAcl++;
3096 if (*szAcl == 'R')
3097 flags |= SE_DACL_AUTO_INHERIT_REQ;
3098 else if (*szAcl == 'I')
3099 flags |= SE_DACL_AUTO_INHERITED;
3101 szAcl++;
3104 *StringAcl = szAcl;
3105 return flags;
3108 /******************************************************************************
3109 * ParseAceStringType
3111 static const ACEFLAG AceType[] =
3113 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3114 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3115 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3116 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3118 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3119 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3120 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3121 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3123 { NULL, 0 },
3126 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3128 UINT len = 0;
3129 LPCWSTR szAcl = *StringAcl;
3130 const ACEFLAG *lpaf = AceType;
3132 while (lpaf->wstr &&
3133 (len = strlenW(lpaf->wstr)) &&
3134 strncmpW(lpaf->wstr, szAcl, len))
3135 lpaf++;
3137 if (!lpaf->wstr)
3138 return 0;
3140 *StringAcl += len;
3141 return lpaf->value;
3145 /******************************************************************************
3146 * ParseAceStringFlags
3148 static const ACEFLAG AceFlags[] =
3150 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3151 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3152 { SDDL_INHERITED, INHERITED_ACE },
3153 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3154 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3155 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3156 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3157 { NULL, 0 },
3160 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3162 UINT len = 0;
3163 BYTE flags = 0;
3164 LPCWSTR szAcl = *StringAcl;
3166 while (*szAcl != ';')
3168 const ACEFLAG *lpaf = AceFlags;
3170 while (lpaf->wstr &&
3171 (len = strlenW(lpaf->wstr)) &&
3172 strncmpW(lpaf->wstr, szAcl, len))
3173 lpaf++;
3175 if (!lpaf->wstr)
3176 return 0;
3178 flags |= lpaf->value;
3179 szAcl += len;
3182 *StringAcl = szAcl;
3183 return flags;
3187 /******************************************************************************
3188 * ParseAceStringRights
3190 static const ACEFLAG AceRights[] =
3192 { SDDL_GENERIC_ALL, GENERIC_ALL },
3193 { SDDL_GENERIC_READ, GENERIC_READ },
3194 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3195 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3197 { SDDL_READ_CONTROL, READ_CONTROL },
3198 { SDDL_STANDARD_DELETE, DELETE },
3199 { SDDL_WRITE_DAC, WRITE_DAC },
3200 { SDDL_WRITE_OWNER, WRITE_OWNER },
3202 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3203 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3204 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3205 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3206 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3207 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3208 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3209 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3210 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3212 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3213 { SDDL_FILE_READ, FILE_GENERIC_READ },
3214 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3215 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3217 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3218 { SDDL_KEY_READ, KEY_READ },
3219 { SDDL_KEY_WRITE, KEY_WRITE },
3220 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3221 { NULL, 0 },
3224 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3226 UINT len = 0;
3227 DWORD rights = 0;
3228 LPCWSTR szAcl = *StringAcl;
3230 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3232 LPCWSTR p = szAcl;
3234 while (*p && *p != ';')
3235 p++;
3237 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3239 rights = strtoulW(szAcl, NULL, 16);
3240 szAcl = p;
3242 else
3243 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3245 else
3247 while (*szAcl != ';')
3249 const ACEFLAG *lpaf = AceRights;
3251 while (lpaf->wstr &&
3252 (len = strlenW(lpaf->wstr)) &&
3253 strncmpW(lpaf->wstr, szAcl, len))
3255 lpaf++;
3258 if (!lpaf->wstr)
3259 return 0;
3261 rights |= lpaf->value;
3262 szAcl += len;
3266 *StringAcl = szAcl;
3267 return rights;
3271 /******************************************************************************
3272 * ParseStringAclToAcl
3274 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3276 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3277 PACL pAcl, LPDWORD cBytes)
3279 DWORD val;
3280 DWORD sidlen;
3281 DWORD length = sizeof(ACL);
3282 DWORD acesize = 0;
3283 DWORD acecount = 0;
3284 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3286 TRACE("%s\n", debugstr_w(StringAcl));
3288 if (!StringAcl)
3289 return FALSE;
3291 if (pAcl) /* pAce is only useful if we're setting values */
3292 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3294 /* Parse ACL flags */
3295 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3297 /* Parse ACE */
3298 while (*StringAcl == '(')
3300 StringAcl++;
3302 /* Parse ACE type */
3303 val = ParseAceStringType(&StringAcl);
3304 if (pAce)
3305 pAce->Header.AceType = (BYTE) val;
3306 if (*StringAcl != ';')
3307 goto lerr;
3308 StringAcl++;
3310 /* Parse ACE flags */
3311 val = ParseAceStringFlags(&StringAcl);
3312 if (pAce)
3313 pAce->Header.AceFlags = (BYTE) val;
3314 if (*StringAcl != ';')
3315 goto lerr;
3316 StringAcl++;
3318 /* Parse ACE rights */
3319 val = ParseAceStringRights(&StringAcl);
3320 if (pAce)
3321 pAce->Mask = val;
3322 if (*StringAcl != ';')
3323 goto lerr;
3324 StringAcl++;
3326 /* Parse ACE object guid */
3327 if (*StringAcl != ';')
3329 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3330 goto lerr;
3332 StringAcl++;
3334 /* Parse ACE inherit object guid */
3335 if (*StringAcl != ';')
3337 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3338 goto lerr;
3340 StringAcl++;
3342 /* Parse ACE account sid */
3343 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3345 while (*StringAcl && *StringAcl != ')')
3346 StringAcl++;
3349 if (*StringAcl != ')')
3350 goto lerr;
3351 StringAcl++;
3353 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3354 length += acesize;
3355 if (pAce)
3357 pAce->Header.AceSize = acesize;
3358 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3360 acecount++;
3363 *cBytes = length;
3365 if (length > 0xffff)
3367 ERR("ACL too large\n");
3368 goto lerr;
3371 if (pAcl)
3373 pAcl->AclRevision = ACL_REVISION;
3374 pAcl->Sbz1 = 0;
3375 pAcl->AclSize = length;
3376 pAcl->AceCount = acecount++;
3377 pAcl->Sbz2 = 0;
3379 return TRUE;
3381 lerr:
3382 WARN("Invalid ACE string format\n");
3383 return FALSE;
3387 /******************************************************************************
3388 * ParseStringSecurityDescriptorToSecurityDescriptor
3390 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3391 LPCWSTR StringSecurityDescriptor,
3392 SECURITY_DESCRIPTOR* SecurityDescriptor,
3393 LPDWORD cBytes)
3395 BOOL bret = FALSE;
3396 WCHAR toktype;
3397 WCHAR tok[MAX_PATH];
3398 LPCWSTR lptoken;
3399 LPBYTE lpNext = NULL;
3400 DWORD len;
3402 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3404 if (SecurityDescriptor)
3405 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3407 while (*StringSecurityDescriptor)
3409 toktype = *StringSecurityDescriptor;
3411 /* Expect char identifier followed by ':' */
3412 StringSecurityDescriptor++;
3413 if (*StringSecurityDescriptor != ':')
3415 SetLastError(ERROR_INVALID_PARAMETER);
3416 goto lend;
3418 StringSecurityDescriptor++;
3420 /* Extract token */
3421 lptoken = StringSecurityDescriptor;
3422 while (*lptoken && *lptoken != ':')
3423 lptoken++;
3425 if (*lptoken)
3426 lptoken--;
3428 len = lptoken - StringSecurityDescriptor;
3429 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3430 tok[len] = 0;
3432 switch (toktype)
3434 case 'O':
3436 DWORD bytes;
3438 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3439 goto lend;
3441 if (SecurityDescriptor)
3443 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3444 lpNext += bytes; /* Advance to next token */
3447 *cBytes += bytes;
3449 break;
3452 case 'G':
3454 DWORD bytes;
3456 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3457 goto lend;
3459 if (SecurityDescriptor)
3461 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3462 lpNext += bytes; /* Advance to next token */
3465 *cBytes += bytes;
3467 break;
3470 case 'D':
3472 DWORD flags;
3473 DWORD bytes;
3475 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3476 goto lend;
3478 if (SecurityDescriptor)
3480 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3481 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3482 lpNext += bytes; /* Advance to next token */
3485 *cBytes += bytes;
3487 break;
3490 case 'S':
3492 DWORD flags;
3493 DWORD bytes;
3495 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3496 goto lend;
3498 if (SecurityDescriptor)
3500 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3501 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3502 lpNext += bytes; /* Advance to next token */
3505 *cBytes += bytes;
3507 break;
3510 default:
3511 FIXME("Unknown token\n");
3512 SetLastError(ERROR_INVALID_PARAMETER);
3513 goto lend;
3516 StringSecurityDescriptor = lptoken;
3519 bret = TRUE;
3521 lend:
3522 return bret;
3525 /******************************************************************************
3526 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3528 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3529 LPCSTR StringSecurityDescriptor,
3530 DWORD StringSDRevision,
3531 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3532 PULONG SecurityDescriptorSize)
3534 UINT len;
3535 BOOL ret = FALSE;
3536 LPWSTR StringSecurityDescriptorW;
3538 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3539 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3541 if (StringSecurityDescriptorW)
3543 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3545 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3546 StringSDRevision, SecurityDescriptor,
3547 SecurityDescriptorSize);
3548 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3551 return ret;
3554 /******************************************************************************
3555 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3557 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3558 LPCWSTR StringSecurityDescriptor,
3559 DWORD StringSDRevision,
3560 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3561 PULONG SecurityDescriptorSize)
3563 DWORD cBytes;
3564 SECURITY_DESCRIPTOR* psd;
3565 BOOL bret = FALSE;
3567 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3569 if (GetVersion() & 0x80000000)
3571 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3572 goto lend;
3574 else if (StringSDRevision != SID_REVISION)
3576 SetLastError(ERROR_UNKNOWN_REVISION);
3577 goto lend;
3580 /* Compute security descriptor length */
3581 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3582 NULL, &cBytes))
3583 goto lend;
3585 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3586 GMEM_ZEROINIT, cBytes);
3587 if (!psd) goto lend;
3589 psd->Revision = SID_REVISION;
3590 psd->Control |= SE_SELF_RELATIVE;
3592 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3593 psd, &cBytes))
3595 LocalFree(psd);
3596 goto lend;
3599 if (SecurityDescriptorSize)
3600 *SecurityDescriptorSize = cBytes;
3602 bret = TRUE;
3604 lend:
3605 TRACE(" ret=%d\n", bret);
3606 return bret;
3609 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3611 if (cch == -1)
3612 cch = strlenW(string);
3614 if (plen)
3615 *plen += cch;
3617 if (pwptr)
3619 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3620 *pwptr += cch;
3624 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3626 DWORD i;
3627 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3628 WCHAR subauthfmt[] = { '-','%','u',0 };
3629 WCHAR buf[26];
3630 SID *pisid = psid;
3632 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3634 SetLastError(ERROR_INVALID_SID);
3635 return FALSE;
3638 if (pisid->IdentifierAuthority.Value[0] ||
3639 pisid->IdentifierAuthority.Value[1])
3641 FIXME("not matching MS' bugs\n");
3642 SetLastError(ERROR_INVALID_SID);
3643 return FALSE;
3646 sprintfW( buf, fmt, pisid->Revision,
3647 MAKELONG(
3648 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3649 pisid->IdentifierAuthority.Value[4] ),
3650 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3651 pisid->IdentifierAuthority.Value[2] )
3652 ) );
3653 DumpString(buf, -1, pwptr, plen);
3655 for( i=0; i<pisid->SubAuthorityCount; i++ )
3657 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3658 DumpString(buf, -1, pwptr, plen);
3660 return TRUE;
3663 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3665 int i;
3666 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3668 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3670 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3671 return TRUE;
3675 return DumpSidNumeric(psid, pwptr, plen);
3678 static const LPCWSTR AceRightBitNames[32] = {
3679 SDDL_CREATE_CHILD, /* 0 */
3680 SDDL_DELETE_CHILD,
3681 SDDL_LIST_CHILDREN,
3682 SDDL_SELF_WRITE,
3683 SDDL_READ_PROPERTY, /* 4 */
3684 SDDL_WRITE_PROPERTY,
3685 SDDL_DELETE_TREE,
3686 SDDL_LIST_OBJECT,
3687 SDDL_CONTROL_ACCESS, /* 8 */
3688 NULL,
3689 NULL,
3690 NULL,
3691 NULL, /* 12 */
3692 NULL,
3693 NULL,
3694 NULL,
3695 SDDL_STANDARD_DELETE, /* 16 */
3696 SDDL_READ_CONTROL,
3697 SDDL_WRITE_DAC,
3698 SDDL_WRITE_OWNER,
3699 NULL, /* 20 */
3700 NULL,
3701 NULL,
3702 NULL,
3703 NULL, /* 24 */
3704 NULL,
3705 NULL,
3706 NULL,
3707 SDDL_GENERIC_ALL, /* 28 */
3708 SDDL_GENERIC_EXECUTE,
3709 SDDL_GENERIC_WRITE,
3710 SDDL_GENERIC_READ
3713 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
3715 static const WCHAR fmtW[] = {'0','x','%','x',0};
3716 WCHAR buf[15];
3717 int i;
3719 if (mask == 0)
3720 return;
3722 /* first check if the right have name */
3723 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
3725 if (AceRights[i].wstr == NULL)
3726 break;
3727 if (mask == AceRights[i].value)
3729 DumpString(AceRights[i].wstr, -1, pwptr, plen);
3730 return;
3734 /* then check if it can be built from bit names */
3735 for (i = 0; i < 32; i++)
3737 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
3739 /* can't be built from bit names */
3740 sprintfW(buf, fmtW, mask);
3741 DumpString(buf, -1, pwptr, plen);
3742 return;
3746 /* build from bit names */
3747 for (i = 0; i < 32; i++)
3748 if (mask & (1 << i))
3749 DumpString(AceRightBitNames[i], -1, pwptr, plen);
3752 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
3754 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
3755 static const WCHAR openbr = '(';
3756 static const WCHAR closebr = ')';
3757 static const WCHAR semicolon = ';';
3759 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
3761 SetLastError(ERROR_INVALID_ACL);
3762 return FALSE;
3765 piace = (ACCESS_ALLOWED_ACE *)pace;
3766 DumpString(&openbr, 1, pwptr, plen);
3767 switch (piace->Header.AceType)
3769 case ACCESS_ALLOWED_ACE_TYPE:
3770 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
3771 break;
3772 case ACCESS_DENIED_ACE_TYPE:
3773 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
3774 break;
3775 case SYSTEM_AUDIT_ACE_TYPE:
3776 DumpString(SDDL_AUDIT, -1, pwptr, plen);
3777 break;
3778 case SYSTEM_ALARM_ACE_TYPE:
3779 DumpString(SDDL_ALARM, -1, pwptr, plen);
3780 break;
3782 DumpString(&semicolon, 1, pwptr, plen);
3784 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
3785 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
3786 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
3787 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
3788 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
3789 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
3790 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
3791 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
3792 if (piace->Header.AceFlags & INHERITED_ACE)
3793 DumpString(SDDL_INHERITED, -1, pwptr, plen);
3794 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
3795 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
3796 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
3797 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
3798 DumpString(&semicolon, 1, pwptr, plen);
3799 DumpRights(piace->Mask, pwptr, plen);
3800 DumpString(&semicolon, 1, pwptr, plen);
3801 /* objects not supported */
3802 DumpString(&semicolon, 1, pwptr, plen);
3803 /* objects not supported */
3804 DumpString(&semicolon, 1, pwptr, plen);
3805 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
3806 return FALSE;
3807 DumpString(&closebr, 1, pwptr, plen);
3808 return TRUE;
3811 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
3813 WORD count;
3814 int i;
3816 if (protected)
3817 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
3818 if (autoInheritReq)
3819 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3820 if (autoInherited)
3821 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3823 if (pacl == NULL)
3824 return TRUE;
3826 if (!IsValidAcl(pacl))
3827 return FALSE;
3829 count = pacl->AceCount;
3830 for (i = 0; i < count; i++)
3832 LPVOID ace;
3833 if (!GetAce(pacl, i, &ace))
3834 return FALSE;
3835 if (!DumpAce(ace, pwptr, plen))
3836 return FALSE;
3839 return TRUE;
3842 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3844 static const WCHAR prefix[] = {'O',':',0};
3845 BOOL bDefaulted;
3846 PSID psid;
3848 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3849 return FALSE;
3851 if (psid == NULL)
3852 return TRUE;
3854 DumpString(prefix, -1, pwptr, plen);
3855 if (!DumpSid(psid, pwptr, plen))
3856 return FALSE;
3857 return TRUE;
3860 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3862 static const WCHAR prefix[] = {'G',':',0};
3863 BOOL bDefaulted;
3864 PSID psid;
3866 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3867 return FALSE;
3869 if (psid == NULL)
3870 return TRUE;
3872 DumpString(prefix, -1, pwptr, plen);
3873 if (!DumpSid(psid, pwptr, plen))
3874 return FALSE;
3875 return TRUE;
3878 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3880 static const WCHAR dacl[] = {'D',':',0};
3881 SECURITY_DESCRIPTOR_CONTROL control;
3882 BOOL present, defaulted;
3883 DWORD revision;
3884 PACL pacl;
3886 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3887 return FALSE;
3889 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3890 return FALSE;
3892 if (!present)
3893 return TRUE;
3895 DumpString(dacl, 2, pwptr, plen);
3896 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3897 return FALSE;
3898 return TRUE;
3901 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3903 static const WCHAR sacl[] = {'S',':',0};
3904 SECURITY_DESCRIPTOR_CONTROL control;
3905 BOOL present, defaulted;
3906 DWORD revision;
3907 PACL pacl;
3909 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3910 return FALSE;
3912 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3913 return FALSE;
3915 if (!present)
3916 return TRUE;
3918 DumpString(sacl, 2, pwptr, plen);
3919 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3920 return FALSE;
3921 return TRUE;
3924 /******************************************************************************
3925 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3927 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, ULONG *OutputLen)
3929 ULONG len;
3930 WCHAR *wptr, *wstr;
3932 if (SDRevision != SDDL_REVISION_1)
3934 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
3935 SetLastError(ERROR_UNKNOWN_REVISION);
3936 return FALSE;
3939 len = 0;
3940 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3941 if (!DumpOwner(SecurityDescriptor, NULL, &len))
3942 return FALSE;
3943 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3944 if (!DumpGroup(SecurityDescriptor, NULL, &len))
3945 return FALSE;
3946 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3947 if (!DumpDacl(SecurityDescriptor, NULL, &len))
3948 return FALSE;
3949 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3950 if (!DumpSacl(SecurityDescriptor, NULL, &len))
3951 return FALSE;
3953 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
3954 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3955 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
3956 return FALSE;
3957 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3958 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
3959 return FALSE;
3960 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3961 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
3962 return FALSE;
3963 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3964 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
3965 return FALSE;
3966 *wptr = 0;
3968 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
3969 *OutputString = wstr;
3970 if (OutputLen)
3971 *OutputLen = strlenW(*OutputString)+1;
3972 return TRUE;
3975 /******************************************************************************
3976 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3978 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, ULONG *OutputLen)
3980 LPWSTR wstr;
3981 ULONG len;
3982 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
3984 int lenA;
3986 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
3987 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
3988 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
3989 LocalFree(wstr);
3991 if (OutputLen != NULL)
3992 *OutputLen = lenA;
3993 return TRUE;
3995 else
3997 *OutputString = NULL;
3998 if (OutputLen)
3999 *OutputLen = 0;
4000 return FALSE;
4004 /******************************************************************************
4005 * ConvertStringSidToSidW [ADVAPI32.@]
4007 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4009 BOOL bret = FALSE;
4010 DWORD cBytes;
4012 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4013 if (GetVersion() & 0x80000000)
4014 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4015 else if (!StringSid || !Sid)
4016 SetLastError(ERROR_INVALID_PARAMETER);
4017 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4019 PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
4021 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4022 if (!bret)
4023 LocalFree(*Sid);
4025 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4026 return bret;
4029 /******************************************************************************
4030 * ConvertStringSidToSidA [ADVAPI32.@]
4032 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4034 BOOL bret = FALSE;
4036 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4037 if (GetVersion() & 0x80000000)
4038 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4039 else if (!StringSid || !Sid)
4040 SetLastError(ERROR_INVALID_PARAMETER);
4041 else
4043 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4044 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4045 len * sizeof(WCHAR));
4047 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4048 bret = ConvertStringSidToSidW(wStringSid, Sid);
4049 HeapFree(GetProcessHeap(), 0, wStringSid);
4051 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4052 return bret;
4055 /******************************************************************************
4056 * ConvertSidToStringSidW [ADVAPI32.@]
4058 * format of SID string is:
4059 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4060 * where
4061 * <rev> is the revision of the SID encoded as decimal
4062 * <auth> is the identifier authority encoded as hex
4063 * <subauthN> is the subauthority id encoded as decimal
4065 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4067 DWORD len = 0;
4068 LPWSTR wstr, wptr;
4070 TRACE("%p %p\n", pSid, pstr );
4072 len = 0;
4073 if (!DumpSidNumeric(pSid, NULL, &len))
4074 return FALSE;
4075 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4076 DumpSidNumeric(pSid, &wptr, NULL);
4077 *wptr = 0;
4079 *pstr = wstr;
4080 return TRUE;
4083 /******************************************************************************
4084 * ConvertSidToStringSidA [ADVAPI32.@]
4086 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4088 LPWSTR wstr = NULL;
4089 LPSTR str;
4090 UINT len;
4092 TRACE("%p %p\n", pSid, pstr );
4094 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4095 return FALSE;
4097 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4098 str = LocalAlloc( 0, len );
4099 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4100 LocalFree( wstr );
4102 *pstr = str;
4104 return TRUE;
4107 BOOL WINAPI CreatePrivateObjectSecurity(
4108 PSECURITY_DESCRIPTOR ParentDescriptor,
4109 PSECURITY_DESCRIPTOR CreatorDescriptor,
4110 PSECURITY_DESCRIPTOR* NewDescriptor,
4111 BOOL IsDirectoryObject,
4112 HANDLE Token,
4113 PGENERIC_MAPPING GenericMapping )
4115 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4116 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4118 return FALSE;
4121 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4123 FIXME("%p - stub\n", ObjectDescriptor);
4125 return TRUE;
4128 BOOL WINAPI CreateProcessAsUserA(
4129 HANDLE hToken,
4130 LPCSTR lpApplicationName,
4131 LPSTR lpCommandLine,
4132 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4133 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4134 BOOL bInheritHandles,
4135 DWORD dwCreationFlags,
4136 LPVOID lpEnvironment,
4137 LPCSTR lpCurrentDirectory,
4138 LPSTARTUPINFOA lpStartupInfo,
4139 LPPROCESS_INFORMATION lpProcessInformation )
4141 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4142 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4143 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4145 return FALSE;
4148 BOOL WINAPI CreateProcessAsUserW(
4149 HANDLE hToken,
4150 LPCWSTR lpApplicationName,
4151 LPWSTR lpCommandLine,
4152 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4153 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4154 BOOL bInheritHandles,
4155 DWORD dwCreationFlags,
4156 LPVOID lpEnvironment,
4157 LPCWSTR lpCurrentDirectory,
4158 LPSTARTUPINFOW lpStartupInfo,
4159 LPPROCESS_INFORMATION lpProcessInformation )
4161 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4162 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4163 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4164 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4166 /* We should create the process with a suspended main thread */
4167 if (!CreateProcessW (lpApplicationName,
4168 lpCommandLine,
4169 lpProcessAttributes,
4170 lpThreadAttributes,
4171 bInheritHandles,
4172 dwCreationFlags, /* CREATE_SUSPENDED */
4173 lpEnvironment,
4174 lpCurrentDirectory,
4175 lpStartupInfo,
4176 lpProcessInformation))
4178 return FALSE;
4181 return TRUE;
4184 /******************************************************************************
4185 * DuplicateTokenEx [ADVAPI32.@]
4187 BOOL WINAPI DuplicateTokenEx(
4188 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4189 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4190 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4191 TOKEN_TYPE TokenType,
4192 PHANDLE DuplicateTokenHandle )
4194 OBJECT_ATTRIBUTES ObjectAttributes;
4196 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4197 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4199 InitializeObjectAttributes(
4200 &ObjectAttributes,
4201 NULL,
4202 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4203 NULL,
4204 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4206 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4207 dwDesiredAccess,
4208 &ObjectAttributes,
4209 ImpersonationLevel,
4210 TokenType,
4211 DuplicateTokenHandle ) );
4214 BOOL WINAPI DuplicateToken(
4215 HANDLE ExistingTokenHandle,
4216 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4217 PHANDLE DuplicateTokenHandle )
4219 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4220 NULL, ImpersonationLevel, TokenImpersonation,
4221 DuplicateTokenHandle );
4224 BOOL WINAPI EnumDependentServicesA(
4225 SC_HANDLE hService,
4226 DWORD dwServiceState,
4227 LPENUM_SERVICE_STATUSA lpServices,
4228 DWORD cbBufSize,
4229 LPDWORD pcbBytesNeeded,
4230 LPDWORD lpServicesReturned )
4232 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4233 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4235 return FALSE;
4238 BOOL WINAPI EnumDependentServicesW(
4239 SC_HANDLE hService,
4240 DWORD dwServiceState,
4241 LPENUM_SERVICE_STATUSW lpServices,
4242 DWORD cbBufSize,
4243 LPDWORD pcbBytesNeeded,
4244 LPDWORD lpServicesReturned )
4246 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4247 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4249 return FALSE;
4252 /******************************************************************************
4253 * ComputeStringSidSize
4255 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4257 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4259 int ctok = 0;
4260 while (*StringSid)
4262 if (*StringSid == '-')
4263 ctok++;
4264 StringSid++;
4267 if (ctok >= 3)
4268 return GetSidLengthRequired(ctok - 2);
4270 else /* String constant format - Only available in winxp and above */
4272 unsigned int i;
4274 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4275 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4276 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4279 return GetSidLengthRequired(0);
4282 /******************************************************************************
4283 * ParseStringSidToSid
4285 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4287 BOOL bret = FALSE;
4288 SID* pisid=pSid;
4290 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4291 if (!StringSid)
4293 SetLastError(ERROR_INVALID_PARAMETER);
4294 TRACE("StringSid is NULL, returning FALSE\n");
4295 return FALSE;
4298 *cBytes = ComputeStringSidSize(StringSid);
4299 if (!pisid) /* Simply compute the size */
4301 TRACE("only size requested, returning TRUE\n");
4302 return TRUE;
4305 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4307 DWORD i = 0, identAuth;
4308 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4310 StringSid += 2; /* Advance to Revision */
4311 pisid->Revision = atoiW(StringSid);
4313 if (pisid->Revision != SDDL_REVISION)
4315 TRACE("Revision %d is unknown\n", pisid->Revision);
4316 goto lend; /* ERROR_INVALID_SID */
4318 if (csubauth == 0)
4320 TRACE("SubAuthorityCount is 0\n");
4321 goto lend; /* ERROR_INVALID_SID */
4324 pisid->SubAuthorityCount = csubauth;
4326 /* Advance to identifier authority */
4327 while (*StringSid && *StringSid != '-')
4328 StringSid++;
4329 if (*StringSid == '-')
4330 StringSid++;
4332 /* MS' implementation can't handle values greater than 2^32 - 1, so
4333 * we don't either; assume most significant bytes are always 0
4335 pisid->IdentifierAuthority.Value[0] = 0;
4336 pisid->IdentifierAuthority.Value[1] = 0;
4337 identAuth = atoiW(StringSid);
4338 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4339 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4340 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4341 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4343 /* Advance to first sub authority */
4344 while (*StringSid && *StringSid != '-')
4345 StringSid++;
4346 if (*StringSid == '-')
4347 StringSid++;
4349 while (*StringSid)
4351 pisid->SubAuthority[i++] = atoiW(StringSid);
4353 while (*StringSid && *StringSid != '-')
4354 StringSid++;
4355 if (*StringSid == '-')
4356 StringSid++;
4359 if (i != pisid->SubAuthorityCount)
4360 goto lend; /* ERROR_INVALID_SID */
4362 bret = TRUE;
4364 else /* String constant format - Only available in winxp and above */
4366 unsigned int i;
4367 pisid->Revision = SDDL_REVISION;
4369 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4370 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4372 DWORD j;
4373 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4374 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4375 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4376 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4377 bret = TRUE;
4380 if (!bret)
4381 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4384 lend:
4385 if (!bret)
4386 SetLastError(ERROR_INVALID_SID);
4388 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4389 return bret;
4392 /******************************************************************************
4393 * GetNamedSecurityInfoA [ADVAPI32.@]
4395 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4396 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4397 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4398 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4400 DWORD len;
4401 LPWSTR wstr = NULL;
4402 DWORD r;
4404 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4405 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4407 if( pObjectName )
4409 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4410 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4411 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4414 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4415 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4417 HeapFree( GetProcessHeap(), 0, wstr );
4419 return r;
4422 /******************************************************************************
4423 * GetNamedSecurityInfoW [ADVAPI32.@]
4425 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4426 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4427 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4429 DWORD needed, offset;
4430 SECURITY_DESCRIPTOR_RELATIVE *relative;
4431 BYTE *buffer;
4433 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4434 group, dacl, sacl, descriptor );
4436 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4438 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4439 if (info & OWNER_SECURITY_INFORMATION)
4440 needed += sizeof(sidWorld);
4441 if (info & GROUP_SECURITY_INFORMATION)
4442 needed += sizeof(sidWorld);
4443 if (info & DACL_SECURITY_INFORMATION)
4444 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4445 if (info & SACL_SECURITY_INFORMATION)
4446 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4448 /* must be freed by caller */
4449 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4450 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4452 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4454 HeapFree( GetProcessHeap(), 0, *descriptor );
4455 return ERROR_INVALID_SECURITY_DESCR;
4458 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4459 relative->Control |= SE_SELF_RELATIVE;
4460 buffer = (BYTE *)relative;
4461 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4463 if (info & OWNER_SECURITY_INFORMATION)
4465 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4466 relative->Owner = offset;
4467 if (owner)
4468 *owner = buffer + offset;
4469 offset += sizeof(sidWorld);
4471 if (info & GROUP_SECURITY_INFORMATION)
4473 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4474 relative->Group = offset;
4475 if (group)
4476 *group = buffer + offset;
4477 offset += sizeof(sidWorld);
4479 if (info & DACL_SECURITY_INFORMATION)
4481 relative->Control |= SE_DACL_PRESENT;
4482 GetWorldAccessACL( (PACL)(buffer + offset) );
4483 relative->Dacl = offset;
4484 if (dacl)
4485 *dacl = (PACL)(buffer + offset);
4486 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4488 if (info & SACL_SECURITY_INFORMATION)
4490 relative->Control |= SE_SACL_PRESENT;
4491 GetWorldAccessACL( (PACL)(buffer + offset) );
4492 relative->Sacl = offset;
4493 if (sacl)
4494 *sacl = (PACL)(buffer + offset);
4496 return ERROR_SUCCESS;
4499 /******************************************************************************
4500 * DecryptFileW [ADVAPI32.@]
4502 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4504 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4505 return TRUE;
4508 /******************************************************************************
4509 * DecryptFileA [ADVAPI32.@]
4511 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4513 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4514 return TRUE;
4517 /******************************************************************************
4518 * EncryptFileW [ADVAPI32.@]
4520 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4522 FIXME("%s\n", debugstr_w(lpFileName));
4523 return TRUE;
4526 /******************************************************************************
4527 * EncryptFileA [ADVAPI32.@]
4529 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4531 FIXME("%s\n", debugstr_a(lpFileName));
4532 return TRUE;
4535 /******************************************************************************
4536 * FileEncryptionStatusW [ADVAPI32.@]
4538 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4540 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4541 if (!lpStatus)
4542 return FALSE;
4543 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4544 return TRUE;
4547 /******************************************************************************
4548 * FileEncryptionStatusA [ADVAPI32.@]
4550 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4552 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4553 if (!lpStatus)
4554 return FALSE;
4555 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4556 return TRUE;
4559 /******************************************************************************
4560 * SetSecurityInfo [ADVAPI32.@]
4562 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4563 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4564 PSID psidGroup, PACL pDacl, PACL pSacl) {
4565 FIXME("stub\n");
4566 return ERROR_SUCCESS;