wininet: Send notifications from InternetWriteFile.
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  * Copyright 2006 Robert Reif
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
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 "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
43
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
51     PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56     LPCWSTR StringSecurityDescriptor,
57     SECURITY_DESCRIPTOR* SecurityDescriptor,
58     LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
60
61 typedef struct _ACEFLAG
62 {
63    LPCWSTR wstr;
64    DWORD value;
65 } ACEFLAG, *LPACEFLAG;
66
67 typedef struct _MAX_SID
68 {
69     /* same fields as struct _SID */
70     BYTE Revision;
71     BYTE SubAuthorityCount;
72     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
75
76 typedef struct WELLKNOWNSID
77 {
78     WCHAR wstr[2];
79     WELL_KNOWN_SID_TYPE Type;
80     MAX_SID Sid;
81 } WELLKNOWNSID;
82
83 static const WELLKNOWNSID WellKnownSids[] =
84 {
85     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
128     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133     { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134     { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135     { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136     { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
137 };
138
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
141 {
142     WELL_KNOWN_SID_TYPE Type;
143     DWORD Rid;
144 } WELLKNOWNRID;
145
146 static const WELLKNOWNRID WellKnownRids[] = {
147     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
148     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
149     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
150     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
151     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
152     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
153     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
154     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
155     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
156     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
159     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
160 };
161
162
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
164
165 typedef struct _AccountSid {
166     WELL_KNOWN_SID_TYPE type;
167     LPCWSTR account;
168     LPCWSTR domain;
169     SID_NAME_USE name_use;
170     LPCWSTR alias;
171 } AccountSid;
172
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 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 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 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 };
187 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
188 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 };
189 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
190 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
191 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
192 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
193 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
194 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
195 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
196 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 };
197 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
198 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 };
199 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
200 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
201 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
202 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
203 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
205 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
206 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 };
207 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
208 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
209 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
210 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
211 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
212 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
213 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
214 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 };
215 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 };
216 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
217 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 };
218 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
219 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
220 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
221 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 };
222 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 };
223 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
224 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
225 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 };
226 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
227 static const WCHAR SELF[] = { 'S','E','L','F',0 };
228 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
229 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
230 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
231 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 };
232 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
233 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
234
235 static const AccountSid ACCOUNT_SIDS[] = {
236     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
237     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
238     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
239     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
240     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
241     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
242     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
243     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
244     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
245     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
246     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
247     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
248     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
249     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
251     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
252     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
253     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
254     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
255     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
256     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
257     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
258     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
259     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
260     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
261     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
262     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
263     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
264     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
265     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
266     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
267     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
268     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
269     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
270     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
271     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
272     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
273     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
274     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
277     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
279     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
280 };
281 /*
282  * ACE access rights
283  */
284 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
285 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
286 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
287 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
288
289 static const WCHAR SDDL_READ_PROPERTY[]    = {'R','P',0};
290 static const WCHAR SDDL_WRITE_PROPERTY[]   = {'W','P',0};
291 static const WCHAR SDDL_CREATE_CHILD[]     = {'C','C',0};
292 static const WCHAR SDDL_DELETE_CHILD[]     = {'D','C',0};
293 static const WCHAR SDDL_LIST_CHILDREN[]    = {'L','C',0};
294 static const WCHAR SDDL_SELF_WRITE[]       = {'S','W',0};
295 static const WCHAR SDDL_LIST_OBJECT[]      = {'L','O',0};
296 static const WCHAR SDDL_DELETE_TREE[]      = {'D','T',0};
297 static const WCHAR SDDL_CONTROL_ACCESS[]   = {'C','R',0};
298
299 static const WCHAR SDDL_FILE_ALL[]         = {'F','A',0};
300 static const WCHAR SDDL_FILE_READ[]        = {'F','R',0};
301 static const WCHAR SDDL_FILE_WRITE[]       = {'F','W',0};
302 static const WCHAR SDDL_FILE_EXECUTE[]     = {'F','X',0};
303
304 static const WCHAR SDDL_KEY_ALL[]          = {'K','A',0};
305 static const WCHAR SDDL_KEY_READ[]         = {'K','R',0};
306 static const WCHAR SDDL_KEY_WRITE[]        = {'K','W',0};
307 static const WCHAR SDDL_KEY_EXECUTE[]      = {'K','X',0};
308
309 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
310 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
311 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
312 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
313
314 /*
315  * ACL flags
316  */
317 static const WCHAR SDDL_PROTECTED[]             = {'P',0};
318 static const WCHAR SDDL_AUTO_INHERIT_REQ[]      = {'A','R',0};
319 static const WCHAR SDDL_AUTO_INHERITED[]        = {'A','I',0};
320
321 /*
322  * ACE types
323  */
324 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
325 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
326 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
328 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
329 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
330 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
331 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
332
333 /*
334  * ACE flags
335  */
336 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
337 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
338 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
339 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
340 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
341 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
342 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
343
344 const char * debugstr_sid(PSID sid)
345 {
346     int auth = 0;
347     SID * psid = sid;
348
349     if (psid == NULL)
350         return "(null)";
351
352     auth = psid->IdentifierAuthority.Value[5] +
353            (psid->IdentifierAuthority.Value[4] << 8) +
354            (psid->IdentifierAuthority.Value[3] << 16) +
355            (psid->IdentifierAuthority.Value[2] << 24);
356
357     switch (psid->SubAuthorityCount) {
358     case 0:
359         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
360     case 1:
361         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
362             psid->SubAuthority[0]);
363     case 2:
364         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
365             psid->SubAuthority[0], psid->SubAuthority[1]);
366     case 3:
367         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
368             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
369     case 4:
370         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
371             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372             psid->SubAuthority[3]);
373     case 5:
374         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
375             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376             psid->SubAuthority[3], psid->SubAuthority[4]);
377     case 6:
378         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
380             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
381     case 7:
382         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
383             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
384             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
385             psid->SubAuthority[6]);
386     case 8:
387         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
388             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
389             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
390             psid->SubAuthority[6], psid->SubAuthority[7]);
391     }
392     return "(too-big)";
393 }
394
395 /* set last error code from NT status and get the proper boolean return value */
396 /* used for functions that are a simple wrapper around the corresponding ntdll API */
397 static inline BOOL set_ntstatus( NTSTATUS status )
398 {
399     if (status) SetLastError( RtlNtStatusToDosError( status ));
400     return !status;
401 }
402
403 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
404
405 static void GetWorldAccessACL(PACL pACL)
406 {
407     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
408
409     pACL->AclRevision = ACL_REVISION;
410     pACL->Sbz1 = 0;
411     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
412     pACL->AceCount = 1;
413     pACL->Sbz2 = 0;
414
415     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
416     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
417     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
418     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
419     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
420 }
421
422 /************************************************************
423  *                ADVAPI_IsLocalComputer
424  *
425  * Checks whether the server name indicates local machine.
426  */
427 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
428 {
429     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
430     BOOL Result;
431     LPWSTR buf;
432
433     if (!ServerName || !ServerName[0])
434         return TRUE;
435
436     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
437     Result = GetComputerNameW(buf,  &dwSize);
438     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
439         ServerName += 2;
440     Result = Result && !lstrcmpW(ServerName, buf);
441     HeapFree(GetProcessHeap(), 0, buf);
442
443     return Result;
444 }
445
446 /************************************************************
447  *                ADVAPI_GetComputerSid
448  *
449  * Reads the computer SID from the registry.
450  */
451 BOOL ADVAPI_GetComputerSid(PSID sid)
452 {
453     HKEY key;
454     LONG ret;
455     BOOL retval = FALSE;
456     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 };
457     static const WCHAR V[] = { 'V',0 };
458
459     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
460         KEY_READ, &key)) == ERROR_SUCCESS)
461     {
462         DWORD size = 0;
463         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
464         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
465         {
466             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
467             if (data)
468             {
469                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
470                      data, &size)) == ERROR_SUCCESS)
471                 {
472                     /* the SID is in the last 24 bytes of the binary data */
473                     CopyMemory(sid, &data[size-24], 24);
474                     retval = TRUE;
475                 }
476                 HeapFree(GetProcessHeap(), 0, data);
477             }
478         }
479         RegCloseKey(key);
480     }
481
482     if(retval == TRUE) return retval;
483
484     /* create a new random SID */
485     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
486         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
487     {
488         PSID new_sid;
489         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
490         DWORD id[3];
491
492         if (RtlGenRandom(id, sizeof(id)))
493         {
494             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
495             {
496                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
497                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
498
499                 FreeSid(new_sid);
500             }
501         }
502         RegCloseKey(key);
503     }
504
505     return retval;
506 }
507
508 /*      ##############################
509         ######  TOKEN FUNCTIONS ######
510         ##############################
511 */
512
513 /******************************************************************************
514  * OpenProcessToken                     [ADVAPI32.@]
515  * Opens the access token associated with a process handle.
516  *
517  * PARAMS
518  *   ProcessHandle [I] Handle to process
519  *   DesiredAccess [I] Desired access to process
520  *   TokenHandle   [O] Pointer to handle of open access token
521  *
522  * RETURNS
523  *  Success: TRUE. TokenHandle contains the access token.
524  *  Failure: FALSE.
525  *
526  * NOTES
527  *  See NtOpenProcessToken.
528  */
529 BOOL WINAPI
530 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
531                   HANDLE *TokenHandle )
532 {
533         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
534 }
535
536 /******************************************************************************
537  * OpenThreadToken [ADVAPI32.@]
538  *
539  * Opens the access token associated with a thread handle.
540  *
541  * PARAMS
542  *   ThreadHandle  [I] Handle to process
543  *   DesiredAccess [I] Desired access to the thread
544  *   OpenAsSelf    [I] ???
545  *   TokenHandle   [O] Destination for the token handle
546  *
547  * RETURNS
548  *  Success: TRUE. TokenHandle contains the access token.
549  *  Failure: FALSE.
550  *
551  * NOTES
552  *  See NtOpenThreadToken.
553  */
554 BOOL WINAPI
555 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
556                  BOOL OpenAsSelf, HANDLE *TokenHandle)
557 {
558         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
559 }
560
561 BOOL WINAPI
562 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
563                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
564 {
565     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
566                                              PreviousState, ReturnLength));
567 }
568
569 /******************************************************************************
570  * AdjustTokenPrivileges [ADVAPI32.@]
571  *
572  * Adjust the privileges of an open token handle.
573  * 
574  * PARAMS
575  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
576  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
577  *  NewState             [I]   Desired new privileges of the token
578  *  BufferLength         [I]   Length of NewState
579  *  PreviousState        [O]   Destination for the previous state
580  *  ReturnLength         [I/O] Size of PreviousState
581  *
582  *
583  * RETURNS
584  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
585  *  Failure: FALSE.
586  *
587  * NOTES
588  *  See NtAdjustPrivilegesToken.
589  */
590 BOOL WINAPI
591 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
592                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
593                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
594 {
595     NTSTATUS status;
596
597     TRACE("\n");
598     
599     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
600                                                      NewState, BufferLength, PreviousState,
601                                                      ReturnLength);
602     SetLastError( RtlNtStatusToDosError( status ));
603     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
604         return TRUE;
605     else
606         return FALSE;
607 }
608
609 /******************************************************************************
610  * CheckTokenMembership [ADVAPI32.@]
611  *
612  * Determine if an access token is a member of a SID.
613  * 
614  * PARAMS
615  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
616  *   SidToCheck  [I] SID that possibly contains the token
617  *   IsMember    [O] Destination for result.
618  *
619  * RETURNS
620  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
621  *  Failure: FALSE.
622  */
623 BOOL WINAPI
624 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
625                       PBOOL IsMember )
626 {
627   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
628
629   *IsMember = TRUE;
630   return(TRUE);
631 }
632
633 /******************************************************************************
634  * GetTokenInformation [ADVAPI32.@]
635  *
636  * Get a type of information about an access token.
637  *
638  * PARAMS
639  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
640  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
641  *   tokeninfo       [O] Destination for token information
642  *   tokeninfolength [I] Length of tokeninfo
643  *   retlen          [O] Destination for returned token information length
644  *
645  * RETURNS
646  *  Success: TRUE. tokeninfo contains retlen bytes of token information
647  *  Failure: FALSE.
648  *
649  * NOTES
650  *  See NtQueryInformationToken.
651  */
652 BOOL WINAPI
653 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
654                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
655 {
656     TRACE("(%p, %s, %p, %d, %p):\n",
657           token,
658           (tokeninfoclass == TokenUser) ? "TokenUser" :
659           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
660           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
661           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
662           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
663           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
664           (tokeninfoclass == TokenSource) ? "TokenSource" :
665           (tokeninfoclass == TokenType) ? "TokenType" :
666           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
667           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
668           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
669           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
670           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
671           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
672           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
673           "Unknown",
674           tokeninfo, tokeninfolength, retlen);
675     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
676                                                   tokeninfolength, retlen));
677 }
678
679 /******************************************************************************
680  * SetTokenInformation [ADVAPI32.@]
681  *
682  * Set information for an access token.
683  *
684  * PARAMS
685  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
686  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
687  *   tokeninfo       [I] Token information to set
688  *   tokeninfolength [I] Length of tokeninfo
689  *
690  * RETURNS
691  *  Success: TRUE. The information for the token is set to tokeninfo.
692  *  Failure: FALSE.
693  */
694 BOOL WINAPI
695 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
696                      LPVOID tokeninfo, DWORD tokeninfolength )
697 {
698     TRACE("(%p, %s, %p, %d): stub\n",
699           token,
700           (tokeninfoclass == TokenUser) ? "TokenUser" :
701           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
702           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
703           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
704           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
705           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
706           (tokeninfoclass == TokenSource) ? "TokenSource" :
707           (tokeninfoclass == TokenType) ? "TokenType" :
708           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
709           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
710           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
711           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
712           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
713           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
714           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
715           "Unknown",
716           tokeninfo, tokeninfolength);
717
718     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
719 }
720
721 /*************************************************************************
722  * SetThreadToken [ADVAPI32.@]
723  *
724  * Assigns an 'impersonation token' to a thread so it can assume the
725  * security privileges of another thread or process.  Can also remove
726  * a previously assigned token. 
727  *
728  * PARAMS
729  *   thread          [O] Handle to thread to set the token for
730  *   token           [I] Token to set
731  *
732  * RETURNS
733  *  Success: TRUE. The threads access token is set to token
734  *  Failure: FALSE.
735  *
736  * NOTES
737  *  Only supported on NT or higher. On Win9X this function does nothing.
738  *  See SetTokenInformation.
739  */
740 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
741 {
742     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
743                                                  ThreadImpersonationToken, &token, sizeof token ));
744 }
745
746 /*************************************************************************
747  * CreateRestrictedToken [ADVAPI32.@]
748  *
749  * Create a new more restricted token from an existing token.
750  *
751  * PARAMS
752  *   baseToken       [I] Token to base the new restricted token on
753  *   flags           [I] Options
754  *   nDisableSids    [I] Length of disableSids array
755  *   disableSids     [I] Array of SIDs to disable in the new token
756  *   nDeletePrivs    [I] Length of deletePrivs array
757  *   deletePrivs     [I] Array of privileges to delete in the new token
758  *   nRestrictSids   [I] Length of restrictSids array
759  *   restrictSids    [I] Array of SIDs to restrict in the new token
760  *   newToken        [O] Address where the new token is stored
761  *
762  * RETURNS
763  *  Success: TRUE
764  *  Failure: FALSE
765  */
766 BOOL WINAPI CreateRestrictedToken(
767     HANDLE baseToken,
768     DWORD flags,
769     DWORD nDisableSids,
770     PSID_AND_ATTRIBUTES disableSids,
771     DWORD nDeletePrivs,
772     PLUID_AND_ATTRIBUTES deletePrivs,
773     DWORD nRestrictSids,
774     PSID_AND_ATTRIBUTES restrictSids,
775     PHANDLE newToken)
776 {
777     FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
778           baseToken, flags, nDisableSids, disableSids,
779           nDeletePrivs, deletePrivs,
780           nRestrictSids, restrictSids,
781           newToken);
782     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
783     return FALSE;
784 }
785
786 /*      ##############################
787         ######  SID FUNCTIONS   ######
788         ##############################
789 */
790
791 /******************************************************************************
792  * AllocateAndInitializeSid [ADVAPI32.@]
793  *
794  * PARAMS
795  *   pIdentifierAuthority []
796  *   nSubAuthorityCount   []
797  *   nSubAuthority0       []
798  *   nSubAuthority1       []
799  *   nSubAuthority2       []
800  *   nSubAuthority3       []
801  *   nSubAuthority4       []
802  *   nSubAuthority5       []
803  *   nSubAuthority6       []
804  *   nSubAuthority7       []
805  *   pSid                 []
806  */
807 BOOL WINAPI
808 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
809                           BYTE nSubAuthorityCount,
810                           DWORD nSubAuthority0, DWORD nSubAuthority1,
811                           DWORD nSubAuthority2, DWORD nSubAuthority3,
812                           DWORD nSubAuthority4, DWORD nSubAuthority5,
813                           DWORD nSubAuthority6, DWORD nSubAuthority7,
814                           PSID *pSid )
815 {
816     return set_ntstatus( RtlAllocateAndInitializeSid(
817                              pIdentifierAuthority, nSubAuthorityCount,
818                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
819                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
820                              pSid ));
821 }
822
823 /******************************************************************************
824  * FreeSid [ADVAPI32.@]
825  *
826  * PARAMS
827  *   pSid []
828  */
829 PVOID WINAPI
830 FreeSid( PSID pSid )
831 {
832         RtlFreeSid(pSid);
833         return NULL; /* is documented like this */
834 }
835
836 /******************************************************************************
837  * CopySid [ADVAPI32.@]
838  *
839  * PARAMS
840  *   nDestinationSidLength []
841  *   pDestinationSid       []
842  *   pSourceSid            []
843  */
844 BOOL WINAPI
845 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
846 {
847         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
848 }
849
850 /******************************************************************************
851  * CreateWellKnownSid [ADVAPI32.@]
852  */
853 BOOL WINAPI
854 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
855                     PSID DomainSid,
856                     PSID pSid,
857                     DWORD* cbSid)
858 {
859     unsigned int i;
860     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
861
862     if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
863         SetLastError(ERROR_INVALID_PARAMETER);
864         return FALSE;
865     }
866
867     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
868         if (WellKnownSids[i].Type == WellKnownSidType) {
869             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
870
871             if (*cbSid < length) {
872                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
873                 return FALSE;
874             }
875
876             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
877             *cbSid = length;
878             return TRUE;
879         }
880     }
881
882     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
883     {
884         SetLastError(ERROR_INVALID_PARAMETER);
885         return FALSE;
886     }
887
888     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
889         if (WellKnownRids[i].Type == WellKnownSidType) {
890             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
891             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
892             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
893
894             if (*cbSid < output_sid_length) {
895                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
896                 return FALSE;
897             }
898
899             CopyMemory(pSid, DomainSid, domain_sid_length);
900             (*GetSidSubAuthorityCount(pSid))++;
901             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
902             *cbSid = output_sid_length;
903             return TRUE;
904         }
905
906     SetLastError(ERROR_INVALID_PARAMETER);
907     return FALSE;
908 }
909
910 /******************************************************************************
911  * IsWellKnownSid [ADVAPI32.@]
912  */
913 BOOL WINAPI
914 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
915 {
916     unsigned int i;
917     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
918
919     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
920         if (WellKnownSids[i].Type == WellKnownSidType)
921             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
922                 return TRUE;
923
924     return FALSE;
925 }
926
927 BOOL WINAPI
928 IsTokenRestricted( HANDLE TokenHandle )
929 {
930     TOKEN_GROUPS *groups;
931     DWORD size;
932     NTSTATUS status;
933     BOOL restricted;
934
935     TRACE("(%p)\n", TokenHandle);
936  
937     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
938     if (status != STATUS_BUFFER_TOO_SMALL)
939         return FALSE;
940  
941     groups = HeapAlloc(GetProcessHeap(), 0, size);
942     if (!groups)
943     {
944         SetLastError(ERROR_OUTOFMEMORY);
945         return FALSE;
946     }
947  
948     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
949     if (status != STATUS_SUCCESS)
950     {
951         HeapFree(GetProcessHeap(), 0, groups);
952         return set_ntstatus(status);
953     }
954  
955     if (groups->GroupCount)
956         restricted = TRUE;
957     else
958         restricted = FALSE;
959      
960     HeapFree(GetProcessHeap(), 0, groups);
961  
962     return restricted;
963 }
964
965 /******************************************************************************
966  * IsValidSid [ADVAPI32.@]
967  *
968  * PARAMS
969  *   pSid []
970  */
971 BOOL WINAPI
972 IsValidSid( PSID pSid )
973 {
974         return RtlValidSid( pSid );
975 }
976
977 /******************************************************************************
978  * EqualSid [ADVAPI32.@]
979  *
980  * PARAMS
981  *   pSid1 []
982  *   pSid2 []
983  */
984 BOOL WINAPI
985 EqualSid( PSID pSid1, PSID pSid2 )
986 {
987         return RtlEqualSid( pSid1, pSid2 );
988 }
989
990 /******************************************************************************
991  * EqualPrefixSid [ADVAPI32.@]
992  */
993 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
994 {
995         return RtlEqualPrefixSid(pSid1, pSid2);
996 }
997
998 /******************************************************************************
999  * GetSidLengthRequired [ADVAPI32.@]
1000  *
1001  * PARAMS
1002  *   nSubAuthorityCount []
1003  */
1004 DWORD WINAPI
1005 GetSidLengthRequired( BYTE nSubAuthorityCount )
1006 {
1007         return RtlLengthRequiredSid(nSubAuthorityCount);
1008 }
1009
1010 /******************************************************************************
1011  * InitializeSid [ADVAPI32.@]
1012  *
1013  * PARAMS
1014  *   pIdentifierAuthority []
1015  */
1016 BOOL WINAPI
1017 InitializeSid (
1018         PSID pSid,
1019         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1020         BYTE nSubAuthorityCount)
1021 {
1022         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1023 }
1024
1025 DWORD WINAPI
1026 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1027 {
1028     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1029
1030     return 1;
1031 }
1032
1033 DWORD WINAPI
1034 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1035 {
1036     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1037
1038     return 1;
1039 }
1040
1041 /******************************************************************************
1042  * GetSidIdentifierAuthority [ADVAPI32.@]
1043  *
1044  * PARAMS
1045  *   pSid []
1046  */
1047 PSID_IDENTIFIER_AUTHORITY WINAPI
1048 GetSidIdentifierAuthority( PSID pSid )
1049 {
1050         return RtlIdentifierAuthoritySid(pSid);
1051 }
1052
1053 /******************************************************************************
1054  * GetSidSubAuthority [ADVAPI32.@]
1055  *
1056  * PARAMS
1057  *   pSid          []
1058  *   nSubAuthority []
1059  */
1060 PDWORD WINAPI
1061 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1062 {
1063         return RtlSubAuthoritySid(pSid, nSubAuthority);
1064 }
1065
1066 /******************************************************************************
1067  * GetSidSubAuthorityCount [ADVAPI32.@]
1068  *
1069  * PARAMS
1070  *   pSid []
1071  */
1072 PUCHAR WINAPI
1073 GetSidSubAuthorityCount (PSID pSid)
1074 {
1075         return RtlSubAuthorityCountSid(pSid);
1076 }
1077
1078 /******************************************************************************
1079  * GetLengthSid [ADVAPI32.@]
1080  *
1081  * PARAMS
1082  *   pSid []
1083  */
1084 DWORD WINAPI
1085 GetLengthSid (PSID pSid)
1086 {
1087         return RtlLengthSid(pSid);
1088 }
1089
1090 /*      ##############################################
1091         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1092         ##############################################
1093 */
1094
1095  /****************************************************************************** 
1096  * BuildSecurityDescriptorA [ADVAPI32.@]
1097  *
1098  * Builds a SD from 
1099  *
1100  * PARAMS
1101  *  pOwner                [I]
1102  *  pGroup                [I]
1103  *  cCountOfAccessEntries [I]
1104  *  pListOfAccessEntries  [I]
1105  *  cCountOfAuditEntries  [I]
1106  *  pListofAuditEntries   [I]
1107  *  pOldSD                [I]
1108  *  lpdwBufferLength      [I/O]
1109  *  pNewSD                [O]
1110  *
1111  * RETURNS
1112  *  Success: ERROR_SUCCESS
1113  *  Failure: nonzero error code from Winerror.h
1114  */
1115 DWORD WINAPI BuildSecurityDescriptorA(
1116     IN PTRUSTEEA pOwner,
1117     IN PTRUSTEEA pGroup,
1118     IN ULONG cCountOfAccessEntries,
1119     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1120     IN ULONG cCountOfAuditEntries,
1121     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1122     IN PSECURITY_DESCRIPTOR pOldSD,
1123     IN OUT PULONG lpdwBufferLength,
1124     OUT PSECURITY_DESCRIPTOR* pNewSD)
1125
1126     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1127           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1128           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1129  
1130     return ERROR_CALL_NOT_IMPLEMENTED;
1131
1132  
1133 /******************************************************************************
1134  * BuildSecurityDescriptorW [ADVAPI32.@]
1135  *
1136  * See BuildSecurityDescriptorA.
1137  */
1138 DWORD WINAPI BuildSecurityDescriptorW(
1139     IN PTRUSTEEW pOwner,
1140     IN PTRUSTEEW pGroup,
1141     IN ULONG cCountOfAccessEntries,
1142     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1143     IN ULONG cCountOfAuditEntries,
1144     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1145     IN PSECURITY_DESCRIPTOR pOldSD,
1146     IN OUT PULONG lpdwBufferLength,
1147     OUT PSECURITY_DESCRIPTOR* pNewSD)
1148
1149     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1150           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1151           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1152  
1153     return ERROR_CALL_NOT_IMPLEMENTED;
1154
1155
1156 /******************************************************************************
1157  * InitializeSecurityDescriptor [ADVAPI32.@]
1158  *
1159  * PARAMS
1160  *   pDescr   []
1161  *   revision []
1162  */
1163 BOOL WINAPI
1164 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1165 {
1166         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1167 }
1168
1169
1170 /******************************************************************************
1171  * MakeAbsoluteSD [ADVAPI32.@]
1172  */
1173 BOOL WINAPI MakeAbsoluteSD (
1174         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1175         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1176         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1177         OUT PACL pDacl,
1178         OUT LPDWORD lpdwDaclSize,
1179         OUT PACL pSacl,
1180         OUT LPDWORD lpdwSaclSize,
1181         OUT PSID pOwner,
1182         OUT LPDWORD lpdwOwnerSize,
1183         OUT PSID pPrimaryGroup,
1184         OUT LPDWORD lpdwPrimaryGroupSize)
1185 {
1186     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1187                                                      pAbsoluteSecurityDescriptor,
1188                                                      lpdwAbsoluteSecurityDescriptorSize,
1189                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1190                                                      pOwner, lpdwOwnerSize,
1191                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1192 }
1193
1194 /******************************************************************************
1195  * GetKernelObjectSecurity [ADVAPI32.@]
1196  */
1197 BOOL WINAPI GetKernelObjectSecurity(
1198         HANDLE Handle,
1199         SECURITY_INFORMATION RequestedInformation,
1200         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1201         DWORD nLength,
1202         LPDWORD lpnLengthNeeded )
1203 {
1204     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1205           pSecurityDescriptor, nLength, lpnLengthNeeded);
1206
1207     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1208                                                nLength, lpnLengthNeeded ));
1209 }
1210
1211 /******************************************************************************
1212  * GetPrivateObjectSecurity [ADVAPI32.@]
1213  */
1214 BOOL WINAPI GetPrivateObjectSecurity(
1215         PSECURITY_DESCRIPTOR ObjectDescriptor,
1216         SECURITY_INFORMATION SecurityInformation,
1217         PSECURITY_DESCRIPTOR ResultantDescriptor,
1218         DWORD DescriptorLength,
1219         PDWORD ReturnLength )
1220 {
1221     SECURITY_DESCRIPTOR desc;
1222     BOOL defaulted, present;
1223     PACL pacl;
1224     PSID psid;
1225
1226     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1227           ResultantDescriptor, DescriptorLength, ReturnLength);
1228
1229     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1230         return FALSE;
1231
1232     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1233     {
1234         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1235             return FALSE;
1236         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1237     }
1238
1239     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1240     {
1241         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1242             return FALSE;
1243         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1244     }
1245
1246     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1247     {
1248         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1249             return FALSE;
1250         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1251     }
1252
1253     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1254     {
1255         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1256             return FALSE;
1257         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1258     }
1259
1260     *ReturnLength = DescriptorLength;
1261     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1262 }
1263
1264 /******************************************************************************
1265  * GetSecurityDescriptorLength [ADVAPI32.@]
1266  */
1267 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1268 {
1269         return RtlLengthSecurityDescriptor(pDescr);
1270 }
1271
1272 /******************************************************************************
1273  * GetSecurityDescriptorOwner [ADVAPI32.@]
1274  *
1275  * PARAMS
1276  *   pOwner            []
1277  *   lpbOwnerDefaulted []
1278  */
1279 BOOL WINAPI
1280 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1281                             LPBOOL lpbOwnerDefaulted )
1282 {
1283     BOOLEAN defaulted;
1284     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1285     *lpbOwnerDefaulted = defaulted;
1286     return ret;
1287 }
1288
1289 /******************************************************************************
1290  * SetSecurityDescriptorOwner [ADVAPI32.@]
1291  *
1292  * PARAMS
1293  */
1294 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1295                                    PSID pOwner, BOOL bOwnerDefaulted)
1296 {
1297     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1298 }
1299 /******************************************************************************
1300  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1301  */
1302 BOOL WINAPI GetSecurityDescriptorGroup(
1303         PSECURITY_DESCRIPTOR SecurityDescriptor,
1304         PSID *Group,
1305         LPBOOL GroupDefaulted)
1306 {
1307     BOOLEAN defaulted;
1308     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1309     *GroupDefaulted = defaulted;
1310     return ret;
1311 }
1312 /******************************************************************************
1313  * SetSecurityDescriptorGroup [ADVAPI32.@]
1314  */
1315 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1316                                            PSID Group, BOOL GroupDefaulted)
1317 {
1318     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1319 }
1320
1321 /******************************************************************************
1322  * IsValidSecurityDescriptor [ADVAPI32.@]
1323  *
1324  * PARAMS
1325  *   lpsecdesc []
1326  */
1327 BOOL WINAPI
1328 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1329 {
1330     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1331 }
1332
1333 /******************************************************************************
1334  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1335  */
1336 BOOL WINAPI GetSecurityDescriptorDacl(
1337         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1338         OUT LPBOOL lpbDaclPresent,
1339         OUT PACL *pDacl,
1340         OUT LPBOOL lpbDaclDefaulted)
1341 {
1342     BOOLEAN present, defaulted;
1343     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1344     *lpbDaclPresent = present;
1345     *lpbDaclDefaulted = defaulted;
1346     return ret;
1347 }
1348
1349 /******************************************************************************
1350  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1351  */
1352 BOOL WINAPI
1353 SetSecurityDescriptorDacl (
1354         PSECURITY_DESCRIPTOR lpsd,
1355         BOOL daclpresent,
1356         PACL dacl,
1357         BOOL dacldefaulted )
1358 {
1359     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1360 }
1361 /******************************************************************************
1362  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1363  */
1364 BOOL WINAPI GetSecurityDescriptorSacl(
1365         IN PSECURITY_DESCRIPTOR lpsd,
1366         OUT LPBOOL lpbSaclPresent,
1367         OUT PACL *pSacl,
1368         OUT LPBOOL lpbSaclDefaulted)
1369 {
1370     BOOLEAN present, defaulted;
1371     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1372     *lpbSaclPresent = present;
1373     *lpbSaclDefaulted = defaulted;
1374     return ret;
1375 }
1376
1377 /**************************************************************************
1378  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1379  */
1380 BOOL WINAPI SetSecurityDescriptorSacl (
1381         PSECURITY_DESCRIPTOR lpsd,
1382         BOOL saclpresent,
1383         PACL lpsacl,
1384         BOOL sacldefaulted)
1385 {
1386     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1387 }
1388 /******************************************************************************
1389  * MakeSelfRelativeSD [ADVAPI32.@]
1390  *
1391  * PARAMS
1392  *   lpabssecdesc  []
1393  *   lpselfsecdesc []
1394  *   lpbuflen      []
1395  */
1396 BOOL WINAPI
1397 MakeSelfRelativeSD(
1398         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1399         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1400         IN OUT LPDWORD lpdwBufferLength)
1401 {
1402     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1403                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1404 }
1405
1406 /******************************************************************************
1407  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1408  */
1409
1410 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1411                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1412 {
1413     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1414 }
1415
1416 /******************************************************************************
1417  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1418  */
1419 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1420   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1421   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1422 {
1423     return set_ntstatus( RtlSetControlSecurityDescriptor(
1424         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1425 }
1426
1427 /*      ##############################
1428         ######  ACL FUNCTIONS   ######
1429         ##############################
1430 */
1431
1432 /*************************************************************************
1433  * InitializeAcl [ADVAPI32.@]
1434  */
1435 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1436 {
1437     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1438 }
1439
1440 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1441 {
1442     IO_STATUS_BLOCK io_block;
1443
1444     TRACE("(%p)\n", hNamedPipe);
1445
1446     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1447                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1448 }
1449
1450 /******************************************************************************
1451  *  AddAccessAllowedAce [ADVAPI32.@]
1452  */
1453 BOOL WINAPI AddAccessAllowedAce(
1454         IN OUT PACL pAcl,
1455         IN DWORD dwAceRevision,
1456         IN DWORD AccessMask,
1457         IN PSID pSid)
1458 {
1459     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1460 }
1461
1462 /******************************************************************************
1463  *  AddAccessAllowedAceEx [ADVAPI32.@]
1464  */
1465 BOOL WINAPI AddAccessAllowedAceEx(
1466         IN OUT PACL pAcl,
1467         IN DWORD dwAceRevision,
1468         IN DWORD AceFlags,
1469         IN DWORD AccessMask,
1470         IN PSID pSid)
1471 {
1472     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1473 }
1474
1475 /******************************************************************************
1476  *  AddAccessDeniedAce [ADVAPI32.@]
1477  */
1478 BOOL WINAPI AddAccessDeniedAce(
1479         IN OUT PACL pAcl,
1480         IN DWORD dwAceRevision,
1481         IN DWORD AccessMask,
1482         IN PSID pSid)
1483 {
1484     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1485 }
1486
1487 /******************************************************************************
1488  *  AddAccessDeniedAceEx [ADVAPI32.@]
1489  */
1490 BOOL WINAPI AddAccessDeniedAceEx(
1491         IN OUT PACL pAcl,
1492         IN DWORD dwAceRevision,
1493         IN DWORD AceFlags,
1494         IN DWORD AccessMask,
1495         IN PSID pSid)
1496 {
1497     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1498 }
1499
1500 /******************************************************************************
1501  *  AddAce [ADVAPI32.@]
1502  */
1503 BOOL WINAPI AddAce(
1504         IN OUT PACL pAcl,
1505         IN DWORD dwAceRevision,
1506         IN DWORD dwStartingAceIndex,
1507         LPVOID pAceList,
1508         DWORD nAceListLength)
1509 {
1510     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1511 }
1512
1513 /******************************************************************************
1514  * DeleteAce [ADVAPI32.@]
1515  */
1516 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1517 {
1518     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1519 }
1520
1521 /******************************************************************************
1522  *  FindFirstFreeAce [ADVAPI32.@]
1523  */
1524 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1525 {
1526         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1527 }
1528
1529 /******************************************************************************
1530  * GetAce [ADVAPI32.@]
1531  */
1532 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1533 {
1534     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1535 }
1536
1537 /******************************************************************************
1538  * GetAclInformation [ADVAPI32.@]
1539  */
1540 BOOL WINAPI GetAclInformation(
1541   PACL pAcl,
1542   LPVOID pAclInformation,
1543   DWORD nAclInformationLength,
1544   ACL_INFORMATION_CLASS dwAclInformationClass)
1545 {
1546     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1547                                                nAclInformationLength, dwAclInformationClass));
1548 }
1549
1550 /******************************************************************************
1551  *  IsValidAcl [ADVAPI32.@]
1552  */
1553 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1554 {
1555         return RtlValidAcl(pAcl);
1556 }
1557
1558 /*      ##############################
1559         ######  MISC FUNCTIONS  ######
1560         ##############################
1561 */
1562
1563 /******************************************************************************
1564  * AllocateLocallyUniqueId [ADVAPI32.@]
1565  *
1566  * PARAMS
1567  *   lpLuid []
1568  */
1569 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1570 {
1571     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1572 }
1573
1574 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1575  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1576 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1577  { '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 };
1578 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1579  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1580 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1581  { '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 };
1582 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1583  { '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 };
1584 static const WCHAR SE_TCB_NAME_W[] =
1585  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1586 static const WCHAR SE_SECURITY_NAME_W[] =
1587  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1588 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1589  { '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 };
1590 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1591  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1593  { '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 };
1594 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1595  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1597  { '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 };
1598 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1599  { '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 };
1600 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1601  { '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 };
1602 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1603  { '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 };
1604 static const WCHAR SE_BACKUP_NAME_W[] =
1605  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1606 static const WCHAR SE_RESTORE_NAME_W[] =
1607  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1609  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1610 static const WCHAR SE_DEBUG_NAME_W[] =
1611  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_AUDIT_NAME_W[] =
1613  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1614 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1615  { '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 };
1616 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1617  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1618 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1619  { '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 };
1620 static const WCHAR SE_UNDOCK_NAME_W[] =
1621  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1623  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1625  { '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 };
1626 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1627  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1629  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1631  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1632
1633 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1634 {
1635     NULL,
1636     NULL,
1637     SE_CREATE_TOKEN_NAME_W,
1638     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1639     SE_LOCK_MEMORY_NAME_W,
1640     SE_INCREASE_QUOTA_NAME_W,
1641     SE_MACHINE_ACCOUNT_NAME_W,
1642     SE_TCB_NAME_W,
1643     SE_SECURITY_NAME_W,
1644     SE_TAKE_OWNERSHIP_NAME_W,
1645     SE_LOAD_DRIVER_NAME_W,
1646     SE_SYSTEM_PROFILE_NAME_W,
1647     SE_SYSTEMTIME_NAME_W,
1648     SE_PROF_SINGLE_PROCESS_NAME_W,
1649     SE_INC_BASE_PRIORITY_NAME_W,
1650     SE_CREATE_PAGEFILE_NAME_W,
1651     SE_CREATE_PERMANENT_NAME_W,
1652     SE_BACKUP_NAME_W,
1653     SE_RESTORE_NAME_W,
1654     SE_SHUTDOWN_NAME_W,
1655     SE_DEBUG_NAME_W,
1656     SE_AUDIT_NAME_W,
1657     SE_SYSTEM_ENVIRONMENT_NAME_W,
1658     SE_CHANGE_NOTIFY_NAME_W,
1659     SE_REMOTE_SHUTDOWN_NAME_W,
1660     SE_UNDOCK_NAME_W,
1661     SE_SYNC_AGENT_NAME_W,
1662     SE_ENABLE_DELEGATION_NAME_W,
1663     SE_MANAGE_VOLUME_NAME_W,
1664     SE_IMPERSONATE_NAME_W,
1665     SE_CREATE_GLOBAL_NAME_W,
1666 };
1667
1668 /******************************************************************************
1669  * LookupPrivilegeValueW                        [ADVAPI32.@]
1670  *
1671  * See LookupPrivilegeValueA.
1672  */
1673 BOOL WINAPI
1674 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1675 {
1676     UINT i;
1677
1678     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1679
1680     if (!ADVAPI_IsLocalComputer(lpSystemName))
1681     {
1682         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1683         return FALSE;
1684     }
1685     if (!lpName)
1686     {
1687         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1688         return FALSE;
1689     }
1690     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1691     {
1692         if( !WellKnownPrivNames[i] )
1693             continue;
1694         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1695             continue;
1696         lpLuid->LowPart = i;
1697         lpLuid->HighPart = 0;
1698         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1699                lpLuid->HighPart, lpLuid->LowPart );
1700         return TRUE;
1701     }
1702     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1703     return FALSE;
1704 }
1705
1706 /******************************************************************************
1707  * LookupPrivilegeValueA                        [ADVAPI32.@]
1708  *
1709  * Retrieves LUID used on a system to represent the privilege name.
1710  *
1711  * PARAMS
1712  *  lpSystemName [I] Name of the system
1713  *  lpName       [I] Name of the privilege
1714  *  lpLuid       [O] Destination for the resulting LUID
1715  *
1716  * RETURNS
1717  *  Success: TRUE. lpLuid contains the requested LUID.
1718  *  Failure: FALSE.
1719  */
1720 BOOL WINAPI
1721 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1722 {
1723     UNICODE_STRING lpSystemNameW;
1724     UNICODE_STRING lpNameW;
1725     BOOL ret;
1726
1727     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1728     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1729     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1730     RtlFreeUnicodeString(&lpNameW);
1731     RtlFreeUnicodeString(&lpSystemNameW);
1732     return ret;
1733 }
1734
1735 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1736                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1737 {
1738     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1739           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1740
1741     return FALSE;
1742 }
1743
1744 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1745                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1746 {
1747     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1748           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1749
1750     return FALSE;
1751 }
1752
1753 /******************************************************************************
1754  * LookupPrivilegeNameA                 [ADVAPI32.@]
1755  *
1756  * See LookupPrivilegeNameW.
1757  */
1758 BOOL WINAPI
1759 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1760  LPDWORD cchName)
1761 {
1762     UNICODE_STRING lpSystemNameW;
1763     BOOL ret;
1764     DWORD wLen = 0;
1765
1766     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1767
1768     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1769     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1770     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1771     {
1772         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1773
1774         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1775          &wLen);
1776         if (ret)
1777         {
1778             /* Windows crashes if cchName is NULL, so will I */
1779             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1780              *cchName, NULL, NULL);
1781
1782             if (len == 0)
1783             {
1784                 /* WideCharToMultiByte failed */
1785                 ret = FALSE;
1786             }
1787             else if (len > *cchName)
1788             {
1789                 *cchName = len;
1790                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1791                 ret = FALSE;
1792             }
1793             else
1794             {
1795                 /* WideCharToMultiByte succeeded, output length needs to be
1796                  * length not including NULL terminator
1797                  */
1798                 *cchName = len - 1;
1799             }
1800         }
1801         HeapFree(GetProcessHeap(), 0, lpNameW);
1802     }
1803     RtlFreeUnicodeString(&lpSystemNameW);
1804     return ret;
1805 }
1806
1807 /******************************************************************************
1808  * LookupPrivilegeNameW                 [ADVAPI32.@]
1809  *
1810  * Retrieves the privilege name referred to by the LUID lpLuid.
1811  *
1812  * PARAMS
1813  *  lpSystemName [I]   Name of the system
1814  *  lpLuid       [I]   Privilege value
1815  *  lpName       [O]   Name of the privilege
1816  *  cchName      [I/O] Number of characters in lpName.
1817  *
1818  * RETURNS
1819  *  Success: TRUE. lpName contains the name of the privilege whose value is
1820  *  *lpLuid.
1821  *  Failure: FALSE.
1822  *
1823  * REMARKS
1824  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1825  *  using this function.
1826  *  If the length of lpName is too small, on return *cchName will contain the
1827  *  number of WCHARs needed to contain the privilege, including the NULL
1828  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1829  *  On success, *cchName will contain the number of characters stored in
1830  *  lpName, NOT including the NULL terminator.
1831  */
1832 BOOL WINAPI
1833 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1834  LPDWORD cchName)
1835 {
1836     size_t privNameLen;
1837
1838     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1839
1840     if (!ADVAPI_IsLocalComputer(lpSystemName))
1841     {
1842         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1843         return FALSE;
1844     }
1845     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1846      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1847     {
1848         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1849         return FALSE;
1850     }
1851     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1852     /* Windows crashes if cchName is NULL, so will I */
1853     if (*cchName <= privNameLen)
1854     {
1855         *cchName = privNameLen + 1;
1856         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1857         return FALSE;
1858     }
1859     else
1860     {
1861         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1862         *cchName = privNameLen;
1863         return TRUE;
1864     }
1865 }
1866
1867 /******************************************************************************
1868  * GetFileSecurityA [ADVAPI32.@]
1869  *
1870  * Obtains Specified information about the security of a file or directory.
1871  *
1872  * PARAMS
1873  *  lpFileName           [I] Name of the file to get info for
1874  *  RequestedInformation [I] SE_ flags from "winnt.h"
1875  *  pSecurityDescriptor  [O] Destination for security information
1876  *  nLength              [I] Length of pSecurityDescriptor
1877  *  lpnLengthNeeded      [O] Destination for length of returned security information
1878  *
1879  * RETURNS
1880  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1881  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1882  *
1883  * NOTES
1884  *  The information returned is constrained by the callers access rights and
1885  *  privileges.
1886  */
1887 BOOL WINAPI
1888 GetFileSecurityA( LPCSTR lpFileName,
1889                     SECURITY_INFORMATION RequestedInformation,
1890                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1891                     DWORD nLength, LPDWORD lpnLengthNeeded )
1892 {
1893     DWORD len;
1894     BOOL r;
1895     LPWSTR name = NULL;
1896
1897     if( lpFileName )
1898     {
1899         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1900         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1901         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1902     }
1903
1904     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1905                           nLength, lpnLengthNeeded );
1906     HeapFree( GetProcessHeap(), 0, name );
1907
1908     return r;
1909 }
1910
1911 /******************************************************************************
1912  * GetFileSecurityW [ADVAPI32.@]
1913  *
1914  * See GetFileSecurityA.
1915  */
1916 BOOL WINAPI
1917 GetFileSecurityW( LPCWSTR lpFileName,
1918                     SECURITY_INFORMATION RequestedInformation,
1919                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1920                     DWORD nLength, LPDWORD lpnLengthNeeded )
1921 {
1922     HANDLE hfile;
1923     NTSTATUS status;
1924     DWORD access = 0;
1925
1926     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1927           RequestedInformation, pSecurityDescriptor,
1928           nLength, lpnLengthNeeded);
1929
1930     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1931                                 DACL_SECURITY_INFORMATION))
1932         access |= READ_CONTROL;
1933     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1934         access |= ACCESS_SYSTEM_SECURITY;
1935
1936     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1937                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1938     if ( hfile == INVALID_HANDLE_VALUE )
1939         return FALSE;
1940
1941     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1942                                     nLength, lpnLengthNeeded );
1943     CloseHandle( hfile );
1944     return set_ntstatus( status );
1945 }
1946
1947
1948 /******************************************************************************
1949  * LookupAccountSidA [ADVAPI32.@]
1950  */
1951 BOOL WINAPI
1952 LookupAccountSidA(
1953         IN LPCSTR system,
1954         IN PSID sid,
1955         OUT LPSTR account,
1956         IN OUT LPDWORD accountSize,
1957         OUT LPSTR domain,
1958         IN OUT LPDWORD domainSize,
1959         OUT PSID_NAME_USE name_use )
1960 {
1961     DWORD len;
1962     BOOL r;
1963     LPWSTR systemW = NULL;
1964     LPWSTR accountW = NULL;
1965     LPWSTR domainW = NULL;
1966     DWORD accountSizeW = *accountSize;
1967     DWORD domainSizeW = *domainSize;
1968
1969     if (system) {
1970         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1971         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1972         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1973     }
1974     if (account)
1975         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1976     if (domain)
1977         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1978
1979     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1980
1981     if (r) {
1982         if (accountW && *accountSize) {
1983             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1984             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1985             *accountSize = len;
1986         } else
1987             *accountSize = accountSizeW + 1;
1988
1989         if (domainW && *domainSize) {
1990             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1991             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1992             *domainSize = len;
1993         } else
1994             *domainSize = domainSizeW + 1;
1995     }
1996
1997     HeapFree( GetProcessHeap(), 0, systemW );
1998     HeapFree( GetProcessHeap(), 0, accountW );
1999     HeapFree( GetProcessHeap(), 0, domainW );
2000
2001     return r;
2002 }
2003
2004 /******************************************************************************
2005  * LookupAccountSidW [ADVAPI32.@]
2006  *
2007  * PARAMS
2008  *   system      []
2009  *   sid         []
2010  *   account     []
2011  *   accountSize []
2012  *   domain      []
2013  *   domainSize  []
2014  *   name_use    []
2015  */
2016
2017 BOOL WINAPI
2018 LookupAccountSidW(
2019         IN LPCWSTR system,
2020         IN PSID sid,
2021         OUT LPWSTR account,
2022         IN OUT LPDWORD accountSize,
2023         OUT LPWSTR domain,
2024         IN OUT LPDWORD domainSize,
2025         OUT PSID_NAME_USE name_use )
2026 {
2027     unsigned int i, j;
2028     const WCHAR * ac = NULL;
2029     const WCHAR * dm = NULL;
2030     SID_NAME_USE use = 0;
2031     LPWSTR computer_name = NULL;
2032     LPWSTR account_name = NULL;
2033
2034     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2035           debugstr_w(system),debugstr_sid(sid),
2036           account,accountSize,accountSize?*accountSize:0,
2037           domain,domainSize,domainSize?*domainSize:0,
2038           name_use);
2039
2040     if (!ADVAPI_IsLocalComputer(system)) {
2041         FIXME("Only local computer supported!\n");
2042         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2043         return FALSE;
2044     }
2045
2046     /* check the well known SIDs first */
2047     for (i = 0; i <= 60; i++) {
2048         if (IsWellKnownSid(sid, i)) {
2049             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2050                 if (ACCOUNT_SIDS[j].type == i) {
2051                     ac = ACCOUNT_SIDS[j].account;
2052                     dm = ACCOUNT_SIDS[j].domain;
2053                     use = ACCOUNT_SIDS[j].name_use;
2054                 }
2055             }
2056             break;
2057         }
2058     }
2059
2060     if (dm == NULL) {
2061         MAX_SID local;
2062
2063         /* check for the local computer next */
2064         if (ADVAPI_GetComputerSid(&local)) {
2065             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2066             BOOL result;
2067
2068             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2069             result = GetComputerNameW(computer_name,  &size);
2070
2071             if (result) {
2072                 if (EqualSid(sid, &local)) {
2073                     dm = computer_name;
2074                     ac = Blank;
2075                     use = 3;
2076                 } else {
2077                     local.SubAuthorityCount++;
2078
2079                     if (EqualPrefixSid(sid, &local)) {
2080                         dm = computer_name;
2081                         use = 1;
2082                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2083                         case DOMAIN_USER_RID_ADMIN:
2084                             ac = Administrator;
2085                             break;
2086                         case DOMAIN_USER_RID_GUEST:
2087                             ac = Guest;
2088                             break;
2089                         case DOMAIN_GROUP_RID_ADMINS:
2090                             ac = Domain_Admins;
2091                             break;
2092                         case DOMAIN_GROUP_RID_USERS:
2093                             ac = Domain_Users;
2094                             break;
2095                         case DOMAIN_GROUP_RID_GUESTS:
2096                             ac = Domain_Guests;
2097                             break;
2098                         case DOMAIN_GROUP_RID_COMPUTERS:
2099                             ac = Domain_Computers;
2100                             break;
2101                         case DOMAIN_GROUP_RID_CONTROLLERS:
2102                             ac = Domain_Controllers;
2103                             break;
2104                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2105                             ac = Cert_Publishers;
2106                             break;
2107                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2108                             ac = Schema_Admins;
2109                             break;
2110                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2111                             ac = Enterprise_Admins;
2112                             break;
2113                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2114                             ac = Group_Policy_Creator_Owners;
2115                             break;
2116                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2117                             ac = RAS_and_IAS_Servers;
2118                             break;
2119                         case 1000:      /* first user account */
2120                             size = UNLEN + 1;
2121                             account_name = HeapAlloc(
2122                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2123                             if (GetUserNameW(account_name, &size))
2124                                 ac = account_name;
2125                             else
2126                                 dm = NULL;
2127
2128                             break;
2129                         default:
2130                             dm = NULL;
2131                             break;
2132                         }
2133                     }
2134                 }
2135             }
2136         }
2137     }
2138
2139     if (dm) {
2140         DWORD ac_len = lstrlenW(ac);
2141         DWORD dm_len = lstrlenW(dm);
2142         BOOL status = TRUE;
2143
2144         if (*accountSize > ac_len) {
2145             if (account)
2146                 lstrcpyW(account, ac);
2147         }
2148         if (*domainSize > dm_len) {
2149             if (domain)
2150                 lstrcpyW(domain, dm);
2151         }
2152         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2153             ((*domainSize != 0) && (*domainSize < dm_len))) {
2154             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2155             status = FALSE;
2156         }
2157         if (*domainSize)
2158             *domainSize = dm_len;
2159         else
2160             *domainSize = dm_len + 1;
2161         if (*accountSize)
2162             *accountSize = ac_len;
2163         else
2164             *accountSize = ac_len + 1;
2165         *name_use = use;
2166         HeapFree(GetProcessHeap(), 0, account_name);
2167         HeapFree(GetProcessHeap(), 0, computer_name);
2168         return status;
2169     }
2170
2171     HeapFree(GetProcessHeap(), 0, account_name);
2172     HeapFree(GetProcessHeap(), 0, computer_name);
2173     SetLastError(ERROR_NONE_MAPPED);
2174     return FALSE;
2175 }
2176
2177 /******************************************************************************
2178  * SetFileSecurityA [ADVAPI32.@]
2179  *
2180  * See SetFileSecurityW.
2181  */
2182 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2183                                 SECURITY_INFORMATION RequestedInformation,
2184                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2185 {
2186     DWORD len;
2187     BOOL r;
2188     LPWSTR name = NULL;
2189
2190     if( lpFileName )
2191     {
2192         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2193         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2194         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2195     }
2196
2197     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2198     HeapFree( GetProcessHeap(), 0, name );
2199
2200     return r;
2201 }
2202
2203 /******************************************************************************
2204  * SetFileSecurityW [ADVAPI32.@]
2205  *
2206  * Sets the security of a file or directory.
2207  *
2208  * PARAMS
2209  *   lpFileName           []
2210  *   RequestedInformation []
2211  *   pSecurityDescriptor  []
2212  *
2213  * RETURNS
2214  *  Success: TRUE.
2215  *  Failure: FALSE.
2216  */
2217 BOOL WINAPI
2218 SetFileSecurityW( LPCWSTR lpFileName,
2219                     SECURITY_INFORMATION RequestedInformation,
2220                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2221 {
2222     HANDLE file;
2223     DWORD access = 0;
2224     NTSTATUS status;
2225
2226     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2227           pSecurityDescriptor );
2228
2229     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2230         RequestedInformation & GROUP_SECURITY_INFORMATION)
2231         access |= WRITE_OWNER;
2232     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2233         access |= ACCESS_SYSTEM_SECURITY;
2234     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2235         access |= WRITE_DAC;
2236
2237     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2238                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2239     if (file == INVALID_HANDLE_VALUE)
2240         return FALSE;
2241
2242     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2243     CloseHandle( file );
2244     return set_ntstatus( status );
2245 }
2246
2247 /******************************************************************************
2248  * QueryWindows31FilesMigration [ADVAPI32.@]
2249  *
2250  * PARAMS
2251  *   x1 []
2252  */
2253 BOOL WINAPI
2254 QueryWindows31FilesMigration( DWORD x1 )
2255 {
2256         FIXME("(%d):stub\n",x1);
2257         return TRUE;
2258 }
2259
2260 /******************************************************************************
2261  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2262  *
2263  * PARAMS
2264  *   x1 []
2265  *   x2 []
2266  *   x3 []
2267  *   x4 []
2268  */
2269 BOOL WINAPI
2270 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2271                                                DWORD x4 )
2272 {
2273         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2274         return TRUE;
2275 }
2276
2277 /******************************************************************************
2278  * NotifyBootConfigStatus [ADVAPI32.@]
2279  *
2280  * PARAMS
2281  *   x1 []
2282  */
2283 BOOL WINAPI
2284 NotifyBootConfigStatus( BOOL x1 )
2285 {
2286         FIXME("(0x%08d):stub\n",x1);
2287         return 1;
2288 }
2289
2290 /******************************************************************************
2291  * RevertToSelf [ADVAPI32.@]
2292  *
2293  * Ends the impersonation of a user.
2294  *
2295  * PARAMS
2296  *   void []
2297  *
2298  * RETURNS
2299  *  Success: TRUE.
2300  *  Failure: FALSE.
2301  */
2302 BOOL WINAPI
2303 RevertToSelf( void )
2304 {
2305     HANDLE Token = NULL;
2306     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2307         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2308 }
2309
2310 /******************************************************************************
2311  * ImpersonateSelf [ADVAPI32.@]
2312  *
2313  * Makes an impersonation token that represents the process user and assigns
2314  * to the current thread.
2315  *
2316  * PARAMS
2317  *  ImpersonationLevel [I] Level at which to impersonate.
2318  *
2319  * RETURNS
2320  *  Success: TRUE.
2321  *  Failure: FALSE.
2322  */
2323 BOOL WINAPI
2324 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2325 {
2326     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2327 }
2328
2329 /******************************************************************************
2330  * ImpersonateLoggedOnUser [ADVAPI32.@]
2331  */
2332 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2333 {
2334     DWORD size;
2335     NTSTATUS Status;
2336     HANDLE ImpersonationToken;
2337     TOKEN_TYPE Type;
2338     static BOOL warn = TRUE;
2339
2340     if (warn)
2341     {
2342         FIXME( "(%p)\n", hToken );
2343         warn = FALSE;
2344     }
2345     if (!GetTokenInformation( hToken, TokenType, &Type,
2346                               sizeof(TOKEN_TYPE), &size ))
2347         return FALSE;
2348
2349     if (Type == TokenPrimary)
2350     {
2351         OBJECT_ATTRIBUTES ObjectAttributes;
2352
2353         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2354
2355         Status = NtDuplicateToken( hToken,
2356                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2357                                    &ObjectAttributes,
2358                                    SecurityImpersonation,
2359                                    TokenImpersonation,
2360                                    &ImpersonationToken );
2361         if (Status != STATUS_SUCCESS)
2362         {
2363             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2364             SetLastError( RtlNtStatusToDosError( Status ) );
2365             return FALSE;
2366         }
2367     }
2368     else
2369         ImpersonationToken = hToken;
2370
2371     Status = NtSetInformationThread( GetCurrentThread(),
2372                                      ThreadImpersonationToken,
2373                                      &ImpersonationToken,
2374                                      sizeof(ImpersonationToken) );
2375
2376     if (Type == TokenPrimary)
2377         NtClose( ImpersonationToken );
2378
2379     if (Status != STATUS_SUCCESS)
2380     {
2381         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2382         SetLastError( RtlNtStatusToDosError( Status ) );
2383         return FALSE;
2384     }
2385
2386     return TRUE;
2387 }
2388
2389 /******************************************************************************
2390  * AccessCheck [ADVAPI32.@]
2391  */
2392 BOOL WINAPI
2393 AccessCheck(
2394         PSECURITY_DESCRIPTOR SecurityDescriptor,
2395         HANDLE ClientToken,
2396         DWORD DesiredAccess,
2397         PGENERIC_MAPPING GenericMapping,
2398         PPRIVILEGE_SET PrivilegeSet,
2399         LPDWORD PrivilegeSetLength,
2400         LPDWORD GrantedAccess,
2401         LPBOOL AccessStatus)
2402 {
2403     NTSTATUS access_status;
2404     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2405                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2406                                            GrantedAccess, &access_status) );
2407     if (ret) *AccessStatus = set_ntstatus( access_status );
2408     return ret;
2409 }
2410
2411
2412 /******************************************************************************
2413  * AccessCheckByType [ADVAPI32.@]
2414  */
2415 BOOL WINAPI AccessCheckByType(
2416     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2417     PSID PrincipalSelfSid,
2418     HANDLE ClientToken, 
2419     DWORD DesiredAccess, 
2420     POBJECT_TYPE_LIST ObjectTypeList,
2421     DWORD ObjectTypeListLength,
2422     PGENERIC_MAPPING GenericMapping,
2423     PPRIVILEGE_SET PrivilegeSet,
2424     LPDWORD PrivilegeSetLength, 
2425     LPDWORD GrantedAccess,
2426     LPBOOL AccessStatus)
2427 {
2428         FIXME("stub\n");
2429
2430         *AccessStatus = TRUE;
2431
2432         return !*AccessStatus;
2433 }
2434
2435 /******************************************************************************
2436  * MapGenericMask [ADVAPI32.@]
2437  *
2438  * Maps generic access rights into specific access rights according to the
2439  * supplied mapping.
2440  *
2441  * PARAMS
2442  *  AccessMask     [I/O] Access rights.
2443  *  GenericMapping [I] The mapping between generic and specific rights.
2444  *
2445  * RETURNS
2446  *  Nothing.
2447  */
2448 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2449 {
2450     RtlMapGenericMask( AccessMask, GenericMapping );
2451 }
2452
2453 /*************************************************************************
2454  * SetKernelObjectSecurity [ADVAPI32.@]
2455  */
2456 BOOL WINAPI SetKernelObjectSecurity (
2457         IN HANDLE Handle,
2458         IN SECURITY_INFORMATION SecurityInformation,
2459         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2460 {
2461     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2462 }
2463
2464
2465 /******************************************************************************
2466  *  AddAuditAccessAce [ADVAPI32.@]
2467  */
2468 BOOL WINAPI AddAuditAccessAce(
2469     IN OUT PACL pAcl, 
2470     IN DWORD dwAceRevision, 
2471     IN DWORD dwAccessMask, 
2472     IN PSID pSid, 
2473     IN BOOL bAuditSuccess, 
2474     IN BOOL bAuditFailure) 
2475 {
2476     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2477                                               bAuditSuccess, bAuditFailure) ); 
2478 }
2479
2480 /******************************************************************************
2481  *  AddAuditAccessAce [ADVAPI32.@]
2482  */
2483 BOOL WINAPI AddAuditAccessAceEx(
2484     IN OUT PACL pAcl,
2485     IN DWORD dwAceRevision,
2486     IN DWORD dwAceFlags,
2487     IN DWORD dwAccessMask,
2488     IN PSID pSid,
2489     IN BOOL bAuditSuccess,
2490     IN BOOL bAuditFailure)
2491 {
2492     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2493                                               bAuditSuccess, bAuditFailure) );
2494 }
2495
2496 /******************************************************************************
2497  * LookupAccountNameA [ADVAPI32.@]
2498  */
2499 BOOL WINAPI
2500 LookupAccountNameA(
2501         IN LPCSTR system,
2502         IN LPCSTR account,
2503         OUT PSID sid,
2504         OUT LPDWORD cbSid,
2505         LPSTR ReferencedDomainName,
2506         IN OUT LPDWORD cbReferencedDomainName,
2507         OUT PSID_NAME_USE name_use )
2508 {
2509     BOOL ret;
2510     UNICODE_STRING lpSystemW;
2511     UNICODE_STRING lpAccountW;
2512     LPWSTR lpReferencedDomainNameW = NULL;
2513
2514     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2515     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2516
2517     if (ReferencedDomainName)
2518         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2519
2520     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2521         cbReferencedDomainName, name_use);
2522
2523     if (ret && lpReferencedDomainNameW)
2524     {
2525         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2526             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2527     }
2528
2529     RtlFreeUnicodeString(&lpSystemW);
2530     RtlFreeUnicodeString(&lpAccountW);
2531     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2532
2533     return ret;
2534 }
2535
2536 /******************************************************************************
2537  * lookup_user_account_name
2538  */
2539 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2540                                      LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2541 {
2542     /* Default implementation: Always return a default SID */
2543     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2544     BOOL ret;
2545     PSID pSid;
2546     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2547     DWORD nameLen;
2548     LPCWSTR domainName;
2549
2550     ret = AllocateAndInitializeSid(&identifierAuthority,
2551         2,
2552         SECURITY_BUILTIN_DOMAIN_RID,
2553         DOMAIN_ALIAS_RID_ADMINS,
2554         0, 0, 0, 0, 0, 0,
2555         &pSid);
2556
2557     if (!ret)
2558        return FALSE;
2559
2560     if (!RtlValidSid(pSid))
2561     {
2562        FreeSid(pSid);
2563        return FALSE;
2564     }
2565
2566     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2567        CopySid(*cbSid, Sid, pSid);
2568     if (*cbSid < GetLengthSid(pSid))
2569     {
2570        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2571        ret = FALSE;
2572     }
2573     *cbSid = GetLengthSid(pSid);
2574
2575     domainName = dm;
2576     nameLen = strlenW(domainName);
2577
2578     if (*cchReferencedDomainName <= nameLen || !ret)
2579     {
2580         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2581         nameLen += 1;
2582         ret = FALSE;
2583     }
2584     else if (ReferencedDomainName)
2585         strcpyW(ReferencedDomainName, domainName);
2586
2587     *cchReferencedDomainName = nameLen;
2588
2589     if (ret)
2590         *peUse = SidTypeUser;
2591
2592     FreeSid(pSid);
2593
2594     return ret;
2595 }
2596
2597 /******************************************************************************
2598  * lookup_computer_account_name
2599  */
2600 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2601                                          LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2602 {
2603     MAX_SID local;
2604     BOOL ret;
2605     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2606     DWORD nameLen;
2607     LPCWSTR domainName;
2608
2609     if ((ret = ADVAPI_GetComputerSid(&local)))
2610     {
2611         if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2612            CopySid(*cbSid, Sid, &local);
2613         if (*cbSid < GetLengthSid(&local))
2614         {
2615            SetLastError(ERROR_INSUFFICIENT_BUFFER);
2616            ret = FALSE;
2617         }
2618         *cbSid = GetLengthSid(&local);
2619     }
2620
2621     domainName = dm;
2622     nameLen = strlenW(domainName);
2623
2624     if (*cchReferencedDomainName <= nameLen || !ret)
2625     {
2626         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2627         nameLen += 1;
2628         ret = FALSE;
2629     }
2630     else if (ReferencedDomainName)
2631         strcpyW(ReferencedDomainName, domainName);
2632
2633     *cchReferencedDomainName = nameLen;
2634
2635     if (ret)
2636         *peUse = SidTypeDomain;
2637
2638     return ret;
2639 }
2640
2641 /******************************************************************************
2642  * LookupAccountNameW [ADVAPI32.@]
2643  */
2644 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2645                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2646                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2647 {
2648     BOOL ret;
2649     PSID pSid;
2650     unsigned int i;
2651     DWORD nameLen;
2652     LPWSTR userName = NULL;
2653     LPCWSTR domainName;
2654     LPCWSTR lpAccountNamePtr;
2655     LPCWSTR lpDomainNamePtr = NULL;
2656
2657     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2658           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2659
2660     if (!ADVAPI_IsLocalComputer(lpSystemName))
2661     {
2662         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2663         return FALSE;
2664     }
2665
2666     if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2667     {
2668         lpAccountName = BUILTIN;
2669     }
2670
2671     /* Check well known SIDs first */
2672     if ((lpAccountNamePtr = strrchrW(lpAccountName,'\\')))
2673     {
2674         lpAccountNamePtr++;
2675         lpDomainNamePtr = lpAccountName;
2676     }
2677     else
2678         lpAccountNamePtr = lpAccountName;
2679
2680     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2681     {
2682         /* check domain first */
2683         if (lpDomainNamePtr && (strncmpiW(lpDomainNamePtr, ACCOUNT_SIDS[i].domain, strlenW(ACCOUNT_SIDS[i].domain)) || lpDomainNamePtr[strlenW(ACCOUNT_SIDS[i].domain)]!='\\'))
2684             continue;
2685
2686         if (!strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].account) ||
2687             (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].alias)))
2688         {
2689             DWORD sidLen = SECURITY_MAX_SID_SIZE;
2690
2691             pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2692
2693             ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2694
2695             if (ret)
2696             {
2697                 if (*cbSid < sidLen)
2698                 {
2699                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2700                     ret = FALSE;
2701                 }
2702                 else if (Sid)
2703                 {
2704                     CopySid(*cbSid, Sid, pSid);
2705                 }
2706
2707                 *cbSid = sidLen;
2708             }
2709
2710             domainName = ACCOUNT_SIDS[i].domain;
2711             nameLen = strlenW(domainName);
2712
2713             if (*cchReferencedDomainName <= nameLen || !ret)
2714             {
2715                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2716                 nameLen += 1;
2717                 ret = FALSE;
2718             }
2719             else if (ReferencedDomainName)
2720             {
2721                 strcpyW(ReferencedDomainName, domainName);
2722             }
2723
2724             *cchReferencedDomainName = nameLen;
2725
2726             if (ret)
2727             {
2728                 *peUse = ACCOUNT_SIDS[i].name_use;
2729             }
2730
2731             HeapFree(GetProcessHeap(), 0, pSid);
2732
2733             return ret;
2734         }
2735     }
2736
2737     /* Let the current Unix user id masquerade as first Windows user account */
2738
2739     nameLen = UNLEN + 1;
2740
2741     userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2742
2743     if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2744         ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2745                                        cchReferencedDomainName, peUse);
2746     else
2747     {
2748         nameLen = UNLEN + 1;
2749         if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2750             ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2751                                                cchReferencedDomainName, peUse);
2752         else
2753         {
2754             SetLastError(ERROR_NONE_MAPPED);
2755             ret = FALSE;
2756         }
2757     }
2758
2759     HeapFree(GetProcessHeap(), 0, userName);
2760
2761     return ret;
2762 }
2763
2764 /******************************************************************************
2765  * PrivilegeCheck [ADVAPI32.@]
2766  */
2767 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2768 {
2769     BOOL ret;
2770     BOOLEAN Result;
2771
2772     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2773
2774     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2775     if (ret)
2776         *pfResult = Result;
2777     return ret;
2778 }
2779
2780 /******************************************************************************
2781  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2782  */
2783 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2784   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2785   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2786   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2787 {
2788         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2789                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2790                 SecurityDescriptor, DesiredAccess, GenericMapping,
2791                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2792         return TRUE;
2793 }
2794
2795 /******************************************************************************
2796  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2797  */
2798 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2799   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2800   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2801   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2802 {
2803         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2804                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2805                 SecurityDescriptor, DesiredAccess, GenericMapping,
2806                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2807         return TRUE;
2808 }
2809
2810 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2811 {
2812     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2813
2814     return TRUE;
2815 }
2816
2817 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2818 {
2819     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2820
2821     return TRUE;
2822 }
2823
2824 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2825 {
2826     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2827
2828     return TRUE;
2829 }
2830
2831 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2832   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2833   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2834   LPBOOL GenerateOnClose)
2835 {
2836         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2837                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2838         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2839         GenerateOnClose);
2840
2841     return TRUE;
2842 }
2843
2844 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2845   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2846   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2847   LPBOOL GenerateOnClose)
2848 {
2849     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2850         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2851         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2852         GenerateOnClose);
2853
2854     return TRUE;
2855 }
2856
2857 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2858   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2859 {
2860     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2861           DesiredAccess, Privileges, AccessGranted);
2862
2863     return TRUE;
2864 }
2865
2866 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2867   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2868 {
2869     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2870           DesiredAccess, Privileges, AccessGranted);
2871
2872     return TRUE;
2873 }
2874
2875 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2876                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2877 {
2878     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2879           ClientToken, Privileges, AccessGranted);
2880
2881     return TRUE;
2882 }
2883
2884 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2885                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2886 {
2887     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2888           ClientToken, Privileges, AccessGranted);
2889
2890     return TRUE;
2891 }
2892
2893 /******************************************************************************
2894  * GetSecurityInfo [ADVAPI32.@]
2895  *
2896  * Retrieves a copy of the security descriptor associated with an object.
2897  *
2898  * PARAMS
2899  *  hObject              [I] A handle for the object.
2900  *  ObjectType           [I] The type of object.
2901  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
2902  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
2903  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
2904  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
2905  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
2906  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2907  *                           which must be freed with LocalFree.
2908  *
2909  * RETURNS
2910  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2911  */
2912 DWORD WINAPI GetSecurityInfo(
2913     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2914     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2915     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2916     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2917 )
2918 {
2919     PSECURITY_DESCRIPTOR sd;
2920     NTSTATUS status;
2921     ULONG n1, n2;
2922     BOOL present, defaulted;
2923
2924     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2925     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2926         return RtlNtStatusToDosError(status);
2927
2928     sd = LocalAlloc(0, n1);
2929     if (!sd)
2930         return ERROR_NOT_ENOUGH_MEMORY;
2931
2932     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2933     if (status != STATUS_SUCCESS)
2934     {
2935         LocalFree(sd);
2936         return RtlNtStatusToDosError(status);
2937     }
2938
2939     if (ppsidOwner)
2940     {
2941         *ppsidOwner = NULL;
2942         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2943     }
2944     if (ppsidGroup)
2945     {
2946         *ppsidGroup = NULL;
2947         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2948     }
2949     if (ppDacl)
2950     {
2951         *ppDacl = NULL;
2952         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2953     }
2954     if (ppSacl)
2955     {
2956         *ppSacl = NULL;
2957         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2958     }
2959     if (ppSecurityDescriptor)
2960         *ppSecurityDescriptor = sd;
2961
2962     return ERROR_SUCCESS;
2963 }
2964
2965 /******************************************************************************
2966  * GetSecurityInfoExA [ADVAPI32.@]
2967  */
2968 DWORD WINAPI GetSecurityInfoExA(
2969         HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2970         SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2971         LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2972         PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2973 )
2974 {
2975   FIXME("stub!\n");
2976   return ERROR_BAD_PROVIDER;
2977 }
2978
2979 /******************************************************************************
2980  * GetSecurityInfoExW [ADVAPI32.@]
2981  */
2982 DWORD WINAPI GetSecurityInfoExW(
2983         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2984         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2985         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2986         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2987 )
2988 {
2989   FIXME("stub!\n");
2990   return ERROR_BAD_PROVIDER; 
2991 }
2992
2993 /******************************************************************************
2994  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2995  */
2996 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2997                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2998                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2999 {
3000     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3001           AccessPermissions, AccessMode, Inheritance);
3002
3003     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3004     pExplicitAccess->grfAccessMode = AccessMode;
3005     pExplicitAccess->grfInheritance = Inheritance;
3006
3007     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3008     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3009     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3010     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3011     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3012 }
3013
3014 /******************************************************************************
3015  * BuildExplicitAccessWithNameW [ADVAPI32.@]
3016  */
3017 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3018                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
3019                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3020 {
3021     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3022           AccessPermissions, AccessMode, Inheritance);
3023
3024     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3025     pExplicitAccess->grfAccessMode = AccessMode;
3026     pExplicitAccess->grfInheritance = Inheritance;
3027
3028     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3029     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3030     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3031     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3032     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3033 }
3034
3035 /******************************************************************************
3036  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3037  */
3038 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3039                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3040                                              LPSTR InheritedObjectTypeName, LPSTR Name )
3041 {
3042     DWORD ObjectsPresent = 0;
3043
3044     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3045           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3046
3047     /* Fill the OBJECTS_AND_NAME structure */
3048     pObjName->ObjectType = ObjectType;
3049     if (ObjectTypeName != NULL)
3050     {
3051         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3052     }
3053
3054     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3055     if (InheritedObjectTypeName != NULL)
3056     {
3057         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3058     }
3059
3060     pObjName->ObjectsPresent = ObjectsPresent;
3061     pObjName->ptstrName = Name;
3062
3063     /* Fill the TRUSTEE structure */
3064     pTrustee->pMultipleTrustee = NULL;
3065     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3066     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3067     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3068     pTrustee->ptstrName = (LPSTR)pObjName;
3069 }
3070
3071 /******************************************************************************
3072  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3073  */
3074 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3075                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3076                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
3077 {
3078     DWORD ObjectsPresent = 0;
3079
3080     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3081           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3082
3083     /* Fill the OBJECTS_AND_NAME structure */
3084     pObjName->ObjectType = ObjectType;
3085     if (ObjectTypeName != NULL)
3086     {
3087         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3088     }
3089
3090     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3091     if (InheritedObjectTypeName != NULL)
3092     {
3093         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3094     }
3095
3096     pObjName->ObjectsPresent = ObjectsPresent;
3097     pObjName->ptstrName = Name;
3098
3099     /* Fill the TRUSTEE structure */
3100     pTrustee->pMultipleTrustee = NULL;
3101     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3102     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3103     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3104     pTrustee->ptstrName = (LPWSTR)pObjName;
3105 }
3106
3107 /******************************************************************************
3108  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3109  */
3110 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3111                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3112 {
3113     DWORD ObjectsPresent = 0;
3114
3115     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3116
3117     /* Fill the OBJECTS_AND_SID structure */
3118     if (pObjectGuid != NULL)
3119     {
3120         pObjSid->ObjectTypeGuid = *pObjectGuid;
3121         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3122     }
3123     else
3124     {
3125         ZeroMemory(&pObjSid->ObjectTypeGuid,
3126                    sizeof(GUID));
3127     }
3128
3129     if (pInheritedObjectGuid != NULL)
3130     {
3131         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3132         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3133     }
3134     else
3135     {
3136         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3137                    sizeof(GUID));
3138     }
3139
3140     pObjSid->ObjectsPresent = ObjectsPresent;
3141     pObjSid->pSid = pSid;
3142
3143     /* Fill the TRUSTEE structure */
3144     pTrustee->pMultipleTrustee = NULL;
3145     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3146     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3147     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3148     pTrustee->ptstrName = (LPSTR) pObjSid;
3149 }
3150
3151 /******************************************************************************
3152  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3153  */
3154 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3155                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3156 {
3157     DWORD ObjectsPresent = 0;
3158
3159     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3160
3161     /* Fill the OBJECTS_AND_SID structure */
3162     if (pObjectGuid != NULL)
3163     {
3164         pObjSid->ObjectTypeGuid = *pObjectGuid;
3165         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3166     }
3167     else
3168     {
3169         ZeroMemory(&pObjSid->ObjectTypeGuid,
3170                    sizeof(GUID));
3171     }
3172
3173     if (pInheritedObjectGuid != NULL)
3174     {
3175         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3176         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3177     }
3178     else
3179     {
3180         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3181                    sizeof(GUID));
3182     }
3183
3184     pObjSid->ObjectsPresent = ObjectsPresent;
3185     pObjSid->pSid = pSid;
3186
3187     /* Fill the TRUSTEE structure */
3188     pTrustee->pMultipleTrustee = NULL;
3189     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3190     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3191     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3192     pTrustee->ptstrName = (LPWSTR) pObjSid;
3193 }
3194
3195 /******************************************************************************
3196  * BuildTrusteeWithSidA [ADVAPI32.@]
3197  */
3198 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3199 {
3200     TRACE("%p %p\n", pTrustee, pSid);
3201
3202     pTrustee->pMultipleTrustee = NULL;
3203     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3204     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3205     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3206     pTrustee->ptstrName = pSid;
3207 }
3208
3209 /******************************************************************************
3210  * BuildTrusteeWithSidW [ADVAPI32.@]
3211  */
3212 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3213 {
3214     TRACE("%p %p\n", pTrustee, pSid);
3215
3216     pTrustee->pMultipleTrustee = NULL;
3217     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3218     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3219     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3220     pTrustee->ptstrName = pSid;
3221 }
3222
3223 /******************************************************************************
3224  * BuildTrusteeWithNameA [ADVAPI32.@]
3225  */
3226 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3227 {
3228     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3229
3230     pTrustee->pMultipleTrustee = NULL;
3231     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3232     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3233     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3234     pTrustee->ptstrName = name;
3235 }
3236
3237 /******************************************************************************
3238  * BuildTrusteeWithNameW [ADVAPI32.@]
3239  */
3240 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3241 {
3242     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3243
3244     pTrustee->pMultipleTrustee = NULL;
3245     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3246     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3247     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3248     pTrustee->ptstrName = name;
3249 }
3250
3251 /****************************************************************************** 
3252  * GetTrusteeFormA [ADVAPI32.@] 
3253  */ 
3254 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3255 {  
3256     TRACE("(%p)\n", pTrustee); 
3257   
3258     if (!pTrustee) 
3259         return TRUSTEE_BAD_FORM; 
3260   
3261     return pTrustee->TrusteeForm; 
3262 }  
3263   
3264 /****************************************************************************** 
3265  * GetTrusteeFormW [ADVAPI32.@] 
3266  */ 
3267 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3268 {  
3269     TRACE("(%p)\n", pTrustee); 
3270   
3271     if (!pTrustee) 
3272         return TRUSTEE_BAD_FORM; 
3273   
3274     return pTrustee->TrusteeForm; 
3275 }  
3276   
3277 /****************************************************************************** 
3278  * GetTrusteeNameA [ADVAPI32.@] 
3279  */ 
3280 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3281 {  
3282     TRACE("(%p)\n", pTrustee); 
3283   
3284     if (!pTrustee) 
3285         return NULL; 
3286   
3287     return pTrustee->ptstrName; 
3288 }  
3289   
3290 /****************************************************************************** 
3291  * GetTrusteeNameW [ADVAPI32.@] 
3292  */ 
3293 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3294 {  
3295     TRACE("(%p)\n", pTrustee); 
3296   
3297     if (!pTrustee) 
3298         return NULL; 
3299   
3300     return pTrustee->ptstrName; 
3301 }  
3302   
3303 /****************************************************************************** 
3304  * GetTrusteeTypeA [ADVAPI32.@] 
3305  */ 
3306 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3307 {  
3308     TRACE("(%p)\n", pTrustee); 
3309   
3310     if (!pTrustee) 
3311         return TRUSTEE_IS_UNKNOWN; 
3312   
3313     return pTrustee->TrusteeType; 
3314 }  
3315   
3316 /****************************************************************************** 
3317  * GetTrusteeTypeW [ADVAPI32.@] 
3318  */ 
3319 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3320 {  
3321     TRACE("(%p)\n", pTrustee); 
3322   
3323     if (!pTrustee) 
3324         return TRUSTEE_IS_UNKNOWN; 
3325   
3326     return pTrustee->TrusteeType; 
3327
3328  
3329 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3330                                DWORD nAclInformationLength,
3331                                ACL_INFORMATION_CLASS dwAclInformationClass )
3332 {
3333     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3334           nAclInformationLength, dwAclInformationClass);
3335
3336     return TRUE;
3337 }
3338
3339 /******************************************************************************
3340  * SetEntriesInAclA [ADVAPI32.@]
3341  */
3342 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3343                                PACL OldAcl, PACL* NewAcl )
3344 {
3345     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3346     if (NewAcl)
3347          *NewAcl = NULL;
3348     return ERROR_SUCCESS;
3349 }
3350
3351 /******************************************************************************
3352  * SetEntriesInAclW [ADVAPI32.@]
3353  */
3354 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3355                                PACL OldAcl, PACL* NewAcl )
3356 {
3357     ULONG i;
3358     PSID *ppsid;
3359     DWORD ret = ERROR_SUCCESS;
3360     DWORD acl_size = sizeof(ACL);
3361     NTSTATUS status;
3362
3363     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3364
3365     *NewAcl = NULL;
3366
3367     if (!count && !OldAcl)
3368         return ERROR_SUCCESS;
3369
3370     /* allocate array of maximum sized sids allowed */
3371     ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3372     if (!ppsid)
3373         return ERROR_OUTOFMEMORY;
3374
3375     for (i = 0; i < count; i++)
3376     {
3377         ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3378
3379         TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3380               "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3381               "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3382               pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3383               pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3384               pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3385               pEntries[i].Trustee.ptstrName);
3386
3387         if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3388         {
3389             WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3390             ret = ERROR_INVALID_PARAMETER;
3391             goto exit;
3392         }
3393
3394         switch (pEntries[i].Trustee.TrusteeForm)
3395         {
3396         case TRUSTEE_IS_SID:
3397             if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3398                          ppsid[i], pEntries[i].Trustee.ptstrName))
3399             {
3400                 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3401                 ret = ERROR_INVALID_PARAMETER;
3402                 goto exit;
3403             }
3404             break;
3405         case TRUSTEE_IS_NAME:
3406         {
3407             DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3408             DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3409             SID_NAME_USE use;
3410             if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3411             {
3412                 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3413                 ret = ERROR_INVALID_PARAMETER;
3414                 goto exit;
3415             }
3416             break;
3417         }
3418         case TRUSTEE_IS_OBJECTS_AND_SID:
3419             FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3420             break;
3421         case TRUSTEE_IS_OBJECTS_AND_NAME:
3422             FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3423             break;
3424         default:
3425             WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3426             ret = ERROR_INVALID_PARAMETER;
3427             goto exit;
3428         }
3429
3430         /* Note: we overestimate the ACL size here as a tradeoff between
3431          * instructions (simplicity) and memory */
3432         switch (pEntries[i].grfAccessMode)
3433         {
3434         case GRANT_ACCESS:
3435         case SET_ACCESS:
3436             acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3437             break;
3438         case DENY_ACCESS:
3439             acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3440             break;
3441         case SET_AUDIT_SUCCESS:
3442         case SET_AUDIT_FAILURE:
3443             acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3444             break;
3445         case REVOKE_ACCESS:
3446             break;
3447         default:
3448             WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3449             ret = ERROR_INVALID_PARAMETER;
3450             goto exit;
3451         }
3452     }
3453
3454     if (OldAcl)
3455     {
3456         ACL_SIZE_INFORMATION size_info;
3457
3458         status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3459         if (status != STATUS_SUCCESS)
3460         {
3461             ret = RtlNtStatusToDosError(status);
3462             goto exit;
3463         }
3464         acl_size += size_info.AclBytesInUse - sizeof(ACL);
3465     }
3466
3467     *NewAcl = LocalAlloc(0, acl_size);
3468     if (!*NewAcl)
3469     {
3470         ret = ERROR_OUTOFMEMORY;
3471         goto exit;
3472     }
3473
3474     status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3475     if (status != STATUS_SUCCESS)
3476     {
3477         ret = RtlNtStatusToDosError(status);
3478         goto exit;
3479     }
3480
3481     for (i = 0; i < count; i++)
3482     {
3483         switch (pEntries[i].grfAccessMode)
3484         {
3485         case GRANT_ACCESS:
3486             status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3487                                               pEntries[i].grfInheritance,
3488                                               pEntries[i].grfAccessPermissions,
3489                                               ppsid[i]);
3490             break;
3491         case SET_ACCESS:
3492         {
3493             ULONG j;
3494             BOOL add = TRUE;
3495             if (OldAcl)
3496             {
3497                 for (j = 0; ; j++)
3498                 {
3499                     const ACE_HEADER *existing_ace_header;
3500                     status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3501                     if (status != STATUS_SUCCESS)
3502                         break;
3503                     if (pEntries[i].grfAccessMode == SET_ACCESS &&
3504                         existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3505                         EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3506                     {
3507                         add = FALSE;
3508                         break;
3509                     }
3510                 }
3511             }
3512             if (add)
3513                 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3514                                                   pEntries[i].grfInheritance,
3515                                                   pEntries[i].grfAccessPermissions,
3516                                                   ppsid[i]);
3517             break;
3518         }
3519         case DENY_ACCESS:
3520             status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3521                                              pEntries[i].grfInheritance,
3522                                              pEntries[i].grfAccessPermissions,
3523                                              ppsid[i]);
3524             break;
3525         case SET_AUDIT_SUCCESS:
3526             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3527                                             pEntries[i].grfInheritance,
3528                                             pEntries[i].grfAccessPermissions,
3529                                             ppsid[i], TRUE, FALSE);
3530             break;
3531         case SET_AUDIT_FAILURE:
3532             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3533                                             pEntries[i].grfInheritance,
3534                                             pEntries[i].grfAccessPermissions,
3535                                             ppsid[i], FALSE, TRUE);
3536             break;
3537         default:
3538             FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3539         }
3540     }
3541
3542     if (OldAcl)
3543     {
3544         for (i = 0; ; i++)
3545         {
3546             BOOL add = TRUE;
3547             ULONG j;
3548             const ACE_HEADER *old_ace_header;
3549             status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3550             if (status != STATUS_SUCCESS) break;
3551             for (j = 0; j < count; j++)
3552             {
3553                 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3554                     old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3555                     EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3556                 {
3557                     status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3558                     add = FALSE;
3559                     break;
3560                 }
3561                 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3562                 {
3563                     switch (old_ace_header->AceType)
3564                     {
3565                     case ACCESS_ALLOWED_ACE_TYPE:
3566                         if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3567                             add = FALSE;
3568                         break;
3569                     case ACCESS_DENIED_ACE_TYPE:
3570                         if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3571                             add = FALSE;
3572                         break;
3573                     case SYSTEM_AUDIT_ACE_TYPE:
3574                         if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3575                             add = FALSE;
3576                         break;
3577                     case SYSTEM_ALARM_ACE_TYPE:
3578                         if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3579                             add = FALSE;
3580                         break;
3581                     default:
3582                         FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3583                     }
3584
3585                     if (!add)
3586                         break;
3587                 }
3588             }
3589             if (add)
3590                 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3591             if (status != STATUS_SUCCESS)
3592             {
3593                 WARN("RtlAddAce failed with error 0x%08x\n", status);
3594                 ret = RtlNtStatusToDosError(status);
3595                 break;
3596             }
3597         }
3598     }
3599
3600 exit:
3601     HeapFree(GetProcessHeap(), 0, ppsid);
3602     return ret;
3603 }
3604
3605 /******************************************************************************
3606  * SetNamedSecurityInfoA [ADVAPI32.@]
3607  */
3608 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3609         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3610         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3611 {
3612     DWORD len;
3613     LPWSTR wstr = NULL;
3614     DWORD r;
3615
3616     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3617            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3618
3619     if( pObjectName )
3620     {
3621         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3622         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3623         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3624     }
3625
3626     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3627                            psidGroup, pDacl, pSacl );
3628
3629     HeapFree( GetProcessHeap(), 0, wstr );
3630
3631     return r;
3632 }
3633
3634 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3635     PSECURITY_DESCRIPTOR ModificationDescriptor,
3636     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3637     PGENERIC_MAPPING GenericMapping,
3638     HANDLE Token )
3639 {
3640     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3641           ObjectsSecurityDescriptor, GenericMapping, Token);
3642
3643     return TRUE;
3644 }
3645
3646 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3647 {
3648     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3649 }
3650
3651 /******************************************************************************
3652  * AreAnyAccessesGranted [ADVAPI32.@]
3653  *
3654  * Determines whether or not any of a set of specified access permissions have
3655  * been granted or not.
3656  *
3657  * PARAMS
3658  *   GrantedAccess [I] The permissions that have been granted.
3659  *   DesiredAccess [I] The permissions that you want to have.
3660  *
3661  * RETURNS
3662  *   Nonzero if any of the permissions have been granted, zero if none of the
3663  *   permissions have been granted.
3664  */
3665
3666 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3667 {
3668     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3669 }
3670
3671 /******************************************************************************
3672  * SetNamedSecurityInfoW [ADVAPI32.@]
3673  */
3674 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3675         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3676         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3677 {
3678     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3679            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3680     return ERROR_SUCCESS;
3681 }
3682
3683 /******************************************************************************
3684  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3685  */
3686 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3687         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3688 {
3689     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3690     return ERROR_CALL_NOT_IMPLEMENTED;
3691 }
3692
3693 /******************************************************************************
3694  * GetExplicitEntriesFromAclW [ADVAPI32.@]
3695  */
3696 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3697         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3698 {
3699     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3700     return ERROR_CALL_NOT_IMPLEMENTED;
3701 }
3702
3703 /******************************************************************************
3704  * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3705  */
3706 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3707         PACCESS_MASK pFailedAuditRights)
3708 {
3709     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3710     return ERROR_CALL_NOT_IMPLEMENTED;
3711
3712 }
3713
3714 /******************************************************************************
3715  * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3716  */
3717 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3718         PACCESS_MASK pFailedAuditRights)
3719 {
3720     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3721     return ERROR_CALL_NOT_IMPLEMENTED;
3722
3723 }
3724
3725 /******************************************************************************
3726  * ParseAclStringFlags
3727  */
3728 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3729 {
3730     DWORD flags = 0;
3731     LPCWSTR szAcl = *StringAcl;
3732
3733     while (*szAcl != '(')
3734     {
3735         if (*szAcl == 'P')
3736         {
3737             flags |= SE_DACL_PROTECTED;
3738         }
3739         else if (*szAcl == 'A')
3740         {
3741             szAcl++;
3742             if (*szAcl == 'R')
3743                 flags |= SE_DACL_AUTO_INHERIT_REQ;
3744             else if (*szAcl == 'I')
3745                 flags |= SE_DACL_AUTO_INHERITED;
3746         }
3747         szAcl++;
3748     }
3749
3750     *StringAcl = szAcl;
3751     return flags;
3752 }
3753
3754 /******************************************************************************
3755  * ParseAceStringType
3756  */
3757 static const ACEFLAG AceType[] =
3758 {
3759     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
3760     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
3761     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3762     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
3763     /*
3764     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3765     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
3766     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
3767     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3768     */
3769     { NULL, 0 },
3770 };
3771
3772 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3773 {
3774     UINT len = 0;
3775     LPCWSTR szAcl = *StringAcl;
3776     const ACEFLAG *lpaf = AceType;
3777
3778     while (lpaf->wstr &&
3779         (len = strlenW(lpaf->wstr)) &&
3780         strncmpW(lpaf->wstr, szAcl, len))
3781         lpaf++;
3782
3783     if (!lpaf->wstr)
3784         return 0;
3785
3786     *StringAcl += len;
3787     return lpaf->value;
3788 }
3789
3790
3791 /******************************************************************************
3792  * ParseAceStringFlags
3793  */
3794 static const ACEFLAG AceFlags[] =
3795 {
3796     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3797     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
3798     { SDDL_INHERITED,         INHERITED_ACE },
3799     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
3800     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
3801     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
3802     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
3803     { NULL, 0 },
3804 };
3805
3806 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3807 {
3808     UINT len = 0;
3809     BYTE flags = 0;
3810     LPCWSTR szAcl = *StringAcl;
3811
3812     while (*szAcl != ';')
3813     {
3814         const ACEFLAG *lpaf = AceFlags;
3815
3816         while (lpaf->wstr &&
3817                (len = strlenW(lpaf->wstr)) &&
3818                strncmpW(lpaf->wstr, szAcl, len))
3819             lpaf++;
3820
3821         if (!lpaf->wstr)
3822             return 0;
3823
3824         flags |= lpaf->value;
3825         szAcl += len;
3826     }
3827
3828     *StringAcl = szAcl;
3829     return flags;
3830 }
3831
3832
3833 /******************************************************************************
3834  * ParseAceStringRights
3835  */
3836 static const ACEFLAG AceRights[] =
3837 {
3838     { SDDL_GENERIC_ALL,     GENERIC_ALL },
3839     { SDDL_GENERIC_READ,    GENERIC_READ },
3840     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
3841     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3842
3843     { SDDL_READ_CONTROL,    READ_CONTROL },
3844     { SDDL_STANDARD_DELETE, DELETE },
3845     { SDDL_WRITE_DAC,       WRITE_DAC },
3846     { SDDL_WRITE_OWNER,     WRITE_OWNER },
3847
3848     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
3849     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
3850     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
3851     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
3852     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
3853     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
3854     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
3855     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
3856     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
3857
3858     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
3859     { SDDL_FILE_READ,       FILE_GENERIC_READ },
3860     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
3861     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
3862
3863     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
3864     { SDDL_KEY_READ,        KEY_READ },
3865     { SDDL_KEY_WRITE,       KEY_WRITE },
3866     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
3867     { NULL, 0 },
3868 };
3869
3870 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3871 {
3872     UINT len = 0;
3873     DWORD rights = 0;
3874     LPCWSTR szAcl = *StringAcl;
3875
3876     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3877     {
3878         LPCWSTR p = szAcl;
3879
3880         while (*p && *p != ';')
3881             p++;
3882
3883         if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3884         {
3885             rights = strtoulW(szAcl, NULL, 16);
3886             szAcl = p;
3887         }
3888         else
3889             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3890     }
3891     else
3892     {
3893         while (*szAcl != ';')
3894         {
3895             const ACEFLAG *lpaf = AceRights;
3896
3897             while (lpaf->wstr &&
3898                (len = strlenW(lpaf->wstr)) &&
3899                strncmpW(lpaf->wstr, szAcl, len))
3900             {
3901                lpaf++;
3902             }
3903
3904             if (!lpaf->wstr)
3905                 return 0;
3906
3907             rights |= lpaf->value;
3908             szAcl += len;
3909         }
3910     }
3911
3912     *StringAcl = szAcl;
3913     return rights;
3914 }
3915
3916
3917 /******************************************************************************
3918  * ParseStringAclToAcl
3919  * 
3920  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
3921  */
3922 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
3923     PACL pAcl, LPDWORD cBytes)
3924 {
3925     DWORD val;
3926     DWORD sidlen;
3927     DWORD length = sizeof(ACL);
3928     DWORD acesize = 0;
3929     DWORD acecount = 0;
3930     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3931
3932     TRACE("%s\n", debugstr_w(StringAcl));
3933
3934     if (!StringAcl)
3935         return FALSE;
3936
3937     if (pAcl) /* pAce is only useful if we're setting values */
3938         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3939
3940     /* Parse ACL flags */
3941     *lpdwFlags = ParseAclStringFlags(&StringAcl);
3942
3943     /* Parse ACE */
3944     while (*StringAcl == '(')
3945     {
3946         StringAcl++;
3947
3948         /* Parse ACE type */
3949         val = ParseAceStringType(&StringAcl);
3950         if (pAce)
3951             pAce->Header.AceType = (BYTE) val;
3952         if (*StringAcl != ';')
3953             goto lerr;
3954         StringAcl++;
3955
3956         /* Parse ACE flags */
3957         val = ParseAceStringFlags(&StringAcl);
3958         if (pAce)
3959             pAce->Header.AceFlags = (BYTE) val;
3960         if (*StringAcl != ';')
3961             goto lerr;
3962         StringAcl++;
3963
3964         /* Parse ACE rights */
3965         val = ParseAceStringRights(&StringAcl);
3966         if (pAce)
3967             pAce->Mask = val;
3968         if (*StringAcl != ';')
3969             goto lerr;
3970         StringAcl++;
3971
3972         /* Parse ACE object guid */
3973         if (*StringAcl != ';')
3974         {
3975             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3976             goto lerr;
3977         }
3978         StringAcl++;
3979
3980         /* Parse ACE inherit object guid */
3981         if (*StringAcl != ';')
3982         {
3983             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3984             goto lerr;
3985         }
3986         StringAcl++;
3987
3988         /* Parse ACE account sid */
3989         if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
3990         {
3991             while (*StringAcl && *StringAcl != ')')
3992                 StringAcl++;
3993         }
3994
3995         if (*StringAcl != ')')
3996             goto lerr;
3997         StringAcl++;
3998
3999         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4000         length += acesize;
4001         if (pAce)
4002         {
4003             pAce->Header.AceSize = acesize;
4004             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4005         }
4006         acecount++;
4007     }
4008
4009     *cBytes = length;
4010
4011     if (length > 0xffff)
4012     {
4013         ERR("ACL too large\n");
4014         goto lerr;
4015     }
4016
4017     if (pAcl)
4018     {
4019         pAcl->AclRevision = ACL_REVISION;
4020         pAcl->Sbz1 = 0;
4021         pAcl->AclSize = length;
4022         pAcl->AceCount = acecount++;
4023         pAcl->Sbz2 = 0;
4024     }
4025     return TRUE;
4026
4027 lerr:
4028     SetLastError(ERROR_INVALID_ACL);
4029     WARN("Invalid ACE string format\n");
4030     return FALSE;
4031 }
4032
4033
4034 /******************************************************************************
4035  * ParseStringSecurityDescriptorToSecurityDescriptor
4036  */
4037 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4038     LPCWSTR StringSecurityDescriptor,
4039     SECURITY_DESCRIPTOR* SecurityDescriptor,
4040     LPDWORD cBytes)
4041 {
4042     BOOL bret = FALSE;
4043     WCHAR toktype;
4044     WCHAR tok[MAX_PATH];
4045     LPCWSTR lptoken;
4046     LPBYTE lpNext = NULL;
4047     DWORD len;
4048
4049     *cBytes = sizeof(SECURITY_DESCRIPTOR);
4050
4051     if (SecurityDescriptor)
4052         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
4053
4054     while (*StringSecurityDescriptor)
4055     {
4056         toktype = *StringSecurityDescriptor;
4057
4058         /* Expect char identifier followed by ':' */
4059         StringSecurityDescriptor++;
4060         if (*StringSecurityDescriptor != ':')
4061         {
4062             SetLastError(ERROR_INVALID_PARAMETER);
4063             goto lend;
4064         }
4065         StringSecurityDescriptor++;
4066
4067         /* Extract token */
4068         lptoken = StringSecurityDescriptor;
4069         while (*lptoken && *lptoken != ':')
4070             lptoken++;
4071
4072         if (*lptoken)
4073             lptoken--;
4074
4075         len = lptoken - StringSecurityDescriptor;
4076         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4077         tok[len] = 0;
4078
4079         switch (toktype)
4080         {
4081             case 'O':
4082             {
4083                 DWORD bytes;
4084
4085                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4086                     goto lend;
4087
4088                 if (SecurityDescriptor)
4089                 {
4090                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4091                     lpNext += bytes; /* Advance to next token */
4092                 }
4093
4094                 *cBytes += bytes;
4095
4096                 break;
4097             }
4098
4099             case 'G':
4100             {
4101                 DWORD bytes;
4102
4103                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4104                     goto lend;
4105
4106                 if (SecurityDescriptor)
4107                 {
4108                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4109                     lpNext += bytes; /* Advance to next token */
4110                 }
4111
4112                 *cBytes += bytes;
4113
4114                 break;
4115             }
4116
4117             case 'D':
4118             {
4119                 DWORD flags;
4120                 DWORD bytes;
4121
4122                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4123                     goto lend;
4124
4125                 if (SecurityDescriptor)
4126                 {
4127                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4128                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4129                     lpNext += bytes; /* Advance to next token */
4130                 }
4131
4132                 *cBytes += bytes;
4133
4134                 break;
4135             }
4136
4137             case 'S':
4138             {
4139                 DWORD flags;
4140                 DWORD bytes;
4141
4142                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4143                     goto lend;
4144
4145                 if (SecurityDescriptor)
4146                 {
4147                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4148                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4149                     lpNext += bytes; /* Advance to next token */
4150                 }
4151
4152                 *cBytes += bytes;
4153
4154                 break;
4155             }
4156
4157             default:
4158                 FIXME("Unknown token\n");
4159                 SetLastError(ERROR_INVALID_PARAMETER);
4160                 goto lend;
4161         }
4162
4163         StringSecurityDescriptor = lptoken;
4164     }
4165
4166     bret = TRUE;
4167
4168 lend:
4169     return bret;
4170 }
4171
4172 /******************************************************************************
4173  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4174  */
4175 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4176         LPCSTR StringSecurityDescriptor,
4177         DWORD StringSDRevision,
4178         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4179         PULONG SecurityDescriptorSize)
4180 {
4181     UINT len;
4182     BOOL ret = FALSE;
4183     LPWSTR StringSecurityDescriptorW;
4184
4185     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4186     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4187
4188     if (StringSecurityDescriptorW)
4189     {
4190         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4191
4192         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4193                                                                    StringSDRevision, SecurityDescriptor,
4194                                                                    SecurityDescriptorSize);
4195         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4196     }
4197
4198     return ret;
4199 }
4200
4201 /******************************************************************************
4202  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4203  */
4204 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4205         LPCWSTR StringSecurityDescriptor,
4206         DWORD StringSDRevision,
4207         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4208         PULONG SecurityDescriptorSize)
4209 {
4210     DWORD cBytes;
4211     SECURITY_DESCRIPTOR* psd;
4212     BOOL bret = FALSE;
4213
4214     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4215
4216     if (GetVersion() & 0x80000000)
4217     {
4218         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4219         goto lend;
4220     }
4221     else if (!StringSecurityDescriptor || !SecurityDescriptor)
4222     {
4223         SetLastError(ERROR_INVALID_PARAMETER);
4224         goto lend;
4225     }
4226     else if (StringSDRevision != SID_REVISION)
4227     {
4228         SetLastError(ERROR_UNKNOWN_REVISION);
4229         goto lend;
4230     }
4231
4232     /* Compute security descriptor length */
4233     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4234         NULL, &cBytes))
4235         goto lend;
4236
4237     psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4238     if (!psd) goto lend;
4239
4240     psd->Revision = SID_REVISION;
4241     psd->Control |= SE_SELF_RELATIVE;
4242
4243     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4244         psd, &cBytes))
4245     {
4246         LocalFree(psd);
4247         goto lend;
4248     }
4249
4250     if (SecurityDescriptorSize)
4251         *SecurityDescriptorSize = cBytes;
4252
4253     bret = TRUE;
4254  
4255 lend:
4256     TRACE(" ret=%d\n", bret);
4257     return bret;
4258 }
4259
4260 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4261 {
4262     if (cch == -1)
4263         cch = strlenW(string);
4264
4265     if (plen)
4266         *plen += cch;
4267
4268     if (pwptr)
4269     {
4270         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4271         *pwptr += cch;
4272     }
4273 }
4274
4275 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4276 {
4277     DWORD i;
4278     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4279     WCHAR subauthfmt[] = { '-','%','u',0 };
4280     WCHAR buf[26];
4281     SID *pisid = psid;
4282
4283     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4284     {
4285         SetLastError(ERROR_INVALID_SID);
4286         return FALSE;
4287     }
4288
4289     if (pisid->IdentifierAuthority.Value[0] ||
4290      pisid->IdentifierAuthority.Value[1])
4291     {
4292         FIXME("not matching MS' bugs\n");
4293         SetLastError(ERROR_INVALID_SID);
4294         return FALSE;
4295     }
4296
4297     sprintfW( buf, fmt, pisid->Revision,
4298         MAKELONG(
4299             MAKEWORD( pisid->IdentifierAuthority.Value[5],
4300                     pisid->IdentifierAuthority.Value[4] ),
4301             MAKEWORD( pisid->IdentifierAuthority.Value[3],
4302                     pisid->IdentifierAuthority.Value[2] )
4303         ) );
4304     DumpString(buf, -1, pwptr, plen);
4305
4306     for( i=0; i<pisid->SubAuthorityCount; i++ )
4307     {
4308         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4309         DumpString(buf, -1, pwptr, plen);
4310     }
4311     return TRUE;
4312 }
4313
4314 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4315 {
4316     size_t i;
4317     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4318     {
4319         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4320         {
4321             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4322             return TRUE;
4323         }
4324     }
4325
4326     return DumpSidNumeric(psid, pwptr, plen);
4327 }
4328
4329 static const LPCWSTR AceRightBitNames[32] = {
4330         SDDL_CREATE_CHILD,        /*  0 */
4331         SDDL_DELETE_CHILD,
4332         SDDL_LIST_CHILDREN,
4333         SDDL_SELF_WRITE,
4334         SDDL_READ_PROPERTY,       /*  4 */
4335         SDDL_WRITE_PROPERTY,
4336         SDDL_DELETE_TREE,
4337         SDDL_LIST_OBJECT,
4338         SDDL_CONTROL_ACCESS,      /*  8 */
4339         NULL,
4340         NULL,
4341         NULL,
4342         NULL,                     /* 12 */
4343         NULL,
4344         NULL,
4345         NULL,
4346         SDDL_STANDARD_DELETE,     /* 16 */
4347         SDDL_READ_CONTROL,
4348         SDDL_WRITE_DAC,
4349         SDDL_WRITE_OWNER,
4350         NULL,                     /* 20 */
4351         NULL,
4352         NULL,
4353         NULL,
4354         NULL,                     /* 24 */
4355         NULL,
4356         NULL,
4357         NULL,
4358         SDDL_GENERIC_ALL,         /* 28 */
4359         SDDL_GENERIC_EXECUTE,
4360         SDDL_GENERIC_WRITE,
4361         SDDL_GENERIC_READ
4362 };
4363
4364 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4365 {
4366     static const WCHAR fmtW[] = {'0','x','%','x',0};
4367     WCHAR buf[15];
4368     size_t i;
4369
4370     if (mask == 0)
4371         return;
4372
4373     /* first check if the right have name */
4374     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4375     {
4376         if (AceRights[i].wstr == NULL)
4377             break;
4378         if (mask == AceRights[i].value)
4379         {
4380             DumpString(AceRights[i].wstr, -1, pwptr, plen);
4381             return;
4382         }
4383     }
4384
4385     /* then check if it can be built from bit names */
4386     for (i = 0; i < 32; i++)
4387     {
4388         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4389         {
4390             /* can't be built from bit names */
4391             sprintfW(buf, fmtW, mask);
4392             DumpString(buf, -1, pwptr, plen);
4393             return;
4394         }
4395     }
4396
4397     /* build from bit names */
4398     for (i = 0; i < 32; i++)
4399         if (mask & (1 << i))
4400             DumpString(AceRightBitNames[i], -1, pwptr, plen);
4401 }
4402
4403 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4404 {
4405     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4406     static const WCHAR openbr = '(';
4407     static const WCHAR closebr = ')';
4408     static const WCHAR semicolon = ';';
4409
4410     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4411     {
4412         SetLastError(ERROR_INVALID_ACL);
4413         return FALSE;
4414     }
4415
4416     piace = pace;
4417     DumpString(&openbr, 1, pwptr, plen);
4418     switch (piace->Header.AceType)
4419     {
4420         case ACCESS_ALLOWED_ACE_TYPE:
4421             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4422             break;
4423         case ACCESS_DENIED_ACE_TYPE:
4424             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4425             break;
4426         case SYSTEM_AUDIT_ACE_TYPE:
4427             DumpString(SDDL_AUDIT, -1, pwptr, plen);
4428             break;
4429         case SYSTEM_ALARM_ACE_TYPE:
4430             DumpString(SDDL_ALARM, -1, pwptr, plen);
4431             break;
4432     }
4433     DumpString(&semicolon, 1, pwptr, plen);
4434
4435     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4436         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4437     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4438         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4439     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4440         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4441     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4442         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4443     if (piace->Header.AceFlags & INHERITED_ACE)
4444         DumpString(SDDL_INHERITED, -1, pwptr, plen);
4445     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4446         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4447     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4448         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4449     DumpString(&semicolon, 1, pwptr, plen);
4450     DumpRights(piace->Mask, pwptr, plen);
4451     DumpString(&semicolon, 1, pwptr, plen);
4452     /* objects not supported */
4453     DumpString(&semicolon, 1, pwptr, plen);
4454     /* objects not supported */
4455     DumpString(&semicolon, 1, pwptr, plen);
4456     if (!DumpSid(&piace->SidStart, pwptr, plen))
4457         return FALSE;
4458     DumpString(&closebr, 1, pwptr, plen);
4459     return TRUE;
4460 }
4461
4462 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4463 {
4464     WORD count;
4465     int i;
4466
4467     if (protected)
4468         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4469     if (autoInheritReq)
4470         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4471     if (autoInherited)
4472         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4473
4474     if (pacl == NULL)
4475         return TRUE;
4476
4477     if (!IsValidAcl(pacl))
4478         return FALSE;
4479
4480     count = pacl->AceCount;
4481     for (i = 0; i < count; i++)
4482     {
4483         LPVOID ace;
4484         if (!GetAce(pacl, i, &ace))
4485             return FALSE;
4486         if (!DumpAce(ace, pwptr, plen))
4487             return FALSE;
4488     }
4489
4490     return TRUE;
4491 }
4492
4493 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4494 {
4495     static const WCHAR prefix[] = {'O',':',0};
4496     BOOL bDefaulted;
4497     PSID psid;
4498
4499     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4500         return FALSE;
4501
4502     if (psid == NULL)
4503         return TRUE;
4504
4505     DumpString(prefix, -1, pwptr, plen);
4506     if (!DumpSid(psid, pwptr, plen))
4507         return FALSE;
4508     return TRUE;
4509 }
4510
4511 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4512 {
4513     static const WCHAR prefix[] = {'G',':',0};
4514     BOOL bDefaulted;
4515     PSID psid;
4516
4517     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4518         return FALSE;
4519
4520     if (psid == NULL)
4521         return TRUE;
4522
4523     DumpString(prefix, -1, pwptr, plen);
4524     if (!DumpSid(psid, pwptr, plen))
4525         return FALSE;
4526     return TRUE;
4527 }
4528
4529 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4530 {
4531     static const WCHAR dacl[] = {'D',':',0};
4532     SECURITY_DESCRIPTOR_CONTROL control;
4533     BOOL present, defaulted;
4534     DWORD revision;
4535     PACL pacl;
4536
4537     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4538         return FALSE;
4539
4540     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4541         return FALSE;
4542
4543     if (!present)
4544         return TRUE;
4545
4546     DumpString(dacl, 2, pwptr, plen);
4547     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4548         return FALSE;
4549     return TRUE;
4550 }
4551
4552 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4553 {
4554     static const WCHAR sacl[] = {'S',':',0};
4555     SECURITY_DESCRIPTOR_CONTROL control;
4556     BOOL present, defaulted;
4557     DWORD revision;
4558     PACL pacl;
4559
4560     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4561         return FALSE;
4562
4563     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4564         return FALSE;
4565
4566     if (!present)
4567         return TRUE;
4568
4569     DumpString(sacl, 2, pwptr, plen);
4570     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4571         return FALSE;
4572     return TRUE;
4573 }
4574
4575 /******************************************************************************
4576  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4577  */
4578 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4579 {
4580     ULONG len;
4581     WCHAR *wptr, *wstr;
4582
4583     if (SDRevision != SDDL_REVISION_1)
4584     {
4585         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4586         SetLastError(ERROR_UNKNOWN_REVISION);
4587         return FALSE;
4588     }
4589
4590     len = 0;
4591     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4592         if (!DumpOwner(SecurityDescriptor, NULL, &len))
4593             return FALSE;
4594     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4595         if (!DumpGroup(SecurityDescriptor, NULL, &len))
4596             return FALSE;
4597     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4598         if (!DumpDacl(SecurityDescriptor, NULL, &len))
4599             return FALSE;
4600     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4601         if (!DumpSacl(SecurityDescriptor, NULL, &len))
4602             return FALSE;
4603
4604     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4605     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4606         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4607             return FALSE;
4608     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4609         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4610             return FALSE;
4611     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4612         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4613             return FALSE;
4614     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4615         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4616             return FALSE;
4617     *wptr = 0;
4618
4619     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4620     *OutputString = wstr;
4621     if (OutputLen)
4622         *OutputLen = strlenW(*OutputString)+1;
4623     return TRUE;
4624 }
4625
4626 /******************************************************************************
4627  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4628  */
4629 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4630 {
4631     LPWSTR wstr;
4632     ULONG len;
4633     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4634     {
4635         int lenA;
4636
4637         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4638         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4639         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4640         LocalFree(wstr);
4641
4642         if (OutputLen != NULL)
4643             *OutputLen = lenA;
4644         return TRUE;
4645     }
4646     else
4647     {
4648         *OutputString = NULL;
4649         if (OutputLen)
4650             *OutputLen = 0;
4651         return FALSE;
4652     }
4653 }
4654
4655 /******************************************************************************
4656  * ConvertStringSidToSidW [ADVAPI32.@]
4657  */
4658 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4659 {
4660     BOOL bret = FALSE;
4661     DWORD cBytes;
4662
4663     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4664     if (GetVersion() & 0x80000000)
4665         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4666     else if (!StringSid || !Sid)
4667         SetLastError(ERROR_INVALID_PARAMETER);
4668     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4669     {
4670         PSID pSid = *Sid = LocalAlloc(0, cBytes);
4671
4672         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4673         if (!bret)
4674             LocalFree(*Sid); 
4675     }
4676     return bret;
4677 }
4678
4679 /******************************************************************************
4680  * ConvertStringSidToSidA [ADVAPI32.@]
4681  */
4682 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4683 {
4684     BOOL bret = FALSE;
4685
4686     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4687     if (GetVersion() & 0x80000000)
4688         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4689     else if (!StringSid || !Sid)
4690         SetLastError(ERROR_INVALID_PARAMETER);
4691     else
4692     {
4693         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4694         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4695          len * sizeof(WCHAR));
4696
4697         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4698         bret = ConvertStringSidToSidW(wStringSid, Sid);
4699         HeapFree(GetProcessHeap(), 0, wStringSid);
4700     }
4701     return bret;
4702 }
4703
4704 /******************************************************************************
4705  * ConvertSidToStringSidW [ADVAPI32.@]
4706  *
4707  *  format of SID string is:
4708  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4709  *  where
4710  *    <rev> is the revision of the SID encoded as decimal
4711  *    <auth> is the identifier authority encoded as hex
4712  *    <subauthN> is the subauthority id encoded as decimal
4713  */
4714 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4715 {
4716     DWORD len = 0;
4717     LPWSTR wstr, wptr;
4718
4719     TRACE("%p %p\n", pSid, pstr );
4720
4721     len = 0;
4722     if (!DumpSidNumeric(pSid, NULL, &len))
4723         return FALSE;
4724     wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4725     DumpSidNumeric(pSid, &wptr, NULL);
4726     *wptr = 0;
4727
4728     *pstr = wstr;
4729     return TRUE;
4730 }
4731
4732 /******************************************************************************
4733  * ConvertSidToStringSidA [ADVAPI32.@]
4734  */
4735 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4736 {
4737     LPWSTR wstr = NULL;
4738     LPSTR str;
4739     UINT len;
4740
4741     TRACE("%p %p\n", pSid, pstr );
4742
4743     if( !ConvertSidToStringSidW( pSid, &wstr ) )
4744         return FALSE;
4745
4746     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4747     str = LocalAlloc( 0, len );
4748     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4749     LocalFree( wstr );
4750
4751     *pstr = str;
4752
4753     return TRUE;
4754 }
4755
4756 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4757         PSECURITY_DESCRIPTOR pdesc,
4758         PSECURITY_DESCRIPTOR cdesc,
4759         PSECURITY_DESCRIPTOR* ndesc,
4760         GUID* objtype,
4761         BOOL isdir,
4762         PGENERIC_MAPPING genmap )
4763 {
4764     FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4765
4766     return FALSE;
4767 }
4768
4769 BOOL WINAPI CreatePrivateObjectSecurity(
4770         PSECURITY_DESCRIPTOR ParentDescriptor,
4771         PSECURITY_DESCRIPTOR CreatorDescriptor,
4772         PSECURITY_DESCRIPTOR* NewDescriptor,
4773         BOOL IsDirectoryObject,
4774         HANDLE Token,
4775         PGENERIC_MAPPING GenericMapping )
4776 {
4777     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4778           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4779
4780     return FALSE;
4781 }
4782
4783 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4784 {
4785     FIXME("%p - stub\n", ObjectDescriptor);
4786
4787     return TRUE;
4788 }
4789
4790 BOOL WINAPI CreateProcessAsUserA(
4791         HANDLE hToken,
4792         LPCSTR lpApplicationName,
4793         LPSTR lpCommandLine,
4794         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4795         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4796         BOOL bInheritHandles,
4797         DWORD dwCreationFlags,
4798         LPVOID lpEnvironment,
4799         LPCSTR lpCurrentDirectory,
4800         LPSTARTUPINFOA lpStartupInfo,
4801         LPPROCESS_INFORMATION lpProcessInformation )
4802 {
4803     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4804           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4805           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4806
4807     return FALSE;
4808 }
4809
4810 BOOL WINAPI CreateProcessAsUserW(
4811         HANDLE hToken,
4812         LPCWSTR lpApplicationName,
4813         LPWSTR lpCommandLine,
4814         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4815         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4816         BOOL bInheritHandles,
4817         DWORD dwCreationFlags,
4818         LPVOID lpEnvironment,
4819         LPCWSTR lpCurrentDirectory,
4820         LPSTARTUPINFOW lpStartupInfo,
4821         LPPROCESS_INFORMATION lpProcessInformation )
4822 {
4823     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
4824           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4825           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
4826           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4827
4828     /* We should create the process with a suspended main thread */
4829     if (!CreateProcessW (lpApplicationName,
4830                          lpCommandLine,
4831                          lpProcessAttributes,
4832                          lpThreadAttributes,
4833                          bInheritHandles,
4834                          dwCreationFlags, /* CREATE_SUSPENDED */
4835                          lpEnvironment,
4836                          lpCurrentDirectory,
4837                          lpStartupInfo,
4838                          lpProcessInformation))
4839     {
4840       return FALSE;
4841     }
4842
4843     return TRUE;
4844 }
4845
4846 /******************************************************************************
4847  * CreateProcessWithLogonW
4848  */
4849 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4850     LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4851     LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4852 {
4853     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4854     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4855     debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4856     lpStartupInfo, lpProcessInformation);
4857
4858     return FALSE;
4859 }
4860
4861 /******************************************************************************
4862  * DuplicateTokenEx [ADVAPI32.@]
4863  */
4864 BOOL WINAPI DuplicateTokenEx(
4865         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4866         LPSECURITY_ATTRIBUTES lpTokenAttributes,
4867         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4868         TOKEN_TYPE TokenType,
4869         PHANDLE DuplicateTokenHandle )
4870 {
4871     OBJECT_ATTRIBUTES ObjectAttributes;
4872
4873     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4874           ImpersonationLevel, TokenType, DuplicateTokenHandle);
4875
4876     InitializeObjectAttributes(
4877         &ObjectAttributes,
4878         NULL,
4879         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4880         NULL,
4881         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4882
4883     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4884                                            dwDesiredAccess,
4885                                            &ObjectAttributes,
4886                                            ImpersonationLevel,
4887                                            TokenType,
4888                                            DuplicateTokenHandle ) );
4889 }
4890
4891 BOOL WINAPI DuplicateToken(
4892         HANDLE ExistingTokenHandle,
4893         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4894         PHANDLE DuplicateTokenHandle )
4895 {
4896     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4897                              NULL, ImpersonationLevel, TokenImpersonation,
4898                              DuplicateTokenHandle );
4899 }
4900
4901 /******************************************************************************
4902  * ComputeStringSidSize
4903  */
4904 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4905 {
4906     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4907     {
4908         int ctok = 0;
4909         while (*StringSid)
4910         {
4911             if (*StringSid == '-')
4912                 ctok++;
4913             StringSid++;
4914         }
4915
4916         if (ctok >= 3)
4917             return GetSidLengthRequired(ctok - 2);
4918     }
4919     else /* String constant format  - Only available in winxp and above */
4920     {
4921         unsigned int i;
4922
4923         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4924             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4925                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4926     }
4927
4928     return GetSidLengthRequired(0);
4929 }
4930
4931 /******************************************************************************
4932  * ParseStringSidToSid
4933  */
4934 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4935 {
4936     BOOL bret = FALSE;
4937     SID* pisid=pSid;
4938
4939     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4940     if (!StringSid)
4941     {
4942         SetLastError(ERROR_INVALID_PARAMETER);
4943         TRACE("StringSid is NULL, returning FALSE\n");
4944         return FALSE;
4945     }
4946
4947     *cBytes = ComputeStringSidSize(StringSid);
4948     if (!pisid) /* Simply compute the size */
4949     {
4950         TRACE("only size requested, returning TRUE\n");
4951         return TRUE;
4952     }
4953
4954     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4955     {
4956         DWORD i = 0, identAuth;
4957         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4958
4959         StringSid += 2; /* Advance to Revision */
4960         pisid->Revision = atoiW(StringSid);
4961
4962         if (pisid->Revision != SDDL_REVISION)
4963         {
4964             TRACE("Revision %d is unknown\n", pisid->Revision);
4965             goto lend; /* ERROR_INVALID_SID */
4966         }
4967         if (csubauth == 0)
4968         {
4969             TRACE("SubAuthorityCount is 0\n");
4970             goto lend; /* ERROR_INVALID_SID */
4971         }
4972
4973         pisid->SubAuthorityCount = csubauth;
4974
4975         /* Advance to identifier authority */
4976         while (*StringSid && *StringSid != '-')
4977             StringSid++;
4978         if (*StringSid == '-')
4979             StringSid++;
4980
4981         /* MS' implementation can't handle values greater than 2^32 - 1, so
4982          * we don't either; assume most significant bytes are always 0
4983          */
4984         pisid->IdentifierAuthority.Value[0] = 0;
4985         pisid->IdentifierAuthority.Value[1] = 0;
4986         identAuth = atoiW(StringSid);
4987         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4988         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4989         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4990         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4991
4992         /* Advance to first sub authority */
4993         while (*StringSid && *StringSid != '-')
4994             StringSid++;
4995         if (*StringSid == '-')
4996             StringSid++;
4997
4998         while (*StringSid)
4999         {
5000             pisid->SubAuthority[i++] = atoiW(StringSid);
5001
5002             while (*StringSid && *StringSid != '-')
5003                 StringSid++;
5004             if (*StringSid == '-')
5005                 StringSid++;
5006         }
5007
5008         if (i != pisid->SubAuthorityCount)
5009             goto lend; /* ERROR_INVALID_SID */
5010
5011         bret = TRUE;
5012     }
5013     else /* String constant format  - Only available in winxp and above */
5014     {
5015         unsigned int i;
5016         pisid->Revision = SDDL_REVISION;
5017
5018         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5019             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5020             {
5021                 DWORD j;
5022                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5023                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5024                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5025                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5026                 bret = TRUE;
5027             }
5028
5029         if (!bret)
5030             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5031     }
5032
5033 lend:
5034     if (!bret)
5035         SetLastError(ERROR_INVALID_SID);
5036
5037     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5038     return bret;
5039 }
5040
5041 /******************************************************************************
5042  * GetNamedSecurityInfoA [ADVAPI32.@]
5043  */
5044 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5045         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5046         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5047         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5048 {
5049     DWORD len;
5050     LPWSTR wstr = NULL;
5051     DWORD r;
5052
5053     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5054         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5055
5056     if( pObjectName )
5057     {
5058         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5059         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5060         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5061     }
5062
5063     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5064                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5065
5066     HeapFree( GetProcessHeap(), 0, wstr );
5067
5068     return r;
5069 }
5070
5071 /******************************************************************************
5072  * GetNamedSecurityInfoW [ADVAPI32.@]
5073  */
5074 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5075     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5076     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5077 {
5078     DWORD needed, offset;
5079     SECURITY_DESCRIPTOR_RELATIVE *relative;
5080     BYTE *buffer;
5081
5082     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5083            group, dacl, sacl, descriptor );
5084
5085     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5086
5087     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5088     if (info & OWNER_SECURITY_INFORMATION)
5089         needed += sizeof(sidWorld);
5090     if (info & GROUP_SECURITY_INFORMATION)
5091         needed += sizeof(sidWorld);
5092     if (info & DACL_SECURITY_INFORMATION)
5093         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5094     if (info & SACL_SECURITY_INFORMATION)
5095         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5096
5097     /* must be freed by caller */
5098     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5099     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5100
5101     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5102     {
5103         HeapFree( GetProcessHeap(), 0, *descriptor );
5104         return ERROR_INVALID_SECURITY_DESCR;
5105     }
5106
5107     relative = *descriptor;
5108     relative->Control |= SE_SELF_RELATIVE;
5109     buffer = (BYTE *)relative;
5110     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5111
5112     if (info & OWNER_SECURITY_INFORMATION)
5113     {
5114         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5115         relative->Owner = offset;
5116         if (owner)
5117             *owner = buffer + offset;
5118         offset += sizeof(sidWorld);
5119     }
5120     if (info & GROUP_SECURITY_INFORMATION)
5121     {
5122         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5123         relative->Group = offset;
5124         if (group)
5125             *group = buffer + offset;
5126         offset += sizeof(sidWorld);
5127     }
5128     if (info & DACL_SECURITY_INFORMATION)
5129     {
5130         relative->Control |= SE_DACL_PRESENT;
5131         GetWorldAccessACL( (PACL)(buffer + offset) );
5132         relative->Dacl = offset;
5133         if (dacl)
5134             *dacl = (PACL)(buffer + offset);
5135         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5136     }
5137     if (info & SACL_SECURITY_INFORMATION)
5138     {
5139         relative->Control |= SE_SACL_PRESENT;
5140         GetWorldAccessACL( (PACL)(buffer + offset) );
5141         relative->Sacl = offset;
5142         if (sacl)
5143             *sacl = (PACL)(buffer + offset);
5144     }
5145     return ERROR_SUCCESS;
5146 }
5147
5148 /******************************************************************************
5149  * DecryptFileW [ADVAPI32.@]
5150  */
5151 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5152 {
5153     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5154     return TRUE;
5155 }
5156
5157 /******************************************************************************
5158  * DecryptFileA [ADVAPI32.@]
5159  */
5160 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5161 {
5162     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5163     return TRUE;
5164 }
5165
5166 /******************************************************************************
5167  * EncryptFileW [ADVAPI32.@]
5168  */
5169 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5170 {
5171     FIXME("%s\n", debugstr_w(lpFileName));
5172     return TRUE;
5173 }
5174
5175 /******************************************************************************
5176  * EncryptFileA [ADVAPI32.@]
5177  */
5178 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5179 {
5180     FIXME("%s\n", debugstr_a(lpFileName));
5181     return TRUE;
5182 }
5183
5184 /******************************************************************************
5185  * FileEncryptionStatusW [ADVAPI32.@]
5186  */
5187 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5188 {
5189     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5190     if (!lpStatus)
5191         return FALSE;
5192     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5193     return TRUE;
5194 }
5195
5196 /******************************************************************************
5197  * FileEncryptionStatusA [ADVAPI32.@]
5198  */
5199 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5200 {
5201     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5202     if (!lpStatus)
5203         return FALSE;
5204     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5205     return TRUE;
5206 }
5207
5208 /******************************************************************************
5209  * SetSecurityInfo [ADVAPI32.@]
5210  */
5211 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
5212                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5213                       PSID psidGroup, PACL pDacl, PACL pSacl) {
5214     FIXME("stub\n");
5215     return ERROR_SUCCESS;
5216 }
5217
5218 /******************************************************************************
5219  * SaferCreateLevel   [ADVAPI32.@]
5220  */
5221 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5222                              SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5223 {
5224     FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5225     return FALSE;
5226 }
5227
5228 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5229                 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5230                 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5231                 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5232                 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5233 {
5234     FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p  Stub\n",
5235         debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5236         pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5237
5238     return ERROR_SUCCESS;
5239 }