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